From ab44125a02716e67d6af5fccba5edd710c344037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wei=C3=9Fer=20Hase?= Date: Tue, 13 Dec 2022 17:04:05 +0100 Subject: [PATCH 1/4] chore: v2.3 deployments * refactor: renaming deployment scripts * feat: goerli redeployment * feat: op-goerli redeployment * feat: improve testnet deployments * feat: added scripts for op deployment * feat: optimisticEthereum deployment * fix: deployment fixture test environment * docs: updated address registry * fix: update connext token addresses --- .env.example | 3 + deploy/0-mainnet/001_keep3r_v1.ts | 2 +- deploy/0-mainnet/003_create_pair_manager.ts | 4 +- deploy/1-mainnet-test/110_job_for_test.ts | 79 +- ..._keep3r_escrow.ts => 201_keep3r_escrow.ts} | 0 ...02_save_oracles.ts => 202_save_oracles.ts} | 0 ....ts => 203_keep3r_helper_and_sidechain.ts} | 3 +- ....ts => 301_keep3r_helper_and_sidechain.ts} | 11 +- ...ove_liq.ts => 310_fund_and_approve_liq.ts} | 10 +- .../311_job_rated_for_test.ts | 54 + .../411_job_rated_for_test.ts | 38 - ..._verify_keep3r.ts => 401_verify_keep3r.ts} | 0 ..._factory.ts => 402_verify_pair_factory.ts} | 0 ..._manager.ts => 403_verify_pair_manager.ts} | 0 deploy/4-verify/410_verify_sidechain.ts | 18 + ...erify_testnet.ts => 421_verify_testnet.ts} | 2 +- ...ain.ts => 422_verify_testnet_sidechain.ts} | 2 +- deployments/goerli/BasicJob.json | 88 +- deployments/goerli/KP3Rv1.json | 2 +- deployments/goerli/Keep3rForTestnet.json | 222 +- .../goerli/Keep3rHelperForTestnet.json | 74 +- deployments/goerli/UniV3Factory.json | 2 +- deployments/goerli/UniV3Pool.json | 2 +- deployments/goerli/WETH.json | 2 +- .../0100086ed88435cb002327f6c69d11e5.json | 334 ++ .../0d224f905ebe4be6830f2d07ee9fcf58.json | 331 ++ .../7120622b6fa82f1fde1bb178c8155d0d.json | 328 ++ .../8c968687fa7312972c014a5aac38beba.json | 334 ++ deployments/optimisticEthereum/.chainId | 1 + deployments/optimisticEthereum/KP3Rv1.json | 189 + .../optimisticEthereum/Keep3rEscrow.json | 539 +++ .../Keep3rHelperSidechain.json | 1548 +++++++ .../optimisticEthereum/Keep3rSidechain.json | 4013 +++++++++++++++++ .../optimisticEthereum/Kp3rWethOracle.json | 987 ++++ .../optimisticEthereum/WethUsdOracle.json | 987 ++++ .../aa1ee30f4d8e78611039940e35c6db8b.json | 331 ++ deployments/optimisticGoerli/BasicJob.json | 36 +- deployments/optimisticGoerli/KP3Rv1.json | 2 +- .../optimisticGoerli/Keep3rEscrow.json | 26 +- .../Keep3rHelperSidechain.json | 1548 +++++++ .../Keep3rHelperSidechainForTestnet.json | 1517 ------- .../Keep3rSidechainForTestnet.json | 224 +- .../optimisticGoerli/Kp3rWethOracle.json | 2 +- .../optimisticGoerli/WethUsdOracle.json | 2 +- .../0100086ed88435cb002327f6c69d11e5.json | 334 ++ .../7d006d28afea8f44b7106e2df679db88.json | 334 ++ .../8c968687fa7312972c014a5aac38beba.json | 334 ++ .../f7e3e740337524d02345ab2e7585c15c.json | 334 ++ deployments/optimisticGoerli/wkLP.json | 189 + docs/README.md | 10 +- hardhat.config.ts | 17 +- package.json | 8 +- solidity/contracts/sidechain/Keep3rEscrow.sol | 17 + .../sidechain/Keep3rHelperSidechain.sol | 17 + .../contracts/sidechain/Keep3rSidechain.sol | 2 + solidity/for-test/JobRatedForTest.sol | 2 +- .../testnet/Keep3rHelperForTestnet.sol | 10 - .../Keep3rHelperSidechainForTestnet.sol | 29 - test/e2e/deployment-fixtures.spec.ts | 6 +- utils/constants.ts | 12 +- 60 files changed, 13547 insertions(+), 2005 deletions(-) rename deploy/2-sidechain/{301_keep3r_escrow.ts => 201_keep3r_escrow.ts} (100%) rename deploy/2-sidechain/{302_save_oracles.ts => 202_save_oracles.ts} (100%) rename deploy/2-sidechain/{303_keep3r_helper_and_sidechain.ts => 203_keep3r_helper_and_sidechain.ts} (86%) rename deploy/3-sidechain-test/{401_keep3r_helper_and_sidechain.ts => 301_keep3r_helper_and_sidechain.ts} (71%) rename deploy/3-sidechain-test/{410_fund_and_approve_liq.ts => 310_fund_and_approve_liq.ts} (59%) create mode 100644 deploy/3-sidechain-test/311_job_rated_for_test.ts delete mode 100644 deploy/3-sidechain-test/411_job_rated_for_test.ts rename deploy/4-verify/{10_verify_keep3r.ts => 401_verify_keep3r.ts} (100%) rename deploy/4-verify/{11_verify_pair_factory.ts => 402_verify_pair_factory.ts} (100%) rename deploy/4-verify/{12_verify_pair_manager.ts => 403_verify_pair_manager.ts} (100%) create mode 100644 deploy/4-verify/410_verify_sidechain.ts rename deploy/4-verify/{61_verify_testnet.ts => 421_verify_testnet.ts} (90%) rename deploy/4-verify/{51_verify_testnet_sidechain.ts => 422_verify_testnet_sidechain.ts} (97%) create mode 100644 deployments/goerli/solcInputs/0100086ed88435cb002327f6c69d11e5.json create mode 100644 deployments/goerli/solcInputs/0d224f905ebe4be6830f2d07ee9fcf58.json create mode 100644 deployments/goerli/solcInputs/7120622b6fa82f1fde1bb178c8155d0d.json create mode 100644 deployments/goerli/solcInputs/8c968687fa7312972c014a5aac38beba.json create mode 100644 deployments/optimisticEthereum/.chainId create mode 100644 deployments/optimisticEthereum/KP3Rv1.json create mode 100644 deployments/optimisticEthereum/Keep3rEscrow.json create mode 100644 deployments/optimisticEthereum/Keep3rHelperSidechain.json create mode 100644 deployments/optimisticEthereum/Keep3rSidechain.json create mode 100644 deployments/optimisticEthereum/Kp3rWethOracle.json create mode 100644 deployments/optimisticEthereum/WethUsdOracle.json create mode 100644 deployments/optimisticEthereum/solcInputs/aa1ee30f4d8e78611039940e35c6db8b.json create mode 100644 deployments/optimisticGoerli/Keep3rHelperSidechain.json delete mode 100644 deployments/optimisticGoerli/Keep3rHelperSidechainForTestnet.json create mode 100644 deployments/optimisticGoerli/solcInputs/0100086ed88435cb002327f6c69d11e5.json create mode 100644 deployments/optimisticGoerli/solcInputs/7d006d28afea8f44b7106e2df679db88.json create mode 100644 deployments/optimisticGoerli/solcInputs/8c968687fa7312972c014a5aac38beba.json create mode 100644 deployments/optimisticGoerli/solcInputs/f7e3e740337524d02345ab2e7585c15c.json create mode 100644 deployments/optimisticGoerli/wkLP.json delete mode 100644 solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol diff --git a/.env.example b/.env.example index 716e4c3..60cd5b7 100644 --- a/.env.example +++ b/.env.example @@ -4,17 +4,20 @@ ENCRYPTED_PRIVATE_KEY= # HTTPs providers MAINNET_HTTPS_URL= +OPTIMISM_HTTPS_URL= GOERLI_HTTPS_URL= OP_GOERLI_HTTPS_URL= # Account's private keys MAINNET_PRIVATE_KEY= +OPTIMISM_PRIVATE_KEY= GOERLI_PRIVATE_KEY= OP_GOERLI_PRIVATE_KEY= # Etherscan (optional, only for verifying smart contracts) ETHERSCAN_API_KEY= ETHEREUM_ETHERSCAN_API_KEY= +OPTIMISTIC_ETHERSCAN_API_KEY= GOERLI_ETHERSCAN_API_KEY= OP_GOERLI_ETHERSCAN_API_KEY= diff --git a/deploy/0-mainnet/001_keep3r_v1.ts b/deploy/0-mainnet/001_keep3r_v1.ts index a4156eb..e54a56f 100644 --- a/deploy/0-mainnet/001_keep3r_v1.ts +++ b/deploy/0-mainnet/001_keep3r_v1.ts @@ -5,7 +5,7 @@ import IERC20 from '../../artifacts/@openzeppelin/contracts/token/ERC20/IERC20.s const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { kp3rV1 } = await hre.getNamedAccounts(); - hre.deployments.save('KP3Rv1', { + await hre.deployments.save('KP3Rv1', { address: kp3rV1, abi: IERC20.abi, }); diff --git a/deploy/0-mainnet/003_create_pair_manager.ts b/deploy/0-mainnet/003_create_pair_manager.ts index e273fd5..21e9b62 100644 --- a/deploy/0-mainnet/003_create_pair_manager.ts +++ b/deploy/0-mainnet/003_create_pair_manager.ts @@ -5,11 +5,11 @@ import { HardhatRuntimeEnvironment } from 'hardhat/types'; const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployer, kp3rWethOracle } = await hre.getNamedAccounts(); - await hre.deployments.execute('UniV3PairManagerFactory', { from: deployer, gasLimit: 3e6, log: true }, 'createPairManager', kp3rWethOracle); + await hre.deployments.execute('UniV3PairManagerFactory', { from: deployer, log: true }, 'createPairManager', kp3rWethOracle); const pairManagerAddress = await hre.deployments.read('UniV3PairManagerFactory', 'pairManagers', kp3rWethOracle); - hre.deployments.save('UniV3PairManager', { + await hre.deployments.save('UniV3PairManager', { address: pairManagerAddress, abi: IUniV3PairManager.abi, }); diff --git a/deploy/1-mainnet-test/110_job_for_test.ts b/deploy/1-mainnet-test/110_job_for_test.ts index 4154614..86fd393 100644 --- a/deploy/1-mainnet-test/110_job_for_test.ts +++ b/deploy/1-mainnet-test/110_job_for_test.ts @@ -3,57 +3,66 @@ import { DeployFunction } from 'hardhat-deploy/types'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployer } = await hre.getNamedAccounts(); + const { deployer, kp3rV1 } = await hre.getNamedAccounts(); const kp3RForTest = await hre.deployments.get('KP3Rv1'); const keep3rV2 = await hre.deployments.get('Keep3rForTestnet'); const pairManager = await hre.deployments.get('UniV3PairManager'); - await hre.deployments.delete('BasicJob'); const jobForTest = await hre.deployments.deploy('BasicJob', { from: deployer, - contract: 'solidity/for-test/BasicJob.sol:BasicJob', + contract: 'solidity/for-test/JobForTest.sol:JobForTest', args: [keep3rV2.address], log: true, }); // register job - await hre.deployments.execute('Keep3rForTestnet', { from: deployer, log: true }, 'addJob', jobForTest.address); - - // mint kLPs - let klpBalance = await hre.deployments.read('UniV3PairManager', 'balanceOf', deployer); - if (klpBalance == 0) { - const wethBalance = await hre.deployments.read('WETH', 'balanceOf', deployer); - if (wethBalance < toUnit(0.1)) { - await hre.deployments.execute('WETH', { from: deployer, log: true, value: toUnit(0.1) }, 'deposit'); - } - const kp3rBalance = await hre.deployments.read('KP3Rv1', 'balanceOf', deployer); - if (kp3rBalance < toUnit(1)) { - await hre.deployments.execute('KP3Rv1', { from: deployer, log: true }, 'mint(uint256)', toUnit(1)); - } + if (jobForTest.newlyDeployed) { + await hre.deployments.execute('Keep3rForTestnet', { from: deployer, log: true }, 'addJob', jobForTest.address); + } + + const LIQUIDITY = await hre.deployments.read('Keep3rForTestnet', 'liquidityAmount', jobForTest.address, pairManager.address); + if (LIQUIDITY == 0) { + // deployer needs to have KP3R and WETH balance + let klpBalance = await hre.deployments.read('UniV3PairManager', 'balanceOf', deployer); + if (klpBalance == 0) { + const wethBalance = await hre.deployments.read('WETH', 'balanceOf', deployer); + if (wethBalance < toUnit(1)) { + await hre.deployments.execute('WETH', { from: deployer, log: true, value: toUnit(0.1) }, 'deposit'); + } + const kp3rBalance = await hre.deployments.read('KP3Rv1', 'balanceOf', deployer); + if (kp3rBalance < toUnit(100)) { + await hre.deployments.execute('KP3Rv1', { from: deployer, log: true }, 'mint(uint256)', toUnit(1)); + } - await hre.deployments.execute('KP3Rv1', { from: deployer, log: true }, 'approve', pairManager.address, toUnit(100)); - await hre.deployments.execute('WETH', { from: deployer, log: true }, 'approve', pairManager.address, toUnit(100)); + await hre.deployments.execute('KP3Rv1', { from: deployer, log: true }, 'approve', pairManager.address, toUnit(100)); + await hre.deployments.execute('WETH', { from: deployer, log: true }, 'approve', pairManager.address, toUnit(100)); - const mintArguments: any[] = [toUnit(1), toUnit(0.1), 0, 0, deployer]; - await hre.deployments.execute('UniV3PairManager', { from: deployer, log: true }, 'mint', ...mintArguments); + const mintArguments: any[] = [toUnit(1), toUnit(0.1), 0, 0, deployer]; + await hre.deployments.execute('UniV3PairManager', { from: deployer, log: true }, 'mint', ...mintArguments); + + klpBalance = await hre.deployments.read('UniV3PairManager', 'balanceOf', deployer); + } + + // add liquidity to job + await hre.deployments.execute('UniV3PairManager', { from: deployer, log: true }, 'approve', keep3rV2.address, klpBalance); + await hre.deployments.execute( + 'Keep3rForTestnet', + { from: deployer, log: true }, + 'addLiquidityToJob', + jobForTest.address, + pairManager.address, + klpBalance + ); + } - klpBalance = await hre.deployments.read('UniV3PairManager', 'balanceOf', deployer); + const IS_KEEPER = await hre.deployments.read('Keep3rForTestnet', 'isKeeper', deployer); + if (!IS_KEEPER) { + // register deployer as keeper + await hre.deployments.execute('Keep3rForTestnet', { from: deployer, log: true }, 'bond', kp3RForTest.address, 0); + await hre.deployments.execute('Keep3rForTestnet', { from: deployer, log: true }, 'activate', kp3RForTest.address); } - // add liquidity to job - await hre.deployments.execute('UniV3PairManager', { from: deployer, log: true }, 'approve', keep3rV2.address, klpBalance); - await hre.deployments.execute( - 'Keep3rForTestnet', - { from: deployer, log: true }, - 'addLiquidityToJob', - jobForTest.address, - pairManager.address, - klpBalance - ); - - // register deployer as keeper - await hre.deployments.execute('Keep3rForTestnet', { from: deployer, log: true }, 'bond', kp3RForTest.address, 0); - await hre.deployments.execute('Keep3rForTestnet', { from: deployer, log: true }, 'activate', kp3RForTest.address); + await hre.deployments.execute('BasicJob', { from: deployer, log: true, gasLimit: 1e6 }, 'work'); }; deployFunction.dependencies = ['testnet-keep3r']; diff --git a/deploy/2-sidechain/301_keep3r_escrow.ts b/deploy/2-sidechain/201_keep3r_escrow.ts similarity index 100% rename from deploy/2-sidechain/301_keep3r_escrow.ts rename to deploy/2-sidechain/201_keep3r_escrow.ts diff --git a/deploy/2-sidechain/302_save_oracles.ts b/deploy/2-sidechain/202_save_oracles.ts similarity index 100% rename from deploy/2-sidechain/302_save_oracles.ts rename to deploy/2-sidechain/202_save_oracles.ts diff --git a/deploy/2-sidechain/303_keep3r_helper_and_sidechain.ts b/deploy/2-sidechain/203_keep3r_helper_and_sidechain.ts similarity index 86% rename from deploy/2-sidechain/303_keep3r_helper_and_sidechain.ts rename to deploy/2-sidechain/203_keep3r_helper_and_sidechain.ts index d89cb3f..ce4686d 100644 --- a/deploy/2-sidechain/303_keep3r_helper_and_sidechain.ts +++ b/deploy/2-sidechain/203_keep3r_helper_and_sidechain.ts @@ -3,6 +3,7 @@ import { HardhatRuntimeEnvironment } from 'hardhat/types'; const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployer, governor, kp3rV1, weth, kp3rWethOracle, wethUsdOracle } = await hre.getNamedAccounts(); + const { kp3rV1: mainnetKp3rV1 } = await hre.companionNetworks['mainnet'].getNamedAccounts(); const keep3rEscrow = await hre.deployments.get('Keep3rEscrow'); @@ -10,7 +11,7 @@ const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnviro const currentNonce: number = await hre.ethers.provider.getTransactionCount(deployer); const keeperV2Address: string = hre.ethers.utils.getContractAddress({ from: deployer, nonce: currentNonce + 1 }); - const keep3rHelperArgs = [keeperV2Address, governor, kp3rV1, weth, kp3rWethOracle, wethUsdOracle]; + const keep3rHelperArgs = [keeperV2Address, governor, mainnetKp3rV1, weth, kp3rWethOracle, wethUsdOracle]; const keep3rHelper = await hre.deployments.deploy('Keep3rHelperSidechain', { from: deployer, diff --git a/deploy/3-sidechain-test/401_keep3r_helper_and_sidechain.ts b/deploy/3-sidechain-test/301_keep3r_helper_and_sidechain.ts similarity index 71% rename from deploy/3-sidechain-test/401_keep3r_helper_and_sidechain.ts rename to deploy/3-sidechain-test/301_keep3r_helper_and_sidechain.ts index 791783a..ee1f0d9 100644 --- a/deploy/3-sidechain-test/401_keep3r_helper_and_sidechain.ts +++ b/deploy/3-sidechain-test/301_keep3r_helper_and_sidechain.ts @@ -2,7 +2,8 @@ import { DeployFunction } from 'hardhat-deploy/types'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployer, governor, kp3rV1, weth, kp3rWethOracle, wethUsdOracle } = await hre.getNamedAccounts(); + const { deployer, governor, kp3rV1, kp3rWethOracle, wethUsdOracle } = await hre.getNamedAccounts(); + const { kp3rV1: mainnetKp3rV1, weth: mainnetWeth } = await hre.companionNetworks['mainnet'].getNamedAccounts(); const keep3rEscrow = await hre.deployments.get('Keep3rEscrow'); @@ -10,11 +11,11 @@ const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnviro const currentNonce: number = await hre.ethers.provider.getTransactionCount(deployer); const keeperV2Address: string = hre.ethers.utils.getContractAddress({ from: deployer, nonce: currentNonce + 1 }); - const keep3rHelperArgs = [keeperV2Address, governor, kp3rV1, weth, kp3rWethOracle, wethUsdOracle]; + const keep3rHelperArgs = [keeperV2Address, governor, mainnetKp3rV1, mainnetWeth, kp3rWethOracle, wethUsdOracle]; - const keep3rHelper = await hre.deployments.deploy('Keep3rHelperSidechainForTestnet', { + const keep3rHelper = await hre.deployments.deploy('Keep3rHelperSidechain', { from: deployer, - contract: 'solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet', + contract: 'solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain', args: keep3rHelperArgs, log: true, }); @@ -27,8 +28,6 @@ const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnviro args: keep3rV2Args, log: true, }); - - await hre.deployments.execute('Keep3rEscrow', { from: deployer, log: true }, 'setMinter', keep3r.address); }; deployFunction.dependencies = ['keep3r-escrow', 'save-oracles']; diff --git a/deploy/3-sidechain-test/410_fund_and_approve_liq.ts b/deploy/3-sidechain-test/310_fund_and_approve_liq.ts similarity index 59% rename from deploy/3-sidechain-test/410_fund_and_approve_liq.ts rename to deploy/3-sidechain-test/310_fund_and_approve_liq.ts index ab647be..aba26b6 100644 --- a/deploy/3-sidechain-test/410_fund_and_approve_liq.ts +++ b/deploy/3-sidechain-test/310_fund_and_approve_liq.ts @@ -3,14 +3,16 @@ import { DeployFunction } from 'hardhat-deploy/types'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployer, kp3rWethOracle, kp3rV1 } = await hre.getNamedAccounts(); + const { deployer, kp3rWethOracle, wkLP } = await hre.getNamedAccounts(); const keep3rEscrow = await hre.deployments.get('Keep3rEscrow'); + const keep3r = await hre.deployments.get('Keep3rSidechainForTestnet'); await hre.deployments.execute('KP3Rv1', { from: deployer, log: true }, 'approve', keep3rEscrow.address, toUnit(100)); - await hre.deployments.execute('Keep3rEscrow', { from: deployer, log: true, gasLimit: 2e6 }, 'deposit', toUnit(100)); + await hre.deployments.execute('Keep3rEscrow', { from: deployer, log: true }, 'deposit', toUnit(100)); + await hre.deployments.execute('Keep3rEscrow', { from: deployer, log: true }, 'setMinter', keep3r.address); - await hre.deployments.execute('Keep3rHelperSidechainForTestnet', { from: deployer, log: true }, 'setOracle', kp3rV1, kp3rWethOracle); - await hre.deployments.execute('Keep3rSidechainForTestnet', { from: deployer, log: true }, 'approveLiquidity', kp3rV1); + await hre.deployments.execute('Keep3rHelperSidechain', { from: deployer, log: true }, 'setOracle', wkLP, kp3rWethOracle); + await hre.deployments.execute('Keep3rSidechainForTestnet', { from: deployer, log: true }, 'approveLiquidity', wkLP); }; deployFunction.dependencies = ['testnet-keep3r-sidechain']; diff --git a/deploy/3-sidechain-test/311_job_rated_for_test.ts b/deploy/3-sidechain-test/311_job_rated_for_test.ts new file mode 100644 index 0000000..cea7a39 --- /dev/null +++ b/deploy/3-sidechain-test/311_job_rated_for_test.ts @@ -0,0 +1,54 @@ +import { toUnit } from '@utils/bn'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import IERC20 from '../../artifacts/@openzeppelin/contracts/token/ERC20/IERC20.sol/IERC20.json'; + +const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const { deployer, kp3rV1, wkLP } = await hre.getNamedAccounts(); + const keep3rV2 = await hre.deployments.get('Keep3rSidechainForTestnet'); + await hre.deployments.save('wkLP', { + address: wkLP, + abi: IERC20.abi, + }); + + const jobForTest = await hre.deployments.deploy('BasicJob', { + from: deployer, + contract: 'solidity/for-test/JobRatedForTest.sol:JobRatedForTest', + args: [keep3rV2.address], + log: true, + }); + + // register job + if (jobForTest.newlyDeployed) { + await hre.deployments.execute('Keep3rSidechainForTestnet', { from: deployer, log: true }, 'addJob', jobForTest.address); + } + + const LIQUIDITY = await hre.deployments.read('Keep3rSidechainForTestnet', 'liquidityAmount', jobForTest.address, wkLP); + if (LIQUIDITY == 0) { + // deployer needs to have kLP balance + const keep3rSidechain = await hre.deployments.get('Keep3rSidechainForTestnet'); + await hre.deployments.execute('wkLP', { from: deployer, log: true }, 'approve', keep3rSidechain.address, toUnit(10)); + await hre.deployments.execute( + 'Keep3rSidechainForTestnet', + { from: deployer, log: true }, + 'addLiquidityToJob', + jobForTest.address, + wkLP, + toUnit(1) + ); + } + + const IS_KEEPER = await hre.deployments.read('Keep3rSidechainForTestnet', 'isKeeper', deployer); + if (!IS_KEEPER) { + // register deployer as keeper + await hre.deployments.execute('Keep3rSidechainForTestnet', { from: deployer, log: true }, 'bond', kp3rV1, 0); + await hre.deployments.execute('Keep3rSidechainForTestnet', { from: deployer, log: true, gasLimit: 1e6 }, 'activate', kp3rV1); + } + + await hre.deployments.execute('BasicJob', { from: deployer, log: true, gasLimit: 1e6 }, 'work'); +}; + +deployFunction.dependencies = ['approve-testnet-liquidity']; +deployFunction.tags = ['job-rated-for-test']; + +export default deployFunction; diff --git a/deploy/3-sidechain-test/411_job_rated_for_test.ts b/deploy/3-sidechain-test/411_job_rated_for_test.ts deleted file mode 100644 index ff78969..0000000 --- a/deploy/3-sidechain-test/411_job_rated_for_test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { toUnit } from '@utils/bn'; -import { DeployFunction } from 'hardhat-deploy/types'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; - -const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployer, kp3rV1 } = await hre.getNamedAccounts(); - const keep3rV2 = await hre.deployments.get('Keep3rSidechainForTestnet'); - - await hre.deployments.delete('BasicJob'); - const jobForTest = await hre.deployments.deploy('BasicJob', { - from: deployer, - contract: 'solidity/for-test/JobRatedForTest.sol:JobRatedForTest', - args: [keep3rV2.address], - log: true, - }); - - // register job - await hre.deployments.execute('Keep3rSidechainForTestnet', { from: deployer, log: true }, 'addJob', jobForTest.address); - - const keep3rSidechain = await hre.deployments.get('Keep3rSidechainForTestnet'); - await hre.deployments.execute('KP3Rv1', { from: deployer, log: true }, 'approve', keep3rSidechain.address, toUnit(10)); - await hre.deployments.execute( - 'Keep3rSidechainForTestnet', - { from: deployer, log: true }, - 'addLiquidityToJob', - jobForTest.address, - kp3rV1, - toUnit(10) - ); - - await hre.deployments.execute('Keep3rSidechainForTestnet', { from: deployer, log: true }, 'bond', kp3rV1, 0); - await hre.deployments.execute('Keep3rSidechainForTestnet', { from: deployer, log: true, gasLimit: 1e6 }, 'activate', kp3rV1); -}; - -deployFunction.dependencies = ['approve-testnet-liquidity']; -deployFunction.tags = ['job-rated-for-test']; - -export default deployFunction; diff --git a/deploy/4-verify/10_verify_keep3r.ts b/deploy/4-verify/401_verify_keep3r.ts similarity index 100% rename from deploy/4-verify/10_verify_keep3r.ts rename to deploy/4-verify/401_verify_keep3r.ts diff --git a/deploy/4-verify/11_verify_pair_factory.ts b/deploy/4-verify/402_verify_pair_factory.ts similarity index 100% rename from deploy/4-verify/11_verify_pair_factory.ts rename to deploy/4-verify/402_verify_pair_factory.ts diff --git a/deploy/4-verify/12_verify_pair_manager.ts b/deploy/4-verify/403_verify_pair_manager.ts similarity index 100% rename from deploy/4-verify/12_verify_pair_manager.ts rename to deploy/4-verify/403_verify_pair_manager.ts diff --git a/deploy/4-verify/410_verify_sidechain.ts b/deploy/4-verify/410_verify_sidechain.ts new file mode 100644 index 0000000..015d0fa --- /dev/null +++ b/deploy/4-verify/410_verify_sidechain.ts @@ -0,0 +1,18 @@ +import { DeployFunction } from 'hardhat-deploy/types'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { verifyContract } from 'utils/deploy'; + +const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const keep3rEscrow = await hre.deployments.get('Keep3rEscrow'); + await verifyContract(hre, keep3rEscrow); + + const keep3rHelper = await hre.deployments.get('Keep3rHelperSidechain'); + await verifyContract(hre, keep3rHelper); + + const keep3rV2 = await hre.deployments.get('Keep3rSidechain'); + await verifyContract(hre, keep3rV2); +}; + +deployFunction.tags = ['verify-sidechain']; + +export default deployFunction; diff --git a/deploy/4-verify/61_verify_testnet.ts b/deploy/4-verify/421_verify_testnet.ts similarity index 90% rename from deploy/4-verify/61_verify_testnet.ts rename to deploy/4-verify/421_verify_testnet.ts index 5b4ba3d..0748b8c 100644 --- a/deploy/4-verify/61_verify_testnet.ts +++ b/deploy/4-verify/421_verify_testnet.ts @@ -6,7 +6,7 @@ const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnviro const pairManager = await hre.deployments.get('UniV3PairManager'); await verifyContract(hre, pairManager); - const keep3rHelper = await hre.deployments.get('Keep3rHelperForTestnet'); + const keep3rHelper = await hre.deployments.get('Keep3rHelper'); await verifyContract(hre, keep3rHelper); const keep3rV2 = await hre.deployments.get('Keep3rForTestnet'); diff --git a/deploy/4-verify/51_verify_testnet_sidechain.ts b/deploy/4-verify/422_verify_testnet_sidechain.ts similarity index 97% rename from deploy/4-verify/51_verify_testnet_sidechain.ts rename to deploy/4-verify/422_verify_testnet_sidechain.ts index 20ecb94..412e9c3 100644 --- a/deploy/4-verify/51_verify_testnet_sidechain.ts +++ b/deploy/4-verify/422_verify_testnet_sidechain.ts @@ -6,7 +6,7 @@ const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnviro const keep3rEscrow = await hre.deployments.get('Keep3rEscrow'); await verifyContract(hre, keep3rEscrow); - const keep3rHelper = await hre.deployments.get('Keep3rHelperSidechainForTestnet'); + const keep3rHelper = await hre.deployments.get('Keep3rHelperSidechain'); await verifyContract(hre, keep3rHelper); const keep3rV2 = await hre.deployments.get('Keep3rSidechainForTestnet'); diff --git a/deployments/goerli/BasicJob.json b/deployments/goerli/BasicJob.json index f7f7363..7fea89d 100644 --- a/deployments/goerli/BasicJob.json +++ b/deployments/goerli/BasicJob.json @@ -1,5 +1,5 @@ { - "address": "0x214DfEBeEfd0BeE69Aba7F22Ea5438797879a4a4", + "address": "0xa2c7A15FFc02e00cdeedBba56c41dAaed84f8734", "abi": [ { "inputs": [ @@ -14,28 +14,9 @@ }, { "inputs": [], - "name": "KeeperNotValid", + "name": "InvalidKeeper", "type": "error" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "array", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "keep3r", @@ -73,7 +54,7 @@ "inputs": [ { "internalType": "uint256", - "name": "_howHard", + "name": "_factor", "type": "uint256" } ], @@ -81,45 +62,32 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_howHard", - "type": "uint256" - } - ], - "name": "workRefund", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" } ], - "transactionHash": "0x8853ea87dd26b3625f2f70f9f6d814fe4849e8c646cccbae3d4106d663855822", + "transactionHash": "0xf993d8bfd999d2fc3ff80f122f960de2de3de06f5cd4653bd19c9e56e378c630", "receipt": { "to": null, "from": "0x258b180E741157763236F5277619D71ECf00B906", - "contractAddress": "0x214DfEBeEfd0BeE69Aba7F22Ea5438797879a4a4", - "transactionIndex": 62, - "gasUsed": "375627", + "contractAddress": "0xa2c7A15FFc02e00cdeedBba56c41dAaed84f8734", + "transactionIndex": 8, + "gasUsed": "299912", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x6e6515f0e319cb7449854df89fe9f7392baa0100d4868aea815f2610dccb47bc", - "transactionHash": "0x8853ea87dd26b3625f2f70f9f6d814fe4849e8c646cccbae3d4106d663855822", + "blockHash": "0x119433484e9184255ac3f2ab0f486614ae8247b48f8f098fd0f43eed4b7837f8", + "transactionHash": "0xf993d8bfd999d2fc3ff80f122f960de2de3de06f5cd4653bd19c9e56e378c630", "logs": [], - "blockNumber": 8043006, - "cumulativeGasUsed": "11774127", + "blockNumber": 8091010, + "cumulativeGasUsed": "1736676", "status": 1, "byzantium": true }, "args": [ - "0x229d018065019c3164B899F4B9c2d4ffEae9B92b" + "0x85063437C02Ba7F4f82F898859e4992380DEd3bb" ], - "numDeployments": 2, - "solcInputHash": "a2dd8c00aab95ba5d841446478d867fa", - "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3r\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"KeeperNotValid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"array\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3r\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"work\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_howHard\",\"type\":\"uint256\"}],\"name\":\"workHard\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_howHard\",\"type\":\"uint256\"}],\"name\":\"workRefund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/BasicJob.sol\":\"BasicJob\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"solidity/for-test/BasicJob.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../interfaces/IKeep3r.sol';\\n\\ncontract BasicJob {\\n error KeeperNotValid();\\n\\n address public keep3r;\\n uint256 public nonce;\\n uint256[] public array;\\n\\n constructor(address _keep3r) {\\n keep3r = _keep3r;\\n }\\n\\n function work() external upkeep {}\\n\\n function workHard(uint256 _howHard) external upkeep {\\n for (uint256 i = nonce; i < _howHard; i++) {\\n nonce++;\\n }\\n }\\n\\n function workRefund(uint256 _howHard) external upkeep {\\n for (uint256 i; i < _howHard; i++) {\\n array.push(i);\\n }\\n\\n while (array.length > 0) {\\n array.pop();\\n }\\n }\\n\\n modifier upkeep() {\\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\\n _;\\n IKeep3r(keep3r).worked(msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x402015b591b42807cc3f22f7e3f02d785f9e507c7d00f42dfffdbfae9958be1c\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0x060f701c6991d323bcf360738568714956013b17b3e3443ea21d825a70c3947c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506040516105f83803806105f883398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b610565806100936000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c8063322e9f041461006757806338d94193146100715780633bb39c3314610097578063634c7bb5146100aa578063affed0e0146100ca578063ead731ad146100d3575b600080fd5b61006f6100e6565b005b61008461007f3660046104c3565b6101e9565b6040519081526020015b60405180910390f35b61006f6100a53660046104c3565b61020a565b6000546100bd906001600160a01b031681565b60405161008e91906104dc565b61008460015481565b61006f6100e13660046104c3565b610343565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa906101169033906004016104dc565b602060405180830381600087803b15801561013057600080fd5b505af1158015610144573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610168919061049a565b61018557604051636959565560e11b815260040160405180910390fd5b6000546040516317fbade560e21b81526001600160a01b0390911690635feeb794906101b59033906004016104dc565b600060405180830381600087803b1580156101cf57600080fd5b505af11580156101e3573d6000803e3d6000fd5b50505050565b600281815481106101f957600080fd5b600091825260209091200154905081565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa9061023a9033906004016104dc565b602060405180830381600087803b15801561025457600080fd5b505af1158015610268573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061028c919061049a565b6102a957604051636959565560e11b815260040160405180910390fd5b6001545b818110156102dd57600180549060006102c5836104f0565b919050555080806102d5906104f0565b9150506102ad565b506000546040516317fbade560e21b81526001600160a01b0390911690635feeb7949061030e9033906004016104dc565b600060405180830381600087803b15801561032857600080fd5b505af115801561033c573d6000803e3d6000fd5b5050505050565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa906103739033906004016104dc565b602060405180830381600087803b15801561038d57600080fd5b505af11580156103a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c5919061049a565b6103e257604051636959565560e11b815260040160405180910390fd5b60005b8181101561043457600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018190558061042c816104f0565b9150506103e5565b505b6002541561046a57600280548061044f5761044f610519565b60019003818190600052602060002001600090559055610436565b6000546040516317fbade560e21b81526001600160a01b0390911690635feeb7949061030e9033906004016104dc565b6000602082840312156104ac57600080fd5b815180151581146104bc57600080fd5b9392505050565b6000602082840312156104d557600080fd5b5035919050565b6001600160a01b0391909116815260200190565b600060001982141561051257634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212203f9310f7ea47008aed6186eba3047510159acaad5be40e9e2a679bef7b52852464736f6c63430008070033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c8063322e9f041461006757806338d94193146100715780633bb39c3314610097578063634c7bb5146100aa578063affed0e0146100ca578063ead731ad146100d3575b600080fd5b61006f6100e6565b005b61008461007f3660046104c3565b6101e9565b6040519081526020015b60405180910390f35b61006f6100a53660046104c3565b61020a565b6000546100bd906001600160a01b031681565b60405161008e91906104dc565b61008460015481565b61006f6100e13660046104c3565b610343565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa906101169033906004016104dc565b602060405180830381600087803b15801561013057600080fd5b505af1158015610144573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610168919061049a565b61018557604051636959565560e11b815260040160405180910390fd5b6000546040516317fbade560e21b81526001600160a01b0390911690635feeb794906101b59033906004016104dc565b600060405180830381600087803b1580156101cf57600080fd5b505af11580156101e3573d6000803e3d6000fd5b50505050565b600281815481106101f957600080fd5b600091825260209091200154905081565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa9061023a9033906004016104dc565b602060405180830381600087803b15801561025457600080fd5b505af1158015610268573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061028c919061049a565b6102a957604051636959565560e11b815260040160405180910390fd5b6001545b818110156102dd57600180549060006102c5836104f0565b919050555080806102d5906104f0565b9150506102ad565b506000546040516317fbade560e21b81526001600160a01b0390911690635feeb7949061030e9033906004016104dc565b600060405180830381600087803b15801561032857600080fd5b505af115801561033c573d6000803e3d6000fd5b5050505050565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa906103739033906004016104dc565b602060405180830381600087803b15801561038d57600080fd5b505af11580156103a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c5919061049a565b6103e257604051636959565560e11b815260040160405180910390fd5b60005b8181101561043457600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018190558061042c816104f0565b9150506103e5565b505b6002541561046a57600280548061044f5761044f610519565b60019003818190600052602060002001600090559055610436565b6000546040516317fbade560e21b81526001600160a01b0390911690635feeb7949061030e9033906004016104dc565b6000602082840312156104ac57600080fd5b815180151581146104bc57600080fd5b9392505050565b6000602082840312156104d557600080fd5b5035919050565b6001600160a01b0391909116815260200190565b600060001982141561051257634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212203f9310f7ea47008aed6186eba3047510159acaad5be40e9e2a679bef7b52852464736f6c63430008070033", + "numDeployments": 4, + "solcInputHash": "0d224f905ebe4be6830f2d07ee9fcf58", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3r\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidKeeper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"keep3r\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"work\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_factor\",\"type\":\"uint256\"}],\"name\":\"workHard\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/JobForTest.sol\":\"JobForTest\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"solidity/for-test/JobForTest.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../interfaces/IKeep3r.sol';\\n\\ncontract JobForTest {\\n error InvalidKeeper();\\n address public keep3r;\\n uint256 public nonce;\\n\\n constructor(address _keep3r) {\\n keep3r = _keep3r;\\n }\\n\\n function work() external {\\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\\n\\n for (uint256 i; i < 1000; i++) {\\n nonce++;\\n }\\n\\n IKeep3r(keep3r).worked(msg.sender);\\n }\\n\\n function workHard(uint256 _factor) external {\\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\\n\\n for (uint256 i; i < 1000 * _factor; i++) {\\n nonce++;\\n }\\n\\n IKeep3r(keep3r).worked(msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x399bb5de1fd8e09bd46993fd9fd423bf5955238edacee0b44f985604fb74272b\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0xf4748c236ddf409e45e7169c735e2fc54e627b2b3ccd189ebb438ad768f1deb1\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5060405161049938038061049983398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b610406806100936000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063322e9f04146100515780633bb39c331461005b578063634c7bb51461006e578063affed0e014610097575b600080fd5b6100596100ae565b005b610059610069366004610353565b6101e7565b600054610081906001600160a01b031681565b60405161008e919061036c565b60405180910390f35b6100a060015481565b60405190815260200161008e565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa906100de90339060040161036c565b602060405180830381600087803b1580156100f857600080fd5b505af115801561010c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610130919061032a565b61014d57604051637671ff4960e11b815260040160405180910390fd5b60005b6103e8811015610182576001805490600061016a8361039f565b9190505550808061017a9061039f565b915050610150565b506000546040516317fbade560e21b81526001600160a01b0390911690635feeb794906101b390339060040161036c565b600060405180830381600087803b1580156101cd57600080fd5b505af11580156101e1573d6000803e3d6000fd5b50505050565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa9061021790339060040161036c565b602060405180830381600087803b15801561023157600080fd5b505af1158015610245573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610269919061032a565b61028657604051637671ff4960e11b815260040160405180910390fd5b60005b610295826103e8610380565b8110156102c457600180549060006102ac8361039f565b919050555080806102bc9061039f565b915050610289565b506000546040516317fbade560e21b81526001600160a01b0390911690635feeb794906102f590339060040161036c565b600060405180830381600087803b15801561030f57600080fd5b505af1158015610323573d6000803e3d6000fd5b5050505050565b60006020828403121561033c57600080fd5b8151801515811461034c57600080fd5b9392505050565b60006020828403121561036557600080fd5b5035919050565b6001600160a01b0391909116815260200190565b600081600019048311821515161561039a5761039a6103ba565b500290565b60006000198214156103b3576103b36103ba565b5060010190565b634e487b7160e01b600052601160045260246000fdfea264697066735822122072f8c8f00b08f3b67ddde30dce3d3b407bfbe619e838b7a0dff19ba72918e0f264736f6c63430008070033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063322e9f04146100515780633bb39c331461005b578063634c7bb51461006e578063affed0e014610097575b600080fd5b6100596100ae565b005b610059610069366004610353565b6101e7565b600054610081906001600160a01b031681565b60405161008e919061036c565b60405180910390f35b6100a060015481565b60405190815260200161008e565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa906100de90339060040161036c565b602060405180830381600087803b1580156100f857600080fd5b505af115801561010c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610130919061032a565b61014d57604051637671ff4960e11b815260040160405180910390fd5b60005b6103e8811015610182576001805490600061016a8361039f565b9190505550808061017a9061039f565b915050610150565b506000546040516317fbade560e21b81526001600160a01b0390911690635feeb794906101b390339060040161036c565b600060405180830381600087803b1580156101cd57600080fd5b505af11580156101e1573d6000803e3d6000fd5b50505050565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa9061021790339060040161036c565b602060405180830381600087803b15801561023157600080fd5b505af1158015610245573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610269919061032a565b61028657604051637671ff4960e11b815260040160405180910390fd5b60005b610295826103e8610380565b8110156102c457600180549060006102ac8361039f565b919050555080806102bc9061039f565b915050610289565b506000546040516317fbade560e21b81526001600160a01b0390911690635feeb794906102f590339060040161036c565b600060405180830381600087803b15801561030f57600080fd5b505af1158015610323573d6000803e3d6000fd5b5050505050565b60006020828403121561033c57600080fd5b8151801515811461034c57600080fd5b9392505050565b60006020828403121561036557600080fd5b5035919050565b6001600160a01b0391909116815260200190565b600081600019048311821515161561039a5761039a6103ba565b500290565b60006000198214156103b3576103b36103ba565b5060010190565b634e487b7160e01b600052601160045260246000fdfea264697066735822122072f8c8f00b08f3b67ddde30dce3d3b407bfbe619e838b7a0dff19ba72918e0f264736f6c63430008070033", "devdoc": { "kind": "dev", "methods": {}, @@ -133,28 +101,20 @@ "storageLayout": { "storage": [ { - "astId": 10461, - "contract": "solidity/for-test/BasicJob.sol:BasicJob", + "astId": 10747, + "contract": "solidity/for-test/JobForTest.sol:JobForTest", "label": "keep3r", "offset": 0, "slot": "0", "type": "t_address" }, { - "astId": 10463, - "contract": "solidity/for-test/BasicJob.sol:BasicJob", + "astId": 10749, + "contract": "solidity/for-test/JobForTest.sol:JobForTest", "label": "nonce", "offset": 0, "slot": "1", "type": "t_uint256" - }, - { - "astId": 10466, - "contract": "solidity/for-test/BasicJob.sol:BasicJob", - "label": "array", - "offset": 0, - "slot": "2", - "type": "t_array(t_uint256)dyn_storage" } ], "types": { @@ -163,12 +123,6 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_uint256)dyn_storage": { - "base": "t_uint256", - "encoding": "dynamic_array", - "label": "uint256[]", - "numberOfBytes": "32" - }, "t_uint256": { "encoding": "inplace", "label": "uint256", diff --git a/deployments/goerli/KP3Rv1.json b/deployments/goerli/KP3Rv1.json index fa5c84b..5d4b7bf 100644 --- a/deployments/goerli/KP3Rv1.json +++ b/deployments/goerli/KP3Rv1.json @@ -185,5 +185,5 @@ "type": "function" } ], - "numDeployments": 2 + "numDeployments": 3 } \ No newline at end of file diff --git a/deployments/goerli/Keep3rForTestnet.json b/deployments/goerli/Keep3rForTestnet.json index f97973f..0c8a38b 100644 --- a/deployments/goerli/Keep3rForTestnet.json +++ b/deployments/goerli/Keep3rForTestnet.json @@ -1,5 +1,5 @@ { - "address": "0x229d018065019c3164B899F4B9c2d4ffEae9B92b", + "address": "0x85063437C02Ba7F4f82F898859e4992380DEd3bb", "abi": [ { "inputs": [ @@ -2319,6 +2319,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "totalBonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -2508,33 +2521,33 @@ "type": "function" } ], - "transactionHash": "0x70ba7598db4c3f6785b3625064f6891836f7a6b654ce94a3694c152bdaac4cd7", + "transactionHash": "0xbfc81543bf5b462a258b28d05a2336a064eb33bcefe27a6482317d1e276305d2", "receipt": { "to": null, "from": "0x258b180E741157763236F5277619D71ECf00B906", - "contractAddress": "0x229d018065019c3164B899F4B9c2d4ffEae9B92b", - "transactionIndex": 61, - "gasUsed": "5466602", + "contractAddress": "0x85063437C02Ba7F4f82F898859e4992380DEd3bb", + "transactionIndex": 36, + "gasUsed": "5474843", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x8c6f453664ffc70021b6c2c15743636a18e831101ddeedb1ddab7cddfc5e9289", - "transactionHash": "0x70ba7598db4c3f6785b3625064f6891836f7a6b654ce94a3694c152bdaac4cd7", + "blockHash": "0x0b622992793b8b301839fe4c1f8beb8baf4d5980dbf7e7fb91c89342a347f780", + "transactionHash": "0xbfc81543bf5b462a258b28d05a2336a064eb33bcefe27a6482317d1e276305d2", "logs": [], - "blockNumber": 8042999, - "cumulativeGasUsed": "14978109", + "blockNumber": 8091007, + "cumulativeGasUsed": "9048487", "status": 1, "byzantium": true }, "args": [ "0x258b180E741157763236F5277619D71ECf00B906", - "0xe8b291495aB1505A96317b2FCB04a370bA1AE3c2", + "0x399394ca069dCDE2C4d2a32E00a06C3D5fE17E3A", "0x16F63C5036d3F48A239358656a8f123eCE85789C", "0x16F63C5036d3F48A239358656a8f123eCE85789C" ], - "numDeployments": 2, - "solcInputHash": "a2dd8c00aab95ba5d841446478d867fa", - "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyAJob\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyAKeeper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Disputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasNotInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientJobTokenCredits\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityLessThanMin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationImpossible\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenCreditsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MinRewardPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDisputer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySlasher\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenUnallowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Activation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"BondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Bonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"Dispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"DustSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"FeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"InflationPeriodChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOwner\",\"type\":\"address\"}],\"name\":\"JobAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationSuccessful\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipAssent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_pendingOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashLiquidity\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"Keep3rHelperChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"Keep3rV1Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"Keep3rV1ProxyChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"KeeperRevoke\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"KeeperSlash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperValidation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_credit\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperWork\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityApproval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsForced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsReward\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"LiquidityMinimumChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityRevocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_resolver\",\"type\":\"address\"}],\"name\":\"Resolve\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"RewardPeriodTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"UnbondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeperOrJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_unbonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Unbonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"acceptJobMigration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"acceptJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"activate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"addDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"addJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addLiquidityToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"addSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addTokenCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"approveLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"approvedLiquidities\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"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\":[],\"name\":\"bondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"}],\"name\":\"bondedPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canActivateAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canWithdrawAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"changeJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"directTokenPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"dispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"firstSeen\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"forceLiquidityCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"hasBonded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"inflationPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minBond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_earned\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_age\",\"type\":\"uint256\"}],\"name\":\"isBondedKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isBondedKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"isKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobLiquidityCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobPendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobPeriodCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCreditsAddedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"jobs\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rHelper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1Proxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keepers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"liquidityAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidityMinimum\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"migrateJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"observeLiquidity\",\"outputs\":[{\"components\":[{\"internalType\":\"int56\",\"name\":\"current\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"difference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"}],\"internalType\":\"struct IKeep3rJobFundableLiquidity.TickCache\",\"name\":\"_tickCache\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingJobMigrations\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingUnbonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"quoteLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"removeDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"removeSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"resolve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"revoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"revokeLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardPeriodTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"rewardedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sendDust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"setBondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"setInflationPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"setKeep3rHelper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"setKeep3rV1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"setKeep3rV1Proxy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"setLiquidityMinimum\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"setRewardPeriodTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"setUnbondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bonded\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_bondAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_unbondAmount\",\"type\":\"uint256\"}],\"name\":\"slash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashTokenFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"slashers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"totalJobCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_credits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbondLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unbondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawTokenCreditsFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workCompleted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"worked\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptJobMigration(address,address)\":{\"details\":\"Unbond/withdraw process doesn't get migrated\",\"params\":{\"_fromJob\":\"The address of the job that requested to migrate\",\"_toJob\":\"The address to which the job wants to migrate to\"}},\"acceptJobOwnership(address)\":{\"params\":{\"_job\":\"The address of the job\"}},\"activate(address)\":{\"params\":{\"_bonding\":\"The asset being activated as bond collateral\"}},\"addJob(address)\":{\"params\":{\"_job\":\"Address of the contract for which work should be performed\"}},\"addLiquidityToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity tokens to add\",\"_job\":\"The address of the job to assign liquidity to\",\"_liquidity\":\"The liquidity being added\"}},\"addTokenCreditsToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of credit being added\",\"_job\":\"The address of the job being credited\",\"_token\":\"The address of the token being credited\"}},\"approveLiquidity(address)\":{\"params\":{\"_liquidity\":\"The address of the liquidity accepted\"}},\"approvedLiquidities()\":{\"returns\":{\"_list\":\"An array of addresses with all the approved liquidity pairs\"}},\"bond(address,uint256)\":{\"params\":{\"_amount\":\"The amount of bonding asset being bonded\",\"_bonding\":\"The asset being bonded\"}},\"bondedPayment(address,uint256)\":{\"details\":\"Pays the keeper that performs the work with KP3R\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\",\"_payment\":\"The reward that should be allocated for the job\"}},\"changeJobOwnership(address,address)\":{\"params\":{\"_job\":\"The address of the job\",\"_newOwner\":\"The address of the proposed new owner\"}},\"directTokenPayment(address,address,uint256)\":{\"details\":\"Pays the keeper that performs the work with a specific token\",\"params\":{\"_amount\":\"The reward that should be allocated\",\"_keeper\":\"Address of the keeper that performed the work\",\"_token\":\"The asset being awarded to the keeper\"}},\"dispute(address)\":{\"params\":{\"_jobOrKeeper\":\"The address in dispute\"}},\"forceLiquidityCreditsToJob(address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity credits to gift\",\"_job\":\"The address of the job being credited\"}},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"details\":\"Should be used for protected functions\",\"params\":{\"_age\":\"The minimum keeper age required\",\"_bond\":\"The bond token being evaluated\",\"_earned\":\"The minimum funds earned in the keepers lifetime\",\"_keeper\":\"The keeper to check\",\"_minBond\":\"The minimum amount of bonded tokens\"},\"returns\":{\"_isBondedKeeper\":\"Whether the `_keeper` meets the given requirements\"}},\"isKeeper(address)\":{\"details\":\"Can be used for general (non critical) functions\",\"params\":{\"_keeper\":\"The keeper being investigated\"},\"returns\":{\"_isKeeper\":\"Whether the address passed as a parameter is a keeper or not\"}},\"jobLiquidityCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the liquidity credits\"},\"returns\":{\"_liquidityCredits\":\"The liquidity credits of a given job\"}},\"jobPeriodCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the period credits\"},\"returns\":{\"_periodCredits\":\"The credits the given job has at the current period\"}},\"jobs()\":{\"returns\":{\"_list\":\"Array with all the jobs in _jobs\"}},\"keepers()\":{\"returns\":{\"_list\":\"Array with all the keepers in _keepers\"}},\"migrateJob(address,address)\":{\"params\":{\"_fromJob\":\"The address of the job that is requesting to migrate\",\"_toJob\":\"The address at which the job is requesting to migrate\"}},\"observeLiquidity(address)\":{\"params\":{\"_liquidity\":\"The address of the liquidity pair being observed\"},\"returns\":{\"_tickCache\":\"The updated TickCache\"}},\"quoteLiquidity(address,uint256)\":{\"details\":\"_periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\",\"params\":{\"_amount\":\"The amount of liquidity to provide\",\"_liquidity\":\"The address of the liquidity to provide\"},\"returns\":{\"_periodCredits\":\"The amount of KP3R periodically minted for the given liquidity\"}},\"resolve(address)\":{\"params\":{\"_jobOrKeeper\":\"The address cleared\"}},\"revoke(address)\":{\"params\":{\"_keeper\":\"The address being slashed\"}},\"revokeLiquidity(address)\":{\"params\":{\"_liquidity\":\"The liquidity no longer accepted\"}},\"sendDust(address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of the token that will be transferred\",\"_to\":\"The address that will receive the idle funds\",\"_token\":\"The token that will be transferred\"}},\"setBondTime(uint256)\":{\"params\":{\"_bond\":\"The new bond time\"}},\"setFee(uint256)\":{\"params\":{\"_fee\":\"The new fee\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setInflationPeriod(uint256)\":{\"params\":{\"_inflationPeriod\":\"The new inflation period\"}},\"setKeep3rHelper(address)\":{\"params\":{\"_keep3rHelper\":\"The Keep3rHelper address\"}},\"setKeep3rV1(address)\":{\"params\":{\"_keep3rV1\":\"The Keep3rV1 address\"}},\"setKeep3rV1Proxy(address)\":{\"params\":{\"_keep3rV1Proxy\":\"The Keep3rV1Proxy address\"}},\"setLiquidityMinimum(uint256)\":{\"params\":{\"_liquidityMinimum\":\"The new minimum amount of liquidity\"}},\"setRewardPeriodTime(uint256)\":{\"params\":{\"_rewardPeriodTime\":\"The new amount of time required to pass between rewards\"}},\"setUnbondTime(uint256)\":{\"params\":{\"_unbond\":\"The new unbond time\"}},\"slash(address,address,uint256,uint256)\":{\"params\":{\"_bondAmount\":\"The bonded amount being slashed\",\"_bonded\":\"The asset being slashed\",\"_keeper\":\"The address being slashed\",\"_unbondAmount\":\"The pending unbond amount being slashed\"}},\"slashLiquidityFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity that will be slashed\",\"_job\":\"The address being slashed\",\"_liquidity\":\"The address of the liquidity that will be slashed\"}},\"slashTokenFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of the token that will be slashed\",\"_job\":\"The address of the job from which the token will be slashed\",\"_token\":\"The address of the token that will be slashed\"}},\"totalJobCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the total credits\"},\"returns\":{\"_credits\":\"The total credits of the given job\"}},\"unbond(address,uint256)\":{\"params\":{\"_amount\":\"Allows for partial unbonding\",\"_bonding\":\"The asset being unbonded\"}},\"unbondLiquidityFromJob(address,address,uint256)\":{\"details\":\"Can only be called by the job's owner\",\"params\":{\"_amount\":\"The amount of liquidity being removed\",\"_job\":\"The address of the job being unbonded from\",\"_liquidity\":\"The liquidity being unbonded\"}},\"withdraw(address)\":{\"params\":{\"_bonding\":\"The asset to withdraw from the bonding pool\"}},\"withdrawLiquidityFromJob(address,address,address)\":{\"params\":{\"_job\":\"The address of the job being withdrawn from\",\"_liquidity\":\"The liquidity being withdrawn\",\"_receiver\":\"The address that will receive the withdrawn liquidity\"}},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of token to be withdrawn\",\"_job\":\"The address of the job from which the credits are withdrawn\",\"_receiver\":\"The user that will receive tokens\",\"_token\":\"The address of the token being withdrawn\"}},\"worked(address)\":{\"details\":\"Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"AlreadyAJob()\":[{\"notice\":\"Throws when the address that is trying to register as a job is already a job\"}],\"AlreadyAKeeper()\":[{\"notice\":\"Throws when the address that is trying to register as a keeper is already a keeper\"}],\"AlreadyDisputed()\":[{\"notice\":\"Throws when a job or keeper is already disputed\"}],\"BondsLocked()\":[{\"notice\":\"Throws if the time required to bond an asset has not passed yet\"}],\"BondsUnexistent()\":[{\"notice\":\"Throws if there are no bonded assets\"}],\"Disputed()\":[{\"notice\":\"Throws if either a job or a keeper is disputed\"}],\"DisputerExistent()\":[{\"notice\":\"Throws if the address is already a registered disputer\"}],\"DisputerUnexistent()\":[{\"notice\":\"Throws if caller is not a registered disputer\"}],\"GasNotInitialized()\":[{\"notice\":\"Throws if work method was called without calling isKeeper or isBondedKeeper\"}],\"InsufficientFunds()\":[{\"notice\":\"Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\"}],\"InsufficientJobTokenCredits()\":[{\"notice\":\"Throws when the user tries to withdraw more tokens than it has\"}],\"JobAlreadyAdded()\":[{\"notice\":\"Throws when trying to add a job that has already been added\"}],\"JobDisputed()\":[{\"notice\":\"Throws when an action that requires an undisputed job is applied on a disputed job\"}],\"JobLiquidityInsufficient()\":[{\"notice\":\"Throws when trying to remove more liquidity than the job has\"}],\"JobLiquidityLessThanMin()\":[{\"notice\":\"Throws when trying to add less liquidity than the minimum liquidity required\"}],\"JobLiquidityUnexistent()\":[{\"notice\":\"Throws when the job doesn't have the requested liquidity\"}],\"JobMigrationImpossible()\":[{\"notice\":\"Throws when the address of the job that requests to migrate wants to migrate to its same address\"}],\"JobMigrationLocked()\":[{\"notice\":\"Throws when cooldown between migrations has not yet passed\"}],\"JobMigrationUnavailable()\":[{\"notice\":\"Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\"}],\"JobTokenCreditsLocked()\":[{\"notice\":\"Throws when the token withdraw cooldown has not yet passed\"}],\"JobTokenInsufficient()\":[{\"notice\":\"Throws when someone tries to slash more tokens than the job has\"}],\"JobTokenUnexistent()\":[{\"notice\":\"Throws when the token trying to be slashed doesn't exist\"}],\"JobUnapproved()\":[{\"notice\":\"Throws if the address claiming to be a job is not in the list of approved jobs\"}],\"JobUnavailable()\":[{\"notice\":\"Throws when an address is passed as a job, but that address is not a job\"}],\"LiquidityPairApproved()\":[{\"notice\":\"Throws when the liquidity being approved has already been approved\"}],\"LiquidityPairUnapproved()\":[{\"notice\":\"Throws when trying to add liquidity to an unapproved pool\"}],\"LiquidityPairUnexistent()\":[{\"notice\":\"Throws when the liquidity being removed has not been approved\"}],\"MinRewardPeriod()\":[{\"notice\":\"Throws if the reward period is less than the minimum reward period time\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"NotDisputed()\":[{\"notice\":\"Throws when a job or keeper is not disputed and someone tries to resolve the dispute\"}],\"OnlyDisputer()\":[{\"notice\":\"Throws if the msg.sender is not a disputer or is not a part of governance\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the job owner\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"OnlyPendingJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the pending job owner\"}],\"OnlySlasher()\":[{\"notice\":\"Throws if the msg.sender is not a slasher or is not a part of governance\"}],\"SlasherExistent()\":[{\"notice\":\"Throws if the address is already a registered slasher\"}],\"SlasherUnexistent()\":[{\"notice\":\"Throws if caller is not a registered slasher\"}],\"TokenUnallowed()\":[{\"notice\":\"Throws when the token is KP3R, as it should not be used for direct token payments\"}],\"UnbondsLocked()\":[{\"notice\":\"Throws if the time required to withdraw the bonds has not passed yet\"}],\"UnbondsUnexistent()\":[{\"notice\":\"Throws if there are no bonds to withdraw\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"Activation(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#activate is called\"},\"BondTimeChange(uint256)\":{\"notice\":\"Emitted when bondTime is changed\"},\"Bonding(address,address,uint256)\":{\"notice\":\"Emitted when the bonding process of a new keeper begins\"},\"Dispute(address,address)\":{\"notice\":\"Emitted when a keeper or a job is disputed\"},\"DisputerAdded(address)\":{\"notice\":\"Emitted when a disputer is added\"},\"DisputerRemoved(address)\":{\"notice\":\"Emitted when a disputer is removed\"},\"DustSent(address,uint256,address)\":{\"notice\":\"Emitted when dust is sent\"},\"FeeChange(uint256)\":{\"notice\":\"Emitted when the fee is changed\"},\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"InflationPeriodChange(uint256)\":{\"notice\":\"Emitted when the inflationPeriod is changed\"},\"JobAddition(address,address)\":{\"notice\":\"Emitted when Keep3rJobManager#addJob is called\"},\"JobMigrationRequested(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#migrateJob function is called\"},\"JobMigrationSuccessful(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#acceptJobMigration function is called\"},\"JobOwnershipAssent(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\"},\"JobOwnershipChange(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#changeJobOwnership is called\"},\"JobSlashLiquidity(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\"},\"JobSlashToken(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashTokenFromJob is called\"},\"Keep3rHelperChange(address)\":{\"notice\":\"Emitted when the Keep3rHelper address is changed\"},\"Keep3rV1Change(address)\":{\"notice\":\"Emitted when the Keep3rV1 address is changed\"},\"Keep3rV1ProxyChange(address)\":{\"notice\":\"Emitted when the Keep3rV1Proxy address is changed\"},\"KeeperRevoke(address,address)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#revoke is called\"},\"KeeperSlash(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#slash is called\"},\"KeeperValidation(uint256)\":{\"notice\":\"Emitted when a keeper is validated before a job\"},\"KeeperWork(address,address,address,uint256,uint256)\":{\"notice\":\"Emitted when a keeper works a job\"},\"LiquidityAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityApproval(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\"},\"LiquidityCreditsForced(address,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\"},\"LiquidityCreditsReward(address,uint256,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityMinimumChange(uint256)\":{\"notice\":\"Emitted when _liquidityMinimum is changed\"},\"LiquidityRevocation(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\"},\"LiquidityWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\"},\"Resolve(address,address)\":{\"notice\":\"Emitted when a dispute is resolved\"},\"RewardPeriodTimeChange(uint256)\":{\"notice\":\"Emitted when _rewardPeriodTime is changed\"},\"SlasherAdded(address)\":{\"notice\":\"Emitted when a slasher is added\"},\"SlasherRemoved(address)\":{\"notice\":\"Emitted when a slasher is removed\"},\"TokenCreditAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\"},\"TokenCreditWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\"},\"UnbondTimeChange(uint256)\":{\"notice\":\"Emitted when _unbondTime is changed\"},\"Unbonding(address,address,uint256)\":{\"notice\":\"Emitted when a keeper or job begins the unbonding process to withdraw the funds\"},\"Withdrawal(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#withdraw is called\"}},\"kind\":\"user\",\"methods\":{\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"acceptJobMigration(address,address)\":{\"notice\":\"Completes the migration process for a job\"},\"acceptJobOwnership(address)\":{\"notice\":\"The proposed address accepts to be the owner of the job\"},\"activate(address)\":{\"notice\":\"End of the bonding process after bonding time has passed\"},\"addDisputer(address)\":{\"notice\":\"Registers a disputer by updating the disputers mapping\"},\"addJob(address)\":{\"notice\":\"Allows any caller to add a new job\"},\"addLiquidityToJob(address,address,uint256)\":{\"notice\":\"Allows anyone to fund a job with liquidity\"},\"addSlasher(address)\":{\"notice\":\"Registers a slasher by updating the slashers mapping\"},\"addTokenCreditsToJob(address,address,uint256)\":{\"notice\":\"Add credit to a job to be paid out for work\"},\"approveLiquidity(address)\":{\"notice\":\"Approve a liquidity pair for being accepted in future\"},\"approvedLiquidities()\":{\"notice\":\"Lists liquidity pairs\"},\"bond(address,uint256)\":{\"notice\":\"Beginning of the bonding process\"},\"bondTime()\":{\"notice\":\"The amount of time required to pass after a keeper has bonded assets for it to be able to activate\"},\"bondedPayment(address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"bonds(address,address)\":{\"notice\":\"Mapping (job => bonding => amount)\"},\"canActivateAfter(address,address)\":{\"notice\":\"Tracks when a bonding for a keeper can be activated\"},\"canWithdrawAfter(address,address)\":{\"notice\":\"Tracks when keeper bonds are ready to be withdrawn\"},\"changeJobOwnership(address,address)\":{\"notice\":\"Proposes a new address to be the owner of the job\"},\"directTokenPayment(address,address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"dispute(address)\":{\"notice\":\"Allows governance to create a dispute for a given keeper/job\"},\"disputers(address)\":{\"notice\":\"Tracks whether the address is a disputer or not\"},\"disputes(address)\":{\"notice\":\"Tracks if a keeper or job has a pending dispute\"},\"fee()\":{\"notice\":\"The fee to be sent to governance when a user adds liquidity to a job\"},\"firstSeen(address)\":{\"notice\":\"Tracks when a keeper was first registered\"},\"forceLiquidityCreditsToJob(address,uint256)\":{\"notice\":\"Gifts liquidity credits to the specified job\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"hasBonded(address)\":{\"notice\":\"Checks whether the address has ever bonded an asset\"},\"inflationPeriod()\":{\"notice\":\"The inflation period is the denominator used to regulate the emission of KP3R\"},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"notice\":\"Confirms if the current keeper is registered and has a minimum bond of any asset.\"},\"isKeeper(address)\":{\"notice\":\"Confirms if the current keeper is registered\"},\"jobLiquidityCredits(address)\":{\"notice\":\"Returns the liquidity credits of a given job\"},\"jobOwner(address)\":{\"notice\":\"Maps the job to the owner of the job\"},\"jobPendingOwner(address)\":{\"notice\":\"Maps the job to its pending owner\"},\"jobPeriodCredits(address)\":{\"notice\":\"Returns the credits of a given job for the current period\"},\"jobTokenCredits(address,address)\":{\"notice\":\"The current token credits available for a job\"},\"jobTokenCreditsAddedAt(address,address)\":{\"notice\":\"Last block where tokens were added to the job\"},\"jobs()\":{\"notice\":\"Lists all jobs\"},\"keep3rHelper()\":{\"notice\":\"Address of Keep3rHelper's contract\"},\"keep3rV1()\":{\"notice\":\"Address of Keep3rV1's contract\"},\"keep3rV1Proxy()\":{\"notice\":\"Address of Keep3rV1Proxy's contract\"},\"keepers()\":{\"notice\":\"Lists all keepers\"},\"liquidityAmount(address,address)\":{\"notice\":\"Amount of liquidity in a specified job\"},\"liquidityMinimum()\":{\"notice\":\"The minimum amount of liquidity required to fund a job per liquidity\"},\"migrateJob(address,address)\":{\"notice\":\"Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\"},\"observeLiquidity(address)\":{\"notice\":\"Observes the current state of the liquidity pair being observed and updates TickCache with the information\"},\"pendingBonds(address,address)\":{\"notice\":\"Tracks the amount of assets deposited in pending bonds\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"pendingJobMigrations(address)\":{\"notice\":\"Maps the jobs that have requested a migration to the address they have requested to migrate to\"},\"pendingUnbonds(address,address)\":{\"notice\":\"Tracks how much keeper bonds are to be withdrawn\"},\"quoteLiquidity(address,uint256)\":{\"notice\":\"Calculates how many credits should be rewarded periodically for a given liquidity amount\"},\"removeDisputer(address)\":{\"notice\":\"Removes a disputer by updating the disputers mapping\"},\"removeSlasher(address)\":{\"notice\":\"Removes a slasher by updating the slashers mapping\"},\"resolve(address)\":{\"notice\":\"Allows governance to resolve a dispute on a keeper/job\"},\"revoke(address)\":{\"notice\":\"Blacklists a keeper from participating in the network\"},\"revokeLiquidity(address)\":{\"notice\":\"Revoke a liquidity pair from being accepted in future\"},\"rewardPeriodTime()\":{\"notice\":\"The amount of time between each scheduled credits reward given to a job\"},\"rewardedAt(address)\":{\"notice\":\"Last time the job was rewarded liquidity credits\"},\"sendDust(address,uint256,address)\":{\"notice\":\"Allows an authorized user to transfer the tokens or eth that may have been left in a contract\"},\"setBondTime(uint256)\":{\"notice\":\"Sets the bond time required to activate as a keeper\"},\"setFee(uint256)\":{\"notice\":\"Sets the new fee\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setInflationPeriod(uint256)\":{\"notice\":\"Sets the new inflation period\"},\"setKeep3rHelper(address)\":{\"notice\":\"Sets the Keep3rHelper address\"},\"setKeep3rV1(address)\":{\"notice\":\"Sets the Keep3rV1 address\"},\"setKeep3rV1Proxy(address)\":{\"notice\":\"Sets the Keep3rV1Proxy address\"},\"setLiquidityMinimum(uint256)\":{\"notice\":\"Sets the minimum amount of liquidity required to fund a job\"},\"setRewardPeriodTime(uint256)\":{\"notice\":\"Sets the time required to pass between rewards for jobs\"},\"setUnbondTime(uint256)\":{\"notice\":\"Sets the unbond time required unbond what has been bonded\"},\"slash(address,address,uint256,uint256)\":{\"notice\":\"Allows governance to slash a keeper based on a dispute\"},\"slashLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Allows governance or a slasher to slash liquidity from a job\"},\"slashTokenFromJob(address,address,uint256)\":{\"notice\":\"Allows governance or slasher to slash a job specific token\"},\"slashers(address)\":{\"notice\":\"Tracks whether the address is a slasher or not\"},\"totalJobCredits(address)\":{\"notice\":\"Calculates the total credits of a given job\"},\"unbond(address,uint256)\":{\"notice\":\"Beginning of the unbonding process\"},\"unbondLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Unbond liquidity for a job\"},\"unbondTime()\":{\"notice\":\"The amount of time required to pass before a keeper can unbond what he has bonded\"},\"withdraw(address)\":{\"notice\":\"Withdraw funds after unbonding has finished\"},\"withdrawLiquidityFromJob(address,address,address)\":{\"notice\":\"Withdraw liquidity from a job\"},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"notice\":\"Withdraw credit from a job\"},\"workCompleted(address)\":{\"notice\":\"Tracks the total KP3R earnings of a keeper since it started working\"},\"worked(address)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"workedAt(address)\":{\"notice\":\"Last time the job was worked\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/testnet/Keep3rForTestnet.sol\":\"Keep3rForTestnet\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"solidity/contracts/Keep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2003\\u2003\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2003\\u2003\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../interfaces/IKeep3r.sol';\\nimport './peripherals/jobs/Keep3rJobs.sol';\\nimport './peripherals/keepers/Keep3rKeepers.sol';\\nimport './peripherals/DustCollector.sol';\\n\\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\\n constructor(\\n address _governance,\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\\n}\\n\",\"keccak256\":\"0x0254310b27d0d227544ad1aff272b58e15ae9dc1e62ec290a46ab1b681612f6f\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/DustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '../../contracts/peripherals/Governable.sol';\\nimport '../../interfaces/peripherals/IDustCollector.sol';\\n\\nabstract contract DustCollector is IDustCollector, Governable {\\n using SafeERC20 for IERC20;\\n\\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external override onlyGovernance {\\n if (_to == address(0)) revert ZeroAddress();\\n if (_token == _ETH_ADDRESS) {\\n payable(_to).transfer(_amount);\\n } else {\\n IERC20(_token).safeTransfer(_to, _amount);\\n }\\n emit DustSent(_token, _amount, _to);\\n }\\n}\\n\",\"keccak256\":\"0x246ac2c4057520bb627ea8040367549786f4477a04fd79358927cd607952bc2f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\\nimport './Keep3rRoles.sol';\\n\\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @notice List of all enabled keepers\\n EnumerableSet.AddressSet internal _keepers;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override workCompleted;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override firstSeen;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override disputes;\\n\\n /// @inheritdoc IKeep3rAccountance\\n /// @notice Mapping (job => bonding => amount)\\n mapping(address => mapping(address => uint256)) public override bonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\\n\\n /// @notice The current liquidity credits available for a job\\n mapping(address => uint256) internal _jobLiquidityCredits;\\n\\n /// @notice Map the address of a job to its correspondent periodCredits\\n mapping(address => uint256) internal _jobPeriodCredits;\\n\\n /// @notice Enumerable array of Job Tokens for Credits\\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\\n\\n /// @notice List of liquidities that a job has (job => liquidities)\\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\\n\\n /// @notice Liquidity pool to observe\\n mapping(address => address) internal _liquidityPool;\\n\\n /// @notice Tracks if a pool has KP3R as token0\\n mapping(address => bool) internal _isKP3RToken0;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingBonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override hasBonded;\\n\\n /// @notice List of all enabled jobs\\n EnumerableSet.AddressSet internal _jobs;\\n\\n /// @inheritdoc IKeep3rAccountance\\n function jobs() external view override returns (address[] memory _list) {\\n _list = _jobs.values();\\n }\\n\\n /// @inheritdoc IKeep3rAccountance\\n function keepers() external view override returns (address[] memory _list) {\\n _list = _keepers.values();\\n }\\n}\\n\",\"keccak256\":\"0xf60c57efe1660d3eb37b4c35de90b6d69336fe53a4e129fe942c2dd6c9024b68\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rParameters.sol';\\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\\n\\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\\n /// @inheritdoc IKeep3rDisputable\\n function dispute(address _jobOrKeeper) external override onlyDisputer {\\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\\n disputes[_jobOrKeeper] = true;\\n emit Dispute(_jobOrKeeper, msg.sender);\\n }\\n\\n /// @inheritdoc IKeep3rDisputable\\n function resolve(address _jobOrKeeper) external override onlyDisputer {\\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\\n disputes[_jobOrKeeper] = false;\\n emit Resolve(_jobOrKeeper, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x664b54040aa4e734f68a01fcfb5bf67cbb1a70efd03862cd3a456457536b1fb4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/IKeep3rHelper.sol';\\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\\nimport './Keep3rAccountance.sol';\\n\\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1Proxy;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rHelper;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override bondTime = 3 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override unbondTime = 14 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override liquidityMinimum = 3 ether;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override rewardPeriodTime = 5 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override inflationPeriod = 34 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override fee = 30;\\n\\n /// @notice The base that will be used to calculate the fee\\n uint256 internal constant _BASE = 10_000;\\n\\n /// @notice The minimum reward period\\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\\n\\n constructor(\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) {\\n keep3rHelper = _keep3rHelper;\\n keep3rV1 = _keep3rV1;\\n keep3rV1Proxy = _keep3rV1Proxy;\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\\n if (_keep3rHelper == address(0)) revert ZeroAddress();\\n keep3rHelper = _keep3rHelper;\\n emit Keep3rHelperChange(_keep3rHelper);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1(address _keep3rV1) external override onlyGovernance {\\n if (_keep3rV1 == address(0)) revert ZeroAddress();\\n keep3rV1 = _keep3rV1;\\n emit Keep3rV1Change(_keep3rV1);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\\n keep3rV1Proxy = _keep3rV1Proxy;\\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\\n bondTime = _bondTime;\\n emit BondTimeChange(_bondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\\n unbondTime = _unbondTime;\\n emit UnbondTimeChange(_unbondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\\n liquidityMinimum = _liquidityMinimum;\\n emit LiquidityMinimumChange(_liquidityMinimum);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n // TODO: check what happens to credit minting when changing this. Shouldn't we update the cached ticks?\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\\n rewardPeriodTime = _rewardPeriodTime;\\n emit RewardPeriodTimeChange(_rewardPeriodTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\\n inflationPeriod = _inflationPeriod;\\n emit InflationPeriodChange(_inflationPeriod);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setFee(uint256 _fee) external override onlyGovernance {\\n fee = _fee;\\n emit FeeChange(_fee);\\n }\\n}\\n\",\"keccak256\":\"0xdad90e204120f4cfdac480a7fa2e52d656d2943e9c4016935f68a3cd1cb00d22\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport './DustCollector.sol';\\nimport './Governable.sol';\\n\\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override slashers;\\n\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override disputers;\\n\\n constructor(address _governance) Governable(_governance) DustCollector() {}\\n\\n /// @inheritdoc IKeep3rRoles\\n function addSlasher(address _slasher) external override onlyGovernance {\\n if (_slasher == address(0)) revert ZeroAddress();\\n if (slashers[_slasher]) revert SlasherExistent();\\n slashers[_slasher] = true;\\n emit SlasherAdded(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeSlasher(address _slasher) external override onlyGovernance {\\n if (!slashers[_slasher]) revert SlasherUnexistent();\\n delete slashers[_slasher];\\n emit SlasherRemoved(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function addDisputer(address _disputer) external override onlyGovernance {\\n if (_disputer == address(0)) revert ZeroAddress();\\n if (disputers[_disputer]) revert DisputerExistent();\\n disputers[_disputer] = true;\\n emit DisputerAdded(_disputer);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeDisputer(address _disputer) external override onlyGovernance {\\n if (!disputers[_disputer]) revert DisputerUnexistent();\\n delete disputers[_disputer];\\n emit DisputerRemoved(_disputer);\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a slasher or governance\\n modifier onlySlasher {\\n if (!slashers[msg.sender]) revert OnlySlasher();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a disputer or governance\\n modifier onlyDisputer {\\n if (!disputers[msg.sender]) revert OnlyDisputer();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x61a1cf0d52db8fe78fa8cfb76d9b02f93ef3adc23e6655969bc1a4bb83ea9a95\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\nimport '../Keep3rDisputable.sol';\\n\\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\\n\\n try IERC20(_token).transfer(governance, _amount) {} catch {}\\n jobTokenCredits[_job][_token] -= _amount;\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit JobSlashToken(_job, _token, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x86cdbf44dfa46c6b6e184e48e11cb8571e26cf50c793b6b07227c29e743da397\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice Cooldown between withdrawals\\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n // KP3R shouldn't be used for direct token payments\\n if (_token == keep3rV1) revert TokenUnallowed();\\n uint256 _before = IERC20(_token).balanceOf(address(this));\\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\\n uint256 _tokenFee = (_received * fee) / _BASE;\\n jobTokenCredits[_job][_token] += _received - _tokenFee;\\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\\n IERC20(_token).safeTransfer(governance, _tokenFee);\\n _jobTokens[_job].add(_token);\\n\\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external override nonReentrant onlyJobOwner(_job) {\\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\\n if (disputes[_job]) revert JobDisputed();\\n\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xb600d18903a008a1ca03743de7cef8330c2d5e66db52c900822551a4be75f7a5\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/IPairManager.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '../../libraries/FullMath.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice List of liquidities that are accepted in the system\\n EnumerableSet.AddressSet internal _approvedLiquidities;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override rewardedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override workedAt;\\n\\n /// @notice Tracks an address and returns its TickCache\\n mapping(address => TickCache) internal _tick;\\n\\n // Views\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approvedLiquidities() external view override returns (address[] memory _list) {\\n _list = _approvedLiquidities.values();\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n _periodCredits += _getReward(\\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\\n );\\n }\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n\\n // If the job was rewarded in the past 1 period time\\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\\n // If the job has period credits, update minted job credits to new twap\\n _liquidityCredits = _periodCredits > 0\\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\\n } else {\\n // Else return a full period worth of credits if current credits have expired\\n _liquidityCredits = _periodCredits;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n uint256 _cooldown = block.timestamp;\\n\\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\\n // Will calculate cooldown if it outdated\\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will calculate cooldown from last reward reference in this period\\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\\n } else {\\n // Will calculate cooldown from last reward timestamp\\n _cooldown -= rewardedAt[_job];\\n }\\n } else {\\n // Will calculate cooldown from period start if expired\\n _cooldown -= _period(block.timestamp);\\n }\\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\\n if (_tick[_liquidity].period == _period(block.timestamp)) {\\n // Will return cached twaps if liquidity is updated\\n _tickCache = _tick[_liquidity];\\n } else {\\n bool success;\\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\\n\\n if (_tick[_liquidity].period == lastPeriod) {\\n // Will only ask for current period accumulator if liquidity is outdated\\n uint32[] memory _secondsAgo = new uint32[](1);\\n int56 previousTick = _tick[_liquidity].current;\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n\\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - previousTick;\\n } else if (_tick[_liquidity].period < lastPeriod) {\\n // Will ask for 2 accumulators if liquidity is expired\\n uint32[] memory _secondsAgo = new uint32[](2);\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\\n\\n int56 _tickCumulative2;\\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - _tickCumulative2;\\n }\\n if (success) {\\n _tickCache.period = _period(block.timestamp);\\n } else {\\n delete _tickCache.period;\\n }\\n }\\n }\\n\\n // Methods\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n _settleJobAccountance(_job);\\n _jobLiquidityCredits[_job] += _amount;\\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n emit LiquidityApproval(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\\n delete _liquidityPool[_liquidity];\\n delete _isKP3RToken0[_liquidity];\\n delete _tick[_liquidity];\\n\\n emit LiquidityRevocation(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n\\n _jobLiquidities[_job].add(_liquidity);\\n\\n _settleJobAccountance(_job);\\n\\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\\n liquidityAmount[_job][_liquidity] += _amount;\\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlyJobOwner(_job) {\\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\\n pendingUnbonds[_job][_liquidity] += _amount;\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n\\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit Unbonding(_job, _liquidity, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external override onlyJobOwner(_job) {\\n if (_receiver == address(0)) revert ZeroAddress();\\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[_job]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[_job][_liquidity];\\n\\n delete pendingUnbonds[_job][_liquidity];\\n delete canWithdrawAfter[_job][_liquidity];\\n\\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\\n }\\n\\n // Internal functions\\n\\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\\n if (rewardedAt[_job] < _period(block.timestamp)) {\\n // Will exit function if job has been rewarded in current period\\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\\n // Will reset job to period syncronicity if a full period passed without rewards\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] = _period(block.timestamp);\\n _rewarded = true;\\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will reset job's syncronicity if last reward was more than epoch ago\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] += rewardPeriodTime;\\n _rewarded = true;\\n } else if (workedAt[_job] < _period(block.timestamp)) {\\n // First keeper on period has to update job accountance to current twaps\\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\\n // Updating job accountance does not reward job\\n }\\n }\\n }\\n\\n /// @notice Only called if _jobLiquidityCredits < payment\\n function _rewardJobCredits(address _job) internal {\\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\\n rewardedAt[_job] = block.timestamp;\\n }\\n\\n /// @notice Updates accountance for _jobPeriodCredits\\n function _updateJobPeriod(address _job) internal {\\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\\n }\\n\\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n if (_tick[_liquidity].period != _period(block.timestamp)) {\\n // Updates liquidity cache only if needed\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n }\\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\\n }\\n }\\n }\\n\\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\\n function _unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) internal nonReentrant {\\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\\n\\n // Ensures current twaps in job liquidities\\n _updateJobPeriod(_job);\\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\\n\\n // A liquidity can be revoked causing a job to have 0 periodCredits\\n if (_jobPeriodCredits[_job] > 0) {\\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\\n }\\n\\n liquidityAmount[_job][_liquidity] -= _amount;\\n if (liquidityAmount[_job][_liquidity] == 0) {\\n _jobLiquidities[_job].remove(_liquidity);\\n }\\n }\\n\\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\\n if (_timePassed < rewardPeriodTime) {\\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\\n } else _result = _multiplier;\\n }\\n\\n /// @notice Returns the start of the period of the provided timestamp\\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\\n return _timestamp - (_timestamp % rewardPeriodTime);\\n }\\n\\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\\n }\\n\\n /// @notice Returns underlying KP3R amount for a given liquidity amount\\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\\n if (_tick[_liquidity].period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\\n }\\n }\\n\\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\\n /// @dev Ensures a maximum of 1 period of credits\\n function _settleJobAccountance(address _job) internal virtual {\\n _updateJobCreditsIfNeeded(_job);\\n _rewardJobCredits(_job);\\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n}\\n\",\"keccak256\":\"0xe3b244460364baf1ea293db6f6feba8365fd376320ad77ae6d6813ed65b52929\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @inheritdoc IKeep3rJobManager\\n function addJob(address _job) external override {\\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\\n if (hasBonded[_job]) revert AlreadyAKeeper();\\n _jobs.add(_job);\\n jobOwner[_job] = msg.sender;\\n emit JobAddition(_job, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xf6e1577a6a34b674ca34a6d7530dc81349e3ad13d321281c37e0b25b7325d013\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\n\\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n mapping(address => address) public override pendingJobMigrations;\\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\\n if (_fromJob == _toJob) revert JobMigrationImpossible();\\n\\n pendingJobMigrations[_fromJob] = _toJob;\\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\\n\\n emit JobMigrationRequested(_fromJob, _toJob);\\n }\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\\n\\n // force job credits update for both jobs\\n _settleJobAccountance(_fromJob);\\n _settleJobAccountance(_toJob);\\n\\n // migrate tokens\\n while (_jobTokens[_fromJob].length() > 0) {\\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\\n _jobTokens[_fromJob].remove(_tokenToMigrate);\\n _jobTokens[_toJob].add(_tokenToMigrate);\\n }\\n\\n // migrate liquidities\\n while (_jobLiquidities[_fromJob].length() > 0) {\\n address _liquidity = _jobLiquidities[_fromJob].at(0);\\n\\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\\n delete liquidityAmount[_fromJob][_liquidity];\\n\\n _jobLiquidities[_toJob].add(_liquidity);\\n _jobLiquidities[_fromJob].remove(_liquidity);\\n }\\n\\n // migrate job balances\\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\\n delete _jobPeriodCredits[_fromJob];\\n\\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\\n delete _jobLiquidityCredits[_fromJob];\\n\\n // stop _fromJob from being a job\\n delete rewardedAt[_fromJob];\\n _jobs.remove(_fromJob);\\n\\n // delete unused data slots\\n delete jobOwner[_fromJob];\\n delete jobPendingOwner[_fromJob];\\n delete _migrationCreatedAt[_fromJob][_toJob];\\n delete pendingJobMigrations[_fromJob];\\n\\n emit JobMigrationSuccessful(_fromJob, _toJob);\\n }\\n}\\n\",\"keccak256\":\"0xd46c3c9ce970098d8d75f11966894a341824aceb40583fcfbbc0ebda93d869f9\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobPendingOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\\n jobPendingOwner[_job] = _newOwner;\\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\\n }\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\\n address _previousOwner = jobOwner[_job];\\n\\n jobOwner[_job] = jobPendingOwner[_job];\\n delete jobPendingOwner[_job];\\n\\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\\n }\\n\\n modifier onlyJobOwner(address _job) {\\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\\n _;\\n }\\n\\n modifier onlyPendingJobOwner(address _job) {\\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xa837590ade9cd5d25690e3f2d8b9a63e7202f7179b32e42eab4fa4c4324b9728\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobMigration.sol';\\nimport '../../../interfaces/IKeep3rHelper.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n uint256 internal _initialGas;\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\\n _initialGas = _getGasLeft();\\n if (_keepers.contains(_keeper)) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external override returns (bool _isBondedKeeper) {\\n _initialGas = _getGasLeft();\\n if (\\n _keepers.contains(_keeper) &&\\n bonds[_keeper][_bond] >= _minBond &&\\n workCompleted[_keeper] >= _earned &&\\n block.timestamp - firstSeen[_keeper] >= _age\\n ) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function worked(address _keeper) external virtual override {\\n if (_initialGas == 0) revert GasNotInitialized();\\n address _job = msg.sender;\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\\n\\n uint256 _gasLeft = _getGasLeft();\\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n _gasLeft = _getGasLeft();\\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n delete _initialGas;\\n\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function bondedPayment(address _keeper, uint256 _payment) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (disputes[_keeper]) revert Disputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_keeper, _amount);\\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\\n }\\n\\n function _bondedPayment(\\n address _job,\\n address _keeper,\\n uint256 _payment\\n ) internal {\\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\\n\\n workedAt[_job] = block.timestamp;\\n _jobLiquidityCredits[_job] -= _payment;\\n bonds[_keeper][keep3rV1] += _payment;\\n workCompleted[_keeper] += _payment;\\n }\\n\\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\\n /// @param _gasLeft Amount of gas left after working the job\\n /// @param _extraGas Amount of expected unaccounted gas\\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\\n /// @return _payment Amount to be payed in KP3R tokens\\n function _calculatePayment(\\n uint256 _gasLeft,\\n uint256 _extraGas,\\n uint256 _oneEthQuote,\\n uint256 _boost\\n ) internal view returns (uint256 _payment) {\\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\\n }\\n\\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\\n _gasLeft = (gasleft() * 64) / 63;\\n }\\n}\\n\",\"keccak256\":\"0x62a300e427311e067163104171046d2d48fce03fe3e0fa72cc39a92a8132e398\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobManager.sol';\\nimport './Keep3rJobWorkable.sol';\\nimport './Keep3rJobDisputable.sol';\\n\\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\\n\",\"keccak256\":\"0x882e1a19891795de04c4c891dc58d50034ca0a32c8b61651aaf0f47d0bc321d4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rKeeperFundable.sol';\\nimport '../Keep3rDisputable.sol';\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function revoke(address _keeper) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _keepers.remove(_keeper);\\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\\n emit KeeperRevoke(_keeper, msg.sender);\\n }\\n\\n function _slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) internal {\\n if (_bonded != keep3rV1) {\\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\\n }\\n bonds[_keeper][_bonded] -= _bondAmount;\\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\\n }\\n}\\n\",\"keccak256\":\"0xa15b13218af4331d1fb3e8cfdfa9b69117f291ac9a462ede6b1b4fb5be8967de\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\nimport '../../../interfaces/external/IKeep3rV1Proxy.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\\n if (disputes[msg.sender]) revert Disputed();\\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\\n\\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\\n\\n hasBonded[msg.sender] = true;\\n pendingBonds[msg.sender][_bonding] += _amount;\\n\\n emit Bonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function activate(address _bonding) external override {\\n address _keeper = msg.sender;\\n if (disputes[_keeper]) revert Disputed();\\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\\n if (_canActivateAfter == 0) revert BondsUnexistent();\\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\\n\\n if (firstSeen[_keeper] == 0) {\\n firstSeen[_keeper] = block.timestamp;\\n }\\n _keepers.add(_keeper);\\n\\n uint256 _amount = pendingBonds[_keeper][_bonding];\\n delete pendingBonds[_keeper][_bonding];\\n\\n _activate(_keeper, _bonding, _amount);\\n emit Activation(_keeper, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function unbond(address _bonding, uint256 _amount) external override {\\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\\n bonds[msg.sender][_bonding] -= _amount;\\n pendingUnbonds[msg.sender][_bonding] += _amount;\\n\\n emit Unbonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function withdraw(address _bonding) external override nonReentrant {\\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[msg.sender]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\\n\\n delete pendingUnbonds[msg.sender][_bonding];\\n delete canWithdrawAfter[msg.sender][_bonding];\\n\\n if (_bonding == keep3rV1) _mint(_amount);\\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\\n\\n emit Withdrawal(msg.sender, _bonding, _amount);\\n }\\n\\n function _mint(uint256 _amount) internal virtual {\\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\\n }\\n\\n function _activate(\\n address _keeper,\\n address _bonding,\\n uint256 _amount\\n ) internal virtual {\\n // bond provided tokens\\n bonds[_keeper][_bonding] += _amount;\\n if (_bonding == keep3rV1) {\\n IKeep3rV1(keep3rV1).burn(_amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8c5f69de1175d4059adb988929f93cad1d91f1110e72daefd7011be7fd1c4ac5\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\nimport './Keep3rKeeperDisputable.sol';\\n\\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\\n\",\"keccak256\":\"0xfc762d9fd6ff478acba446c3ab6fc19c7d49a85de097dc35f02c56e928153c5e\",\"license\":\"MIT\"},\"solidity/for-test/testnet/Keep3rForTestnet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../contracts/Keep3r.sol';\\n\\ncontract Keep3rForTestnet is Keep3r {\\n constructor(\\n address _governance,\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\\n bondTime = 0; // allows keepers to instantly register\\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\\n liquidityMinimum = 1; // allows job providers to add low liquidity\\n rewardPeriodTime = 1 days; // reduces twap calculation period\\n inflationPeriod = 5 days; // increases credit mintint\\n }\\n}\\n\",\"keccak256\":\"0x352f197aacd9a3f89519279c30652782d0bde64f51a4094f25624fa4e8a7ccd4\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct TokenOraclePool {\\n address poolAddress;\\n bool isTKNToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0x76f99ca04361c0459fc9e99f0387ddb76da18cc470ec5bc744e7dc3bf6e9d334\",\"license\":\"MIT\"},\"solidity/interfaces/IPairManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n/// @title Pair Manager interface\\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\\ninterface IPairManager is IERC20Metadata {\\n /// @notice Address of the factory from which the pair manager was created\\n /// @return _factory The address of the PairManager Factory\\n function factory() external view returns (address _factory);\\n\\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\\n /// @return _pool The address of the pool\\n function pool() external view returns (address _pool);\\n\\n /// @notice Token0 of the pool\\n /// @return _token0 The address of token0\\n function token0() external view returns (address _token0);\\n\\n /// @notice Token1 of the pool\\n /// @return _token1 The address of token1\\n function token1() external view returns (address _token1);\\n}\\n\",\"keccak256\":\"0x345c312b340c5775fb8f68d89ce851c7f75522940bd9bc64f2301a3f8312636a\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IGovernable.sol';\\n\\ninterface IKeep3rV1Proxy is IGovernable {\\n // Structs\\n struct Recipient {\\n address recipient;\\n uint256 caps;\\n }\\n\\n // Variables\\n function keep3rV1() external view returns (address);\\n\\n function minter() external view returns (address);\\n\\n function next(address) external view returns (uint256);\\n\\n function caps(address) external view returns (uint256);\\n\\n function recipients() external view returns (address[] memory);\\n\\n function recipientsCaps() external view returns (Recipient[] memory);\\n\\n // Errors\\n error Cooldown();\\n error NoDrawableAmount();\\n error ZeroAddress();\\n error OnlyMinter();\\n\\n // Methods\\n function addRecipient(address recipient, uint256 amount) external;\\n\\n function removeRecipient(address recipient) external;\\n\\n function draw() external returns (uint256 _amount);\\n\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n function setMinter(address _minter) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function mint(address _account, uint256 _amount) external;\\n\\n function setKeep3rV1Governance(address _governance) external;\\n\\n function acceptKeep3rV1Governance() external;\\n\\n function dispute(address _keeper) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function addJob(address _job) external;\\n\\n function removeJob(address _job) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n}\\n\",\"keccak256\":\"0xfb2e81fe347b39aabce849ef2d42c6df846b7ef0ed5ae952c85bbb708da99408\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0x060f701c6991d323bcf360738568714956013b17b3e3443ea21d825a70c3947c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040526203f480601e5562127500601f556729a2241af62c000060205562069780602155622cd300602255601e6023553480156200003e57600080fd5b5060405162005fa638038062005fa683398101604081905262000061916200012a565b60016000558383838382828286806001600160a01b038116620000965760405162b293ed60e81b815260040160405180910390fd5b600380546001600160a01b03199081166001600160a01b0393841617909155601d8054821696831696909617909555601b805486169482169490941790935550601c8054909316911617905550506000601e819055601f555050600160205550506201518060215550506206978060225562000187565b80516001600160a01b03811681146200012557600080fd5b919050565b600080600080608085870312156200014157600080fd5b6200014c856200010d565b93506200015c602086016200010d565b92506200016c604086016200010d565b91506200017c606086016200010d565b905092959194509250565b615e0f80620001976000396000f3fe608060405234801561001057600080fd5b50600436106103d65760003560e01c8063951dc22c11610202578063c5198abc11610121578063c5198abc146109a5578063c7ae40d0146109b8578063cb4be2bb146109cb578063cb54694d146109de578063cd22af1b146109f1578063d55995fe14610a1c578063dd2080d614610a2f578063ddca3f4314610a42578063e326ac4314610a4b578063ebbb619414610a6b578063ec00cdfc14610a7e578063ec8ca64314610a91578063f0f346b914610aba578063f11a1d1a14610acd578063f136a09d14610ae0578063f25e311b14610b00578063f39c38a014610b13578063f75f9f7b14610b26578063f9d46cf214610b39578063fc253d2b14610b4c578063fe75bc4614610b5557600080fd5b8063951dc22c146107cb578063966abd00146107d357806398e90a0f146107e65780639d5c33d81461080f578063a214580914610822578063a39744b514610835578063a515366a14610860578063a5d059ca14610873578063a676f9ff14610886578063a7d2e784146108a6578063aac6aa9c146108af578063ab033ea9146108c2578063af320e81146108d5578063b0103b1a146108e8578063b23922331461090b578063b440027f1461091e578063b600702a14610949578063b7e773401461095c578063b87fcbff1461096f578063c20297f01461099257600080fd5b806359a2255e116102f957806359a2255e146106275780635aa6e6751461063a5780635ebe23f01461064d5780635feeb79414610656578063633fb68f1461066957806364bb43ee1461067257806368a9f19c14610685578063694798e61461069857806369fe0e2d146106c35780636ba42aaa146106d65780636cf262bc146106e95780636e2a9ca6146106fc57806372da828a1461070f57806374a8f10314610722578063768b5d90146107355780637c8fce231461073e578063878c723e146107465780638bb6dfa81461076f5780638cb22b76146107825780638fe204dd146107a557806390a4684e146107b857600080fd5b8063034d4c61146103db57806307b435c2146104015780630c620bce1461042c5780630d6a1f87146104415780631101eb411461045457806311466d721461046957806315006b821461047c578063165e62e7146104a7578063168f92e7146104e45780631b44555e1461050f5780631c5a9d9c1461052f5780631ef94b911461054257806321040b0114610562578063238efcbc1461058d578063274a8db41461059557806351cff8d9146105c857806352a4de29146105db57806355ea6c47146105ee578063575288bf14610601578063594a3a9314610614575b600080fd5b6103ee6103e9366004615760565b610b68565b6040519081526020015b60405180910390f35b6103ee61040f36600461579a565b601660209081526000928352604080842090915290825290205481565b610434610c6e565b6040516103f89190615b0f565b6103ee61044f366004615949565b610c7f565b61046761046236600461581e565b610d85565b005b610467610477366004615949565b610edf565b6103ee61048a36600461579a565b601460209081526000928352604080842090915290825290205481565b6104ba6104b5366004615760565b61106e565b604080518251600690810b825260208085015190910b9082015291810151908201526060016103f8565b6103ee6104f236600461579a565b600d60209081526000928352604080842090915290825290205481565b6103ee61051d366004615760565b60096020526000908152604090205481565b61046761053d366004615760565b611434565b601b54610555906001600160a01b031681565b6040516103f89190615a86565b6103ee61057036600461579a565b601760209081526000928352604080842090915290825290205481565b610467611598565b6105b86105a3366004615760565b60066020526000908152604090205460ff1681565b60405190151581526020016103f8565b6104676105d6366004615760565b611624565b6104676105e936600461581e565b6117bc565b6104676105fc366004615760565b6119ee565b61046761060f36600461581e565b611aa2565b61046761062236600461579a565b611d65565b610467610635366004615760565b611e0a565b600354610555906001600160a01b031681565b6103ee601e5481565b610467610664366004615760565b611ebc565b6103ee60205481565b610467610680366004615760565b61214b565b610467610693366004615760565b61222c565b6103ee6106a636600461579a565b602760209081526000928352604080842090915290825290205481565b6104676106d1366004615a0a565b61230b565b6105b86106e4366004615760565b61236b565b6103ee6106f7366004615760565b6123cb565b61046761070a36600461581e565b612501565b61046761071d366004615760565b612650565b610467610730366004615760565b6126ed565b6103ee60215481565b6104346127e8565b610555610754366004615760565b6001602052600090815260409020546001600160a01b031681565b6103ee61077d366004615760565b6127f4565b6105b8610790366004615760565b60186020526000908152604090205460ff1681565b6104676107b3366004615a0a565b612897565b6104676107c636600461579a565b6128f7565b6104346129e5565b6104676107e1366004615975565b6129f1565b6105556107f4366004615760565b6002602052600090815260409020546001600160a01b031681565b61046761081d366004615760565b612b07565b6104676108303660046157d3565b612be6565b6103ee61084336600461579a565b600c60209081526000928352604080842090915290825290205481565b61046761086e366004615949565b612db6565b610467610881366004615949565b613017565b6103ee610894366004615760565b60286020526000908152604090205481565b6103ee601f5481565b6104676108bd366004615760565b6130f1565b6104676108d0366004615760565b6131a5565b6104676108e336600461579a565b61321b565b6105b86108f6366004615760565b600b6020526000908152604090205460ff1681565b610467610919366004615a0a565b61369a565b6103ee61092c36600461579a565b602460209081526000928352604080842090915290825290205481565b610467610957366004615760565b6136fa565b61046761096a366004615a0a565b61391f565b6105b861097d366004615760565b60056020526000908152604090205460ff1681565b6104676109a03660046158b2565b61397f565b6104676109b3366004615760565b613a38565b601c54610555906001600160a01b031681565b6104676109d9366004615760565b613afe565b6104676109ec366004615a0a565b613b9b565b6103ee6109ff36600461579a565b601560209081526000928352604080842090915290825290205481565b610467610a2a36600461585f565b613c1f565b610467610a3d36600461581e565b613e56565b6103ee60235481565b6103ee610a59366004615760565b600a6020526000908152604090205481565b610467610a79366004615a0a565b613fd3565b610467610a8c366004615760565b614031565b610555610a9f366004615760565b602b602052600090815260409020546001600160a01b031681565b610467610ac8366004615760565b6140ce565b601d54610555906001600160a01b031681565b6103ee610aee366004615760565b60296020526000908152604090205481565b610467610b0e36600461581e565b614182565b600454610555906001600160a01b031681565b610467610b34366004615760565b6143c7565b6105b8610b473660046158f8565b61447f565b6103ee60225481565b610467610b63366004615949565b614568565b600080610b74836123cb565b6021549091504290610b8f90610b8a9083615c90565b614658565b6001600160a01b0385166000908152602860205260409020541115610c33576021546001600160a01b038516600090815260286020526040902054610bd49042615c90565b10610c10576021546001600160a01b038516600090815260286020526040902054610bff9190615bf5565b610c099082615c90565b9050610c49565b6001600160a01b038416600090815260286020526040902054610c099082615c90565b610c3c42614658565b610c469082615c90565b90505b610c538183614672565b610c5c856127f4565b610c669190615bf5565b949350505050565b6060610c7a602561469c565b905090565b6000610c8c6025846146b0565b15610d7f576000610c9c8461106e565b90508060400151600014610d7d576001600160a01b03841660009081526013602052604081205460ff16610cdd578160200151610cd890615d02565b610ce3565b81602001515b601d5460215460405163a0d2710760e01b8152929350610d74926001600160a01b039092169163a0d2710791610d1f9189918791600401615bc6565b60206040518083038186803b158015610d3757600080fd5b505afa158015610d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6f9190615a23565b6146d2565b92505050610d7f565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610dc157604051636efb4f4160e11b815260040160405180910390fd5b601f54610dce9042615bf5565b6001600160a01b03808616600081815260166020908152604080832094891680845294825280832095909555918152601782528381209281529190529081208054849290610e1d908490615bf5565b90915550610e2e90508484846146e3565b6001600160a01b038085166000908152602760209081526040808320938716835292905220548015801590610e6d5750602054610e6b82866148f1565b105b15610e8b57604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de85604051610ed091815260200190565b60405180910390a35050505050565b336000818152600b602052604090205460ff1615610f105760405163ad2fdf3b60e01b815260040160405180910390fd5b610f1b6019826146b0565b610f375760405162941a5760e11b815260040160405180910390fd5b610f4081614a0f565b15610f9b576001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615dba83398151915293610f929390929091615bdf565b60405180910390a25b6001600160a01b0381166000908152600e602052604090205482111561101a57610fc481614be5565b6001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615dba833981519152936110119390929091615bdf565b60405180910390a25b611025818484614c73565b601b546001600160a01b03808516918382169116600080516020615d9a83398151915285611051614d57565b6040805192835260208301919091520160405180910390a4505050565b604080516060810182526000808252602082018190529181019190915261109442614658565b6001600160a01b0383166000908152602a6020526040902060010154141561110a57506001600160a01b03166000908152602a602090815260409182902082516060810184528154600681810b810b810b8352600160381b909104810b810b900b92810192909252600101549181019190915290565b60008061111e60215442610b8a9190615c90565b6001600160a01b0385166000908152602a602052604090206001015490915081141561128257604080516001808252818301909252600091602080830190803683375050506001600160a01b0386166000908152602a602052604090205490915060060b61118b42614658565b6111959042615c90565b826000815181106111a8576111a8615d6b565b63ffffffff909216602092830291909101820152601d546001600160a01b038881166000908152601290935260409283902054925163dc686d9160e01b81529181169263dc686d91926112049291909116908690600401615a9a565b60606040518083038186803b15801561121c57600080fd5b505afa158015611230573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125491906159c7565b600692830b90920b80885291955061126e91839150615c40565b600690810b900b60208601525061140b9050565b6001600160a01b0384166000908152602a602052604090206001015481111561140b576040805160028082526060820183526000926020830190803683370190505090506112cf42614658565b6112d99042615c90565b816000815181106112ec576112ec615d6b565b602002602001019063ffffffff16908163ffffffff168152505060215461131242614658565b61131c9042615c90565b6113269190615bf5565b8160018151811061133957611339615d6b565b63ffffffff909216602092830291909101820152601d546001600160a01b0387811660009081526012909352604080842054905163dc686d9160e01b81529282169263dc686d91926113919216908690600401615a9a565b60606040518083038186803b1580156113a957600080fd5b505afa1580156113bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e191906159c7565b600692830b90920b80885291955091506113fc908290615c40565b600690810b900b602086015250505b81156114245761141a42614658565b604084015261142c565b600060408401525b50505b919050565b336000818152600b602052604090205460ff1615611465576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b03808216600090815260156020908152604080832093861683529290522054806114a957604051636258f48160e01b815260040160405180910390fd5b4281106114c957604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600a6020526040902054611502576001600160a01b0382166000908152600a602052604090204290555b61150d600783614d71565b506001600160a01b03828116600090815260146020908152604080832093871683529290529081208054919055611545838583614d86565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a758360405161158a91815260200190565b60405180910390a350505050565b6004546001600160a01b031633146115c357604051637ef5703160e11b815260040160405180910390fd5b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161161a91615a86565b60405180910390a1565b600260005414156116505760405162461bcd60e51b815260040161164790615b8f565b60405180910390fd5b600260009081553381526017602090815260408083206001600160a01b03851684529091529020546116955760405163184c088160e21b815260040160405180910390fd5b3360009081526016602090815260408083206001600160a01b038516845290915290205442116116d8576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600b602052604090205460ff1615611709576040516362e6201d60e01b815260040160405180910390fd5b3360008181526017602090815260408083206001600160a01b038681168086529184528285208054908690559585526016845282852082865290935290832092909255601b5416141561175f5761175f81614e3c565b6117736001600160a01b0383163383614e9d565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b600260005414156117df5760405162461bcd60e51b815260040161164790615b8f565b60026000556117ef6025836146b0565b61180c5760405163e0b6aead60e01b815260040160405180910390fd5b6118176019846146b0565b61183457604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526011602052604090206118569083614d71565b5061186083614ef3565b602080546001600160a01b0380861660009081526027845260408082209287168252919093529091205461189f90611899908490615bf5565b846148f1565b10156118be57604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615dba8339815191529361190b9390929091615bdf565b60405180910390a26119286001600160a01b038316333084614f51565b6001600160a01b0380841660009081526027602090815260408083209386168352929052908120805483929061195f908490615bf5565b909155506119729050610d6f82846148f1565b6001600160a01b0384166000908152600f60205260408120805490919061199a908490615bf5565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff16611a1e57604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff16611a57576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600b6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b60026000541415611ac55760405162461bcd60e51b815260040161164790615b8f565b6002600055611ad56019846146b0565b611af257604051636211d34960e01b815260040160405180910390fd5b601b546001600160a01b0383811691161415611b205760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038416906370a0823190611b4f903090600401615a86565b60206040518083038186803b158015611b6757600080fd5b505afa158015611b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9f9190615a23565b9050611bb66001600160a01b038416333085614f51565b600081846001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611be59190615a86565b60206040518083038186803b158015611bfd57600080fd5b505afa158015611c11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c359190615a23565b611c3f9190615c90565b9050600061271060235483611c549190615c21565b611c5e9190615c0d565b9050611c6a8183615c90565b6001600160a01b038088166000908152600d60209081526040808320938a1683529290529081208054909190611ca1908490615bf5565b90915550506001600160a01b0380871660009081526024602090815260408083208985168085529252909120429055600354611cde921683614e9d565b6001600160a01b0386166000908152601060205260409020611d009086614d71565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611d5091815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611da157604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611e465760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b602d54611edc57604051630262ab9b60e61b815260040160405180910390fd5b336000818152600b602052604090205460ff1615611f0d5760405163ad2fdf3b60e01b815260040160405180910390fd5b611f186019826146b0565b611f345760405162941a5760e11b815260040160405180910390fd5b611f3d81614a0f565b15611f98576001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615dba83398151915293611f8f9390929091615bdf565b60405180910390a25b601d546001600160a01b038381166000908152600c60209081526040808320601b548516845290915280822054905163435b21c160e01b8152600481019190915290928392839291169063435b21c19060240160606040518083038186803b15801561200357600080fd5b505afa158015612017573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203b9190615a3c565b925092509250600061204b614d57565b9050600061205b82848688614f8f565b6001600160a01b0387166000908152600e60205260409020549091508111156120f55761208786614be5565b6001600160a01b038616600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615dba833981519152936120d49390929091615bdf565b60405180910390a26120e4614d57565b91506120f282848688614f8f565b90505b612100868883614c73565b6000602d55601b5460408051838152602081018590526001600160a01b038a8116938a821693911691600080516020615d9a833981519152910160405180910390a450505050505050565b6003546001600160a01b03163314612176576040516354348f0360e01b815260040160405180910390fd5b612181602582614fec565b61219e57604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600090815260126020908152604080832080546001600160a01b031916905560138252808320805460ff19169055602a90915280822080546001600160701b031916815560010191909155517f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e5690612221908390615a86565b60405180910390a150565b6003546001600160a01b03163314612257576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661227e5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16156122b85760405163546da66560e11b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b90612221908390615a86565b6003546001600160a01b03163314612336576040516354348f0360e01b815260040160405180910390fd5b60238190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d90602001612221565b6000612375614d57565b602d556123836007836146b0565b1561142f577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602d546040516123bb91815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b03831660009081526011602052604090206123f090615001565b8110156124fb576001600160a01b0383166000908152601160205260408120612419908361500b565b90506124266025826146b0565b156124e85760006124368261106e565b905080604001516000146124e6576001600160a01b03821660009081526013602052604081205460ff1661247757816020015161247290615d02565b61247d565b81602001515b601d546001600160a01b03888116600090815260276020908152604080832089851684529091529081902054602154915163a0d2710760e01b81529495506124d894929093169263a0d2710792610d1f928791600401615bc6565b6124e29086615bf5565b9450505b505b50806124f381615cd3565b9150506123cf565b50919050565b3360009081526005602052604090205460ff1661253157604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff1661256a576040516310cec38560e21b815260040160405180910390fd5b6125758383836146e3565b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb926125a992909116908590600401615af6565b602060405180830381600087803b1580156125c357600080fd5b505af19250505080156125f3575060408051601f3d908101601f191682019092526125f0918101906159ac565b60015b6125fc576125fe565b505b336001600160a01b0316836001600160a01b03167f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e8484604051612643929190615af6565b60405180910390a3505050565b6003546001600160a01b0316331461267b576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166126a25760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383161790556040517f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b090612221908390615a86565b3360009081526005602052604090205460ff1661271d57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff16612756576040516310cec38560e21b815260040160405180910390fd5b612761600782614fec565b50601b546001600160a01b038083166000818152600c60209081526040808320949095168083529381528482205492825260178152848220848352905292909220546127af92849291615017565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610c7a601961469c565b600080612800836123cb565b6021546001600160a01b0385166000908152602860205260409020549192509061282a9042615c90565b1015610d7f5760008111612856576001600160a01b0383166000908152600e6020526040902054612890565b6001600160a01b0383166000908152600f6020908152604080832054600e90925290912054612886908390615c21565b6128909190615c0d565b91506124fb565b6003546001600160a01b031633146128c2576040516354348f0360e01b815260040160405180910390fd5b601f8190556040518181527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee290602001612221565b6001600160a01b03828116600090815260016020526040902054839116331461293357604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156129665760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602b6020908152604080832080546001600160a01b0319169588169586179055602c825280832094835293905282902042905590517fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c906129d8908590615a86565b60405180910390a2505050565b6060610c7a600761469c565b6003546001600160a01b03163314612a1c576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116612a435760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415612aa4576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015612a9e573d6000803e3d6000fd5b50612ab8565b612ab86001600160a01b0384168284614e9d565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b03163314612b32576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116612b595760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1615612b935760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19166001179055517f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f90612221908390615a86565b6001600160a01b038381166000908152600160205260409020548491163314612c2257604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b038216612c495760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03808516600090815260176020908152604080832093871683529290522054612c8c5760405163184c088160e21b815260040160405180910390fd5b6001600160a01b038085166000908152601660209081526040808320938716835292905220544211612cd1576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600b602052604090205460ff1615612d0b576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b0380851660008181526017602090815260408083209488168084529482528083208054908490559383526016825280832085845290915281205590612d58908483614e9d565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca792886284604051612da791815260200190565b60405180910390a45050505050565b60026000541415612dd95760405162461bcd60e51b815260040161164790615b8f565b60026000908155338152600b602052604090205460ff1615612e0e576040516362e6201d60e01b815260040160405180910390fd5b612e196019336146b0565b15612e375760405163d7229c4360e01b815260040160405180910390fd5b601e54612e449042615bf5565b3360009081526015602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81529091906370a0823190612e8f903090600401615a86565b60206040518083038186803b158015612ea757600080fd5b505afa158015612ebb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612edf9190615a23565b9050612ef66001600160a01b038416333085614f51565b6040516370a0823160e01b815281906001600160a01b038516906370a0823190612f24903090600401615a86565b60206040518083038186803b158015612f3c57600080fd5b505afa158015612f50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f749190615a23565b612f7e9190615c90565b336000908152601860209081526040808320805460ff19166001179055601482528083206001600160a01b0388168452909152812080549294508492909190612fc8908490615bf5565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b601f546130249042615bf5565b3360008181526016602090815260408083206001600160a01b03881680855290835281842095909555928252600c81528282209382529290925281208054839290613070908490615c90565b90915550503360009081526017602090815260408083206001600160a01b0386168452909152812080548392906130a8908490615bf5565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b0316331461311c576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16613155576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19169055517f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d02590612221908390615a86565b6003546001600160a01b031633146131d0576040516354348f0360e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90612221908390615a86565b6001600160a01b03818116600090815260016020526040902054829116331461325757604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff168061329657506001600160a01b0382166000908152600b602052604090205460ff165b156132b45760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602b60205260409020548116908316146132f157604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602c602090815260408083209386168352929052205461332390603c90615bf5565b421015613343576040516356248e9760e01b815260040160405180910390fd5b61334c83614ef3565b61335582614ef3565b6001600160a01b038316600090815260106020526040812061337690615001565b1115613458576001600160a01b038316600090815260106020526040812061339e908261500b565b6001600160a01b038086166000908152600d6020818152604080842085871680865290835281852054958a1685529282528084209284529190528120805493945091926133ec908490615bf5565b90915550506001600160a01b038085166000818152600d60209081526040808320948616835293815283822082905591815260109091522061342e9082614fec565b506001600160a01b03831660009081526010602052604090206134519082614d71565b5050613355565b6001600160a01b038316600090815260116020526040812061347990615001565b111561355b576001600160a01b03831660009081526011602052604081206134a1908261500b565b6001600160a01b03808616600090815260276020818152604080842085871680865290835281852054958a1685529282528084209284529190528120805493945091926134ef908490615bf5565b90915550506001600160a01b03808516600090815260276020908152604080832085851684528252808320839055928616825260119052206135319082614d71565b506001600160a01b03841660009081526011602052604090206135549082614fec565b5050613458565b6001600160a01b038084166000908152600f60205260408082205492851682528120805490919061358d908490615bf5565b90915550506001600160a01b038084166000908152600f60209081526040808320839055600e909152808220549285168252812080549091906135d1908490615bf5565b90915550506001600160a01b0383166000908152600e602090815260408083208390556028909152812055613607601984614fec565b506001600160a01b03808416600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602c8352818420958816808552958352818420849055938352602b909152908190208054909216909155517f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f2906129d8908690615a86565b6003546001600160a01b031633146136c5576040516354348f0360e01b815260040160405180910390fd5b60228190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb6990602001612221565b6003546001600160a01b03163314613725576040516354348f0360e01b815260040160405180910390fd5b613730602582614d71565b61374d5760405163f25e6b9f60e01b815260040160405180910390fd5b806001600160a01b03166316f0115b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561378657600080fd5b505afa15801561379a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137be919061577d565b6001600160a01b038281166000908152601260205260409081902080546001600160a01b0319169383169384179055601d54905163696a437b60e01b815291169163696a437b916138129190600401615a86565b60206040518083038186803b15801561382a57600080fd5b505afa15801561383e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061386291906159ac565b6001600160a01b0382166000908152601360205260409020805460ff19169115159190911790556138928161106e565b6001600160a01b0382166000908152602a60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b161791909117815591810151600190920191909155517fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b90612221908390615a86565b6003546001600160a01b0316331461394a576040516354348f0360e01b815260040160405180910390fd5b601e8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b4390602001612221565b3360009081526005602052604090205460ff166139af57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600b602052604090205460ff166139e8576040516310cec38560e21b815260040160405180910390fd5b6139f484848484615017565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613a2a8486615bf5565b60405190815260200161158a565b613a436019826146b0565b15613a6157604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526018602052604090205460ff1615613a9b57604051632f3d320560e01b815260040160405180910390fd5b613aa6601982614d71565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613b29576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116613b505760405163d92e233d60e01b815260040160405180910390fd5b601c80546001600160a01b0319166001600160a01b0383161790556040517feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae25090612221908390615a86565b6003546001600160a01b03163314613bc6576040516354348f0360e01b815260040160405180910390fd5b62015180811015613bea57604051633f384aad60e21b815260040160405180910390fd5b60218190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d990602001612221565b60026000541415613c425760405162461bcd60e51b815260040161164790615b8f565b600260009081556001600160a01b03858116825260016020526040909120548591163314613c8357604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260246020908152604080832093881683529290522054613cb590603c90615bf5565b4211613cd457604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600d6020908152604080832093881683529290522054831115613d1a5760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600b602052604090205460ff1615613d545760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600d6020908152604080832093881683529290529081208054859290613d8b908490615c90565b90915550613da590506001600160a01b0385168385614e9d565b6001600160a01b038086166000908152600d6020908152604080832093881683529290522054613df3576001600160a01b0385166000908152601060205260409020613df19085614fec565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613e4291815260200190565b60405180910390a450506001600055505050565b336000818152600b602052604090205460ff1615613e875760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff1615613ec1576040516362e6201d60e01b815260040160405180910390fd5b613ecc6019826146b0565b613ee85760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600d6020908152604080832093881683529290522054821115613f2e5760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600d6020908152604080832093881683529290529081208054849290613f65908490615c90565b90915550613f7f90506001600160a01b0385168484614e9d565b826001600160a01b0316816001600160a01b0316856001600160a01b0316600080516020615d9a83398151915285613fb5614d57565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b03163314613ffe576040516354348f0360e01b815260040160405180910390fd5b60208181556040518281527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e79101612221565b6003546001600160a01b0316331461405c576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166140835760405163d92e233d60e01b815260040160405180910390fd5b601b80546001600160a01b0319166001600160a01b0383161790556040517f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf90612221908390615a86565b6003546001600160a01b031633146140f9576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1661413257604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19169055517f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e90612221908390615a86565b3360009081526005602052604090205460ff166141b257604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff166141eb576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b038316600090815260106020526040902061420d90836146b0565b61422a57604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600d602090815260408083209386168352929052205481111561426f5760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb926142a392909116908590600401615af6565b602060405180830381600087803b1580156142bd57600080fd5b505af19250505080156142ed575060408051601f3d908101601f191682019092526142ea918101906159ac565b60015b6142f6576142f8565b505b6001600160a01b038084166000908152600d602090815260408083209386168352929052908120805483929061432f908490615c90565b90915550506001600160a01b038084166000908152600d6020908152604080832093861683529290522054614382576001600160a01b03831660009081526010602052604090206143809083614fec565b505b336001600160a01b0316836001600160a01b03167f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d3183331048484604051612643929190615af6565b3360009081526006602052604090205460ff166143f757604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff1615614431576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600b6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b6000614489614d57565b602d556144976007876146b0565b80156144c857506001600160a01b038087166000908152600c60209081526040808320938916835292905220548411155b80156144ec57506001600160a01b0386166000908152600960205260409020548311155b801561451b57506001600160a01b0386166000908152600a602052604090205482906145189042615c90565b10155b1561455f577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602d5460405161455391815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b03163314614593576040516354348f0360e01b815260040160405180910390fd5b61459e6019836146b0565b6145bb57604051636211d34960e01b815260040160405180910390fd5b6145c482614ef3565b6001600160a01b0382166000908152600e6020526040812080548392906145ec908490615bf5565b90915550506001600160a01b038216600081815260286020908152604080832054600e909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d19261464c928252602082015260400190565b60405180910390a25050565b6000602154826146689190615cee565b610d7f9083615c90565b60006021548310156124fb5760215461468b8385615c21565b6146959190615c0d565b9050610d7f565b606060006146a98361516d565b9392505050565b6001600160a01b038116600090815260018301602052604081205415156146a9565b6000610d7f826021546022546151c9565b600260005414156147065760405162461bcd60e51b815260040161164790615b8f565b600260009081556001600160a01b038416815260116020526040902061472c90836146b0565b614748576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b0380841660009081526027602090815260408083209386168352929052205481111561478e5760405163435b562560e01b815260040160405180910390fd5b61479783615277565b60006147a6610d6f83856148f1565b6001600160a01b0385166000908152600f60205260409020549091501561485c576001600160a01b0384166000908152600f6020908152604080832054600e909252909120546147f7908390615c21565b6148019190615c0d565b6001600160a01b0385166000908152600e602052604081208054909190614829908490615c90565b90915550506001600160a01b0384166000908152600f602052604081208054839290614856908490615c90565b90915550505b6001600160a01b03808516600090815260276020908152604080832093871683529290529081208054849290614893908490615c90565b90915550506001600160a01b038085166000908152602760209081526040808320938716835292905220546148e6576001600160a01b03841660009081526011602052604090206148e49084614fec565b505b505060016000555050565b6001600160a01b0381166000908152602a602052604081206001015415610d7f576001600160a01b03821660009081526013602052604081205460ff16614963576001600160a01b0383166000908152602a602052604090205461495e90600160381b900460060b615d02565b614987565b6001600160a01b0383166000908152602a6020526040902054600160381b900460060b5b601d5460215460405163a0d2710760e01b81529293506001600160a01b039091169163a0d27107916149bf9188918691600401615bc6565b60206040518083038186803b1580156149d757600080fd5b505afa1580156149eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c669190615a23565b6000614a1a42614658565b6001600160a01b038316600090815260286020526040902054101561142f57614a4a60215442610b8a9190615c90565b6001600160a01b03831660009081526028602052604090205411614ac057614a7182615277565b6001600160a01b0382166000908152600f6020908152604080832054600e90925290912055614a9f42614658565b6001600160a01b038316600090815260286020526040902055506001919050565b6021546001600160a01b038316600090815260286020526040902054614ae69042615c90565b10614b4257614af482615277565b6001600160a01b0382166000908152600f6020908152604080832054600e83528184205560215460289092528220805491929091614b33908490615bf5565b909155506001915061142f9050565b614b4b42614658565b6001600160a01b038316600090815260296020526040902054101561142f576001600160a01b0382166000908152600f6020526040902054614b8c83615277565b6001600160a01b0383166000908152600f6020908152604080832054600e909252909120548291614bbc91615c21565b614bc69190615c0d565b6001600160a01b0384166000908152600e602052604090205550919050565b6001600160a01b038116600090815260286020526040902054614c2a90614c0c9042615c90565b6001600160a01b0383166000908152600f6020526040902054614672565b6001600160a01b0382166000908152600e602052604081208054909190614c52908490615bf5565b90915550506001600160a01b03166000908152602860205260409020429055565b6001600160a01b0383166000908152600e6020526040902054811115614cac5760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602960209081526040808320429055600e90915281208054839290614ce1908490615c90565b90915550506001600160a01b038083166000908152600c60209081526040808320601b5490941683529290529081208054839290614d20908490615bf5565b90915550506001600160a01b03821660009081526009602052604081208054839290614d4d908490615bf5565b9091555050505050565b6000603f5a614d67906040615c21565b610c7a9190615c0d565b60006146a9836001600160a01b03841661529c565b6001600160a01b038084166000908152600c6020908152604080832093861683529290529081208054839290614dbd908490615bf5565b9091555050601b546001600160a01b0383811691161415614e3757601b54604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c6890602401600060405180830381600087803b158015614e1e57600080fd5b505af1158015614e32573d6000803e3d6000fd5b505050505b505050565b601c5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401600060405180830381600087803b158015614e8257600080fd5b505af1158015614e96573d6000803e3d6000fd5b5050505050565b614e378363a9059cbb60e01b8484604051602401614ebc929190615af6565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526152eb565b614efc81614a0f565b50614f0681614be5565b6001600160a01b0381166000908152600e6020908152604080832054600f90925290912054614f3591906153bd565b6001600160a01b039091166000908152600e6020526040902055565b6040516001600160a01b0380851660248301528316604482015260648101829052614f899085906323b872dd60e01b90608401614ebc565b50505050565b6000808486602d54614fa19190615c90565b614fab9190615bf5565b9050670de0b6b3a764000084612710614fc48685615c21565b614fce9190615c0d565b614fd89190615c21565b614fe29190615c0d565b9695505050505050565b60006146a9836001600160a01b0384166153d3565b6000610d7f825490565b60006146a983836154c6565b601b546001600160a01b038481169116146150ef576003546001600160a01b038085169163a9059cbb911661504c8486615bf5565b6040518363ffffffff1660e01b8152600401615069929190615af6565b602060405180830381600087803b15801561508357600080fd5b505af19250505080156150b3575060408051601f3d908101601f191682019092526150b0918101906159ac565b60015b6150ed573d8080156150e1576040519150601f19603f3d011682016040523d82523d6000602084013e6150e6565b606091505b50506150ef565b505b6001600160a01b038085166000908152600c6020908152604080832093871683529290529081208054849290615126908490615c90565b90915550506001600160a01b03808516600090815260176020908152604080832093871683529290529081208054839290615162908490615c90565b909155505050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156151bd57602002820191906000526020600020905b8154815260200190600101908083116151a9575b50505050509050919050565b60008080600019858709858702925082811083820303915050806000141561520357600084116151f857600080fd5b5082900490506146a9565b80841161520f57600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b615280816154f0565b6001600160a01b039091166000908152600f6020526040902055565b60008181526001830160205260408120546152e357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d7f565b506000610d7f565b6000615340826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166156339092919063ffffffff16565b805190915015614e37578080602001905181019061535e91906159ac565b614e375760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611647565b60008183106153cc57816146a9565b5090919050565b600081815260018301602052604081205480156154bc5760006153f7600183615c90565b855490915060009061540b90600190615c90565b905081811461547057600086600001828154811061542b5761542b615d6b565b906000526020600020015490508087600001848154811061544e5761544e615d6b565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061548157615481615d55565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d7f565b6000915050610d7f565b60008260000182815481106154dd576154dd615d6b565b9060005260206000200154905092915050565b6000805b6001600160a01b038316600090815260116020526040902061551590615001565b8110156124fb576001600160a01b038316600090815260116020526040812061553e908361500b565b905061554b6025826146b0565b156156205761555942614658565b6001600160a01b0382166000908152602a6020526040902060010154146155df576155838161106e565b6001600160a01b0382166000908152602a60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b16179190911781559101516001909101555b6001600160a01b0380851660009081526027602090815260408083209385168352929052205461561390610d6f90836148f1565b61561d9084615bf5565b92505b508061562b81615cd3565b9150506154f4565b6060610c66848460008585843b61568c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611647565b600080866001600160a01b031685876040516156a89190615a6a565b60006040518083038185875af1925050503d80600081146156e5576040519150601f19603f3d011682016040523d82523d6000602084013e6156ea565b606091505b50915091506156fa828286615705565b979650505050505050565b606083156157145750816146a9565b8251156157245782518084602001fd5b8160405162461bcd60e51b81526004016116479190615b5c565b8051801515811461142f57600080fd5b8051600681900b811461142f57600080fd5b60006020828403121561577257600080fd5b81356146a981615d81565b60006020828403121561578f57600080fd5b81516146a981615d81565b600080604083850312156157ad57600080fd5b82356157b881615d81565b915060208301356157c881615d81565b809150509250929050565b6000806000606084860312156157e857600080fd5b83356157f381615d81565b9250602084013561580381615d81565b9150604084013561581381615d81565b809150509250925092565b60008060006060848603121561583357600080fd5b833561583e81615d81565b9250602084013561584e81615d81565b929592945050506040919091013590565b6000806000806080858703121561587557600080fd5b843561588081615d81565b9350602085013561589081615d81565b92506040850135915060608501356158a781615d81565b939692955090935050565b600080600080608085870312156158c857600080fd5b84356158d381615d81565b935060208501356158e381615d81565b93969395505050506040820135916060013590565b600080600080600060a0868803121561591057600080fd5b853561591b81615d81565b9450602086013561592b81615d81565b94979496505050506040830135926060810135926080909101359150565b6000806040838503121561595c57600080fd5b823561596781615d81565b946020939093013593505050565b60008060006060848603121561598a57600080fd5b833561599581615d81565b925060208401359150604084013561581381615d81565b6000602082840312156159be57600080fd5b6146a98261573e565b6000806000606084860312156159dc57600080fd5b6159e58461574e565b92506159f36020850161574e565b9150615a016040850161573e565b90509250925092565b600060208284031215615a1c57600080fd5b5035919050565b600060208284031215615a3557600080fd5b5051919050565b600080600060608486031215615a5157600080fd5b8351925060208401519150604084015190509250925092565b60008251615a7c818460208701615ca7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615ae957845163ffffffff1683529383019391830191600101615ac7565b5090979650505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015615b505783516001600160a01b031683529284019291840191600101615b2b565b50909695505050505050565b6020815260008251806020840152615b7b816040850160208701615ca7565b601f01601f19169190910160400192915050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b92835260069190910b6020830152604082015260600190565b9283526020830191909152604082015260600190565b60008219821115615c0857615c08615d29565b500190565b600082615c1c57615c1c615d3f565b500490565b6000816000190483118215151615615c3b57615c3b615d29565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615c6b57615c6b615d29565b81667fffffffffffff018313811615615c8657615c86615d29565b5090039392505050565b600082821015615ca257615ca2615d29565b500390565b60005b83811015615cc2578181015183820152602001615caa565b83811115614f895750506000910152565b6000600019821415615ce757615ce7615d29565b5060010190565b600082615cfd57615cfd615d3f565b500690565b60008160060b667fffffffffffff19811415615d2057615d20615d29565b60000392915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114615d9657600080fd5b5056fe46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfaee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a2646970667358221220deb9df8ff35657e1a12e81f8ef9afd471831f8295ea7f82180fa059863a3067564736f6c63430008070033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103d65760003560e01c8063951dc22c11610202578063c5198abc11610121578063c5198abc146109a5578063c7ae40d0146109b8578063cb4be2bb146109cb578063cb54694d146109de578063cd22af1b146109f1578063d55995fe14610a1c578063dd2080d614610a2f578063ddca3f4314610a42578063e326ac4314610a4b578063ebbb619414610a6b578063ec00cdfc14610a7e578063ec8ca64314610a91578063f0f346b914610aba578063f11a1d1a14610acd578063f136a09d14610ae0578063f25e311b14610b00578063f39c38a014610b13578063f75f9f7b14610b26578063f9d46cf214610b39578063fc253d2b14610b4c578063fe75bc4614610b5557600080fd5b8063951dc22c146107cb578063966abd00146107d357806398e90a0f146107e65780639d5c33d81461080f578063a214580914610822578063a39744b514610835578063a515366a14610860578063a5d059ca14610873578063a676f9ff14610886578063a7d2e784146108a6578063aac6aa9c146108af578063ab033ea9146108c2578063af320e81146108d5578063b0103b1a146108e8578063b23922331461090b578063b440027f1461091e578063b600702a14610949578063b7e773401461095c578063b87fcbff1461096f578063c20297f01461099257600080fd5b806359a2255e116102f957806359a2255e146106275780635aa6e6751461063a5780635ebe23f01461064d5780635feeb79414610656578063633fb68f1461066957806364bb43ee1461067257806368a9f19c14610685578063694798e61461069857806369fe0e2d146106c35780636ba42aaa146106d65780636cf262bc146106e95780636e2a9ca6146106fc57806372da828a1461070f57806374a8f10314610722578063768b5d90146107355780637c8fce231461073e578063878c723e146107465780638bb6dfa81461076f5780638cb22b76146107825780638fe204dd146107a557806390a4684e146107b857600080fd5b8063034d4c61146103db57806307b435c2146104015780630c620bce1461042c5780630d6a1f87146104415780631101eb411461045457806311466d721461046957806315006b821461047c578063165e62e7146104a7578063168f92e7146104e45780631b44555e1461050f5780631c5a9d9c1461052f5780631ef94b911461054257806321040b0114610562578063238efcbc1461058d578063274a8db41461059557806351cff8d9146105c857806352a4de29146105db57806355ea6c47146105ee578063575288bf14610601578063594a3a9314610614575b600080fd5b6103ee6103e9366004615760565b610b68565b6040519081526020015b60405180910390f35b6103ee61040f36600461579a565b601660209081526000928352604080842090915290825290205481565b610434610c6e565b6040516103f89190615b0f565b6103ee61044f366004615949565b610c7f565b61046761046236600461581e565b610d85565b005b610467610477366004615949565b610edf565b6103ee61048a36600461579a565b601460209081526000928352604080842090915290825290205481565b6104ba6104b5366004615760565b61106e565b604080518251600690810b825260208085015190910b9082015291810151908201526060016103f8565b6103ee6104f236600461579a565b600d60209081526000928352604080842090915290825290205481565b6103ee61051d366004615760565b60096020526000908152604090205481565b61046761053d366004615760565b611434565b601b54610555906001600160a01b031681565b6040516103f89190615a86565b6103ee61057036600461579a565b601760209081526000928352604080842090915290825290205481565b610467611598565b6105b86105a3366004615760565b60066020526000908152604090205460ff1681565b60405190151581526020016103f8565b6104676105d6366004615760565b611624565b6104676105e936600461581e565b6117bc565b6104676105fc366004615760565b6119ee565b61046761060f36600461581e565b611aa2565b61046761062236600461579a565b611d65565b610467610635366004615760565b611e0a565b600354610555906001600160a01b031681565b6103ee601e5481565b610467610664366004615760565b611ebc565b6103ee60205481565b610467610680366004615760565b61214b565b610467610693366004615760565b61222c565b6103ee6106a636600461579a565b602760209081526000928352604080842090915290825290205481565b6104676106d1366004615a0a565b61230b565b6105b86106e4366004615760565b61236b565b6103ee6106f7366004615760565b6123cb565b61046761070a36600461581e565b612501565b61046761071d366004615760565b612650565b610467610730366004615760565b6126ed565b6103ee60215481565b6104346127e8565b610555610754366004615760565b6001602052600090815260409020546001600160a01b031681565b6103ee61077d366004615760565b6127f4565b6105b8610790366004615760565b60186020526000908152604090205460ff1681565b6104676107b3366004615a0a565b612897565b6104676107c636600461579a565b6128f7565b6104346129e5565b6104676107e1366004615975565b6129f1565b6105556107f4366004615760565b6002602052600090815260409020546001600160a01b031681565b61046761081d366004615760565b612b07565b6104676108303660046157d3565b612be6565b6103ee61084336600461579a565b600c60209081526000928352604080842090915290825290205481565b61046761086e366004615949565b612db6565b610467610881366004615949565b613017565b6103ee610894366004615760565b60286020526000908152604090205481565b6103ee601f5481565b6104676108bd366004615760565b6130f1565b6104676108d0366004615760565b6131a5565b6104676108e336600461579a565b61321b565b6105b86108f6366004615760565b600b6020526000908152604090205460ff1681565b610467610919366004615a0a565b61369a565b6103ee61092c36600461579a565b602460209081526000928352604080842090915290825290205481565b610467610957366004615760565b6136fa565b61046761096a366004615a0a565b61391f565b6105b861097d366004615760565b60056020526000908152604090205460ff1681565b6104676109a03660046158b2565b61397f565b6104676109b3366004615760565b613a38565b601c54610555906001600160a01b031681565b6104676109d9366004615760565b613afe565b6104676109ec366004615a0a565b613b9b565b6103ee6109ff36600461579a565b601560209081526000928352604080842090915290825290205481565b610467610a2a36600461585f565b613c1f565b610467610a3d36600461581e565b613e56565b6103ee60235481565b6103ee610a59366004615760565b600a6020526000908152604090205481565b610467610a79366004615a0a565b613fd3565b610467610a8c366004615760565b614031565b610555610a9f366004615760565b602b602052600090815260409020546001600160a01b031681565b610467610ac8366004615760565b6140ce565b601d54610555906001600160a01b031681565b6103ee610aee366004615760565b60296020526000908152604090205481565b610467610b0e36600461581e565b614182565b600454610555906001600160a01b031681565b610467610b34366004615760565b6143c7565b6105b8610b473660046158f8565b61447f565b6103ee60225481565b610467610b63366004615949565b614568565b600080610b74836123cb565b6021549091504290610b8f90610b8a9083615c90565b614658565b6001600160a01b0385166000908152602860205260409020541115610c33576021546001600160a01b038516600090815260286020526040902054610bd49042615c90565b10610c10576021546001600160a01b038516600090815260286020526040902054610bff9190615bf5565b610c099082615c90565b9050610c49565b6001600160a01b038416600090815260286020526040902054610c099082615c90565b610c3c42614658565b610c469082615c90565b90505b610c538183614672565b610c5c856127f4565b610c669190615bf5565b949350505050565b6060610c7a602561469c565b905090565b6000610c8c6025846146b0565b15610d7f576000610c9c8461106e565b90508060400151600014610d7d576001600160a01b03841660009081526013602052604081205460ff16610cdd578160200151610cd890615d02565b610ce3565b81602001515b601d5460215460405163a0d2710760e01b8152929350610d74926001600160a01b039092169163a0d2710791610d1f9189918791600401615bc6565b60206040518083038186803b158015610d3757600080fd5b505afa158015610d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6f9190615a23565b6146d2565b92505050610d7f565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610dc157604051636efb4f4160e11b815260040160405180910390fd5b601f54610dce9042615bf5565b6001600160a01b03808616600081815260166020908152604080832094891680845294825280832095909555918152601782528381209281529190529081208054849290610e1d908490615bf5565b90915550610e2e90508484846146e3565b6001600160a01b038085166000908152602760209081526040808320938716835292905220548015801590610e6d5750602054610e6b82866148f1565b105b15610e8b57604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de85604051610ed091815260200190565b60405180910390a35050505050565b336000818152600b602052604090205460ff1615610f105760405163ad2fdf3b60e01b815260040160405180910390fd5b610f1b6019826146b0565b610f375760405162941a5760e11b815260040160405180910390fd5b610f4081614a0f565b15610f9b576001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615dba83398151915293610f929390929091615bdf565b60405180910390a25b6001600160a01b0381166000908152600e602052604090205482111561101a57610fc481614be5565b6001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615dba833981519152936110119390929091615bdf565b60405180910390a25b611025818484614c73565b601b546001600160a01b03808516918382169116600080516020615d9a83398151915285611051614d57565b6040805192835260208301919091520160405180910390a4505050565b604080516060810182526000808252602082018190529181019190915261109442614658565b6001600160a01b0383166000908152602a6020526040902060010154141561110a57506001600160a01b03166000908152602a602090815260409182902082516060810184528154600681810b810b810b8352600160381b909104810b810b900b92810192909252600101549181019190915290565b60008061111e60215442610b8a9190615c90565b6001600160a01b0385166000908152602a602052604090206001015490915081141561128257604080516001808252818301909252600091602080830190803683375050506001600160a01b0386166000908152602a602052604090205490915060060b61118b42614658565b6111959042615c90565b826000815181106111a8576111a8615d6b565b63ffffffff909216602092830291909101820152601d546001600160a01b038881166000908152601290935260409283902054925163dc686d9160e01b81529181169263dc686d91926112049291909116908690600401615a9a565b60606040518083038186803b15801561121c57600080fd5b505afa158015611230573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125491906159c7565b600692830b90920b80885291955061126e91839150615c40565b600690810b900b60208601525061140b9050565b6001600160a01b0384166000908152602a602052604090206001015481111561140b576040805160028082526060820183526000926020830190803683370190505090506112cf42614658565b6112d99042615c90565b816000815181106112ec576112ec615d6b565b602002602001019063ffffffff16908163ffffffff168152505060215461131242614658565b61131c9042615c90565b6113269190615bf5565b8160018151811061133957611339615d6b565b63ffffffff909216602092830291909101820152601d546001600160a01b0387811660009081526012909352604080842054905163dc686d9160e01b81529282169263dc686d91926113919216908690600401615a9a565b60606040518083038186803b1580156113a957600080fd5b505afa1580156113bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e191906159c7565b600692830b90920b80885291955091506113fc908290615c40565b600690810b900b602086015250505b81156114245761141a42614658565b604084015261142c565b600060408401525b50505b919050565b336000818152600b602052604090205460ff1615611465576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b03808216600090815260156020908152604080832093861683529290522054806114a957604051636258f48160e01b815260040160405180910390fd5b4281106114c957604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600a6020526040902054611502576001600160a01b0382166000908152600a602052604090204290555b61150d600783614d71565b506001600160a01b03828116600090815260146020908152604080832093871683529290529081208054919055611545838583614d86565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a758360405161158a91815260200190565b60405180910390a350505050565b6004546001600160a01b031633146115c357604051637ef5703160e11b815260040160405180910390fd5b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161161a91615a86565b60405180910390a1565b600260005414156116505760405162461bcd60e51b815260040161164790615b8f565b60405180910390fd5b600260009081553381526017602090815260408083206001600160a01b03851684529091529020546116955760405163184c088160e21b815260040160405180910390fd5b3360009081526016602090815260408083206001600160a01b038516845290915290205442116116d8576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600b602052604090205460ff1615611709576040516362e6201d60e01b815260040160405180910390fd5b3360008181526017602090815260408083206001600160a01b038681168086529184528285208054908690559585526016845282852082865290935290832092909255601b5416141561175f5761175f81614e3c565b6117736001600160a01b0383163383614e9d565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b600260005414156117df5760405162461bcd60e51b815260040161164790615b8f565b60026000556117ef6025836146b0565b61180c5760405163e0b6aead60e01b815260040160405180910390fd5b6118176019846146b0565b61183457604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526011602052604090206118569083614d71565b5061186083614ef3565b602080546001600160a01b0380861660009081526027845260408082209287168252919093529091205461189f90611899908490615bf5565b846148f1565b10156118be57604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615dba8339815191529361190b9390929091615bdf565b60405180910390a26119286001600160a01b038316333084614f51565b6001600160a01b0380841660009081526027602090815260408083209386168352929052908120805483929061195f908490615bf5565b909155506119729050610d6f82846148f1565b6001600160a01b0384166000908152600f60205260408120805490919061199a908490615bf5565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff16611a1e57604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff16611a57576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600b6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b60026000541415611ac55760405162461bcd60e51b815260040161164790615b8f565b6002600055611ad56019846146b0565b611af257604051636211d34960e01b815260040160405180910390fd5b601b546001600160a01b0383811691161415611b205760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038416906370a0823190611b4f903090600401615a86565b60206040518083038186803b158015611b6757600080fd5b505afa158015611b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9f9190615a23565b9050611bb66001600160a01b038416333085614f51565b600081846001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611be59190615a86565b60206040518083038186803b158015611bfd57600080fd5b505afa158015611c11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c359190615a23565b611c3f9190615c90565b9050600061271060235483611c549190615c21565b611c5e9190615c0d565b9050611c6a8183615c90565b6001600160a01b038088166000908152600d60209081526040808320938a1683529290529081208054909190611ca1908490615bf5565b90915550506001600160a01b0380871660009081526024602090815260408083208985168085529252909120429055600354611cde921683614e9d565b6001600160a01b0386166000908152601060205260409020611d009086614d71565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611d5091815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611da157604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611e465760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b602d54611edc57604051630262ab9b60e61b815260040160405180910390fd5b336000818152600b602052604090205460ff1615611f0d5760405163ad2fdf3b60e01b815260040160405180910390fd5b611f186019826146b0565b611f345760405162941a5760e11b815260040160405180910390fd5b611f3d81614a0f565b15611f98576001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615dba83398151915293611f8f9390929091615bdf565b60405180910390a25b601d546001600160a01b038381166000908152600c60209081526040808320601b548516845290915280822054905163435b21c160e01b8152600481019190915290928392839291169063435b21c19060240160606040518083038186803b15801561200357600080fd5b505afa158015612017573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203b9190615a3c565b925092509250600061204b614d57565b9050600061205b82848688614f8f565b6001600160a01b0387166000908152600e60205260409020549091508111156120f55761208786614be5565b6001600160a01b038616600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615dba833981519152936120d49390929091615bdf565b60405180910390a26120e4614d57565b91506120f282848688614f8f565b90505b612100868883614c73565b6000602d55601b5460408051838152602081018590526001600160a01b038a8116938a821693911691600080516020615d9a833981519152910160405180910390a450505050505050565b6003546001600160a01b03163314612176576040516354348f0360e01b815260040160405180910390fd5b612181602582614fec565b61219e57604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600090815260126020908152604080832080546001600160a01b031916905560138252808320805460ff19169055602a90915280822080546001600160701b031916815560010191909155517f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e5690612221908390615a86565b60405180910390a150565b6003546001600160a01b03163314612257576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661227e5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16156122b85760405163546da66560e11b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b90612221908390615a86565b6003546001600160a01b03163314612336576040516354348f0360e01b815260040160405180910390fd5b60238190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d90602001612221565b6000612375614d57565b602d556123836007836146b0565b1561142f577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602d546040516123bb91815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b03831660009081526011602052604090206123f090615001565b8110156124fb576001600160a01b0383166000908152601160205260408120612419908361500b565b90506124266025826146b0565b156124e85760006124368261106e565b905080604001516000146124e6576001600160a01b03821660009081526013602052604081205460ff1661247757816020015161247290615d02565b61247d565b81602001515b601d546001600160a01b03888116600090815260276020908152604080832089851684529091529081902054602154915163a0d2710760e01b81529495506124d894929093169263a0d2710792610d1f928791600401615bc6565b6124e29086615bf5565b9450505b505b50806124f381615cd3565b9150506123cf565b50919050565b3360009081526005602052604090205460ff1661253157604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff1661256a576040516310cec38560e21b815260040160405180910390fd5b6125758383836146e3565b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb926125a992909116908590600401615af6565b602060405180830381600087803b1580156125c357600080fd5b505af19250505080156125f3575060408051601f3d908101601f191682019092526125f0918101906159ac565b60015b6125fc576125fe565b505b336001600160a01b0316836001600160a01b03167f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e8484604051612643929190615af6565b60405180910390a3505050565b6003546001600160a01b0316331461267b576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166126a25760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383161790556040517f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b090612221908390615a86565b3360009081526005602052604090205460ff1661271d57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff16612756576040516310cec38560e21b815260040160405180910390fd5b612761600782614fec565b50601b546001600160a01b038083166000818152600c60209081526040808320949095168083529381528482205492825260178152848220848352905292909220546127af92849291615017565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610c7a601961469c565b600080612800836123cb565b6021546001600160a01b0385166000908152602860205260409020549192509061282a9042615c90565b1015610d7f5760008111612856576001600160a01b0383166000908152600e6020526040902054612890565b6001600160a01b0383166000908152600f6020908152604080832054600e90925290912054612886908390615c21565b6128909190615c0d565b91506124fb565b6003546001600160a01b031633146128c2576040516354348f0360e01b815260040160405180910390fd5b601f8190556040518181527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee290602001612221565b6001600160a01b03828116600090815260016020526040902054839116331461293357604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156129665760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602b6020908152604080832080546001600160a01b0319169588169586179055602c825280832094835293905282902042905590517fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c906129d8908590615a86565b60405180910390a2505050565b6060610c7a600761469c565b6003546001600160a01b03163314612a1c576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116612a435760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415612aa4576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015612a9e573d6000803e3d6000fd5b50612ab8565b612ab86001600160a01b0384168284614e9d565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b03163314612b32576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116612b595760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1615612b935760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19166001179055517f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f90612221908390615a86565b6001600160a01b038381166000908152600160205260409020548491163314612c2257604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b038216612c495760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03808516600090815260176020908152604080832093871683529290522054612c8c5760405163184c088160e21b815260040160405180910390fd5b6001600160a01b038085166000908152601660209081526040808320938716835292905220544211612cd1576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600b602052604090205460ff1615612d0b576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b0380851660008181526017602090815260408083209488168084529482528083208054908490559383526016825280832085845290915281205590612d58908483614e9d565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca792886284604051612da791815260200190565b60405180910390a45050505050565b60026000541415612dd95760405162461bcd60e51b815260040161164790615b8f565b60026000908155338152600b602052604090205460ff1615612e0e576040516362e6201d60e01b815260040160405180910390fd5b612e196019336146b0565b15612e375760405163d7229c4360e01b815260040160405180910390fd5b601e54612e449042615bf5565b3360009081526015602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81529091906370a0823190612e8f903090600401615a86565b60206040518083038186803b158015612ea757600080fd5b505afa158015612ebb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612edf9190615a23565b9050612ef66001600160a01b038416333085614f51565b6040516370a0823160e01b815281906001600160a01b038516906370a0823190612f24903090600401615a86565b60206040518083038186803b158015612f3c57600080fd5b505afa158015612f50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f749190615a23565b612f7e9190615c90565b336000908152601860209081526040808320805460ff19166001179055601482528083206001600160a01b0388168452909152812080549294508492909190612fc8908490615bf5565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b601f546130249042615bf5565b3360008181526016602090815260408083206001600160a01b03881680855290835281842095909555928252600c81528282209382529290925281208054839290613070908490615c90565b90915550503360009081526017602090815260408083206001600160a01b0386168452909152812080548392906130a8908490615bf5565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b0316331461311c576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16613155576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19169055517f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d02590612221908390615a86565b6003546001600160a01b031633146131d0576040516354348f0360e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90612221908390615a86565b6001600160a01b03818116600090815260016020526040902054829116331461325757604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff168061329657506001600160a01b0382166000908152600b602052604090205460ff165b156132b45760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602b60205260409020548116908316146132f157604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602c602090815260408083209386168352929052205461332390603c90615bf5565b421015613343576040516356248e9760e01b815260040160405180910390fd5b61334c83614ef3565b61335582614ef3565b6001600160a01b038316600090815260106020526040812061337690615001565b1115613458576001600160a01b038316600090815260106020526040812061339e908261500b565b6001600160a01b038086166000908152600d6020818152604080842085871680865290835281852054958a1685529282528084209284529190528120805493945091926133ec908490615bf5565b90915550506001600160a01b038085166000818152600d60209081526040808320948616835293815283822082905591815260109091522061342e9082614fec565b506001600160a01b03831660009081526010602052604090206134519082614d71565b5050613355565b6001600160a01b038316600090815260116020526040812061347990615001565b111561355b576001600160a01b03831660009081526011602052604081206134a1908261500b565b6001600160a01b03808616600090815260276020818152604080842085871680865290835281852054958a1685529282528084209284529190528120805493945091926134ef908490615bf5565b90915550506001600160a01b03808516600090815260276020908152604080832085851684528252808320839055928616825260119052206135319082614d71565b506001600160a01b03841660009081526011602052604090206135549082614fec565b5050613458565b6001600160a01b038084166000908152600f60205260408082205492851682528120805490919061358d908490615bf5565b90915550506001600160a01b038084166000908152600f60209081526040808320839055600e909152808220549285168252812080549091906135d1908490615bf5565b90915550506001600160a01b0383166000908152600e602090815260408083208390556028909152812055613607601984614fec565b506001600160a01b03808416600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602c8352818420958816808552958352818420849055938352602b909152908190208054909216909155517f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f2906129d8908690615a86565b6003546001600160a01b031633146136c5576040516354348f0360e01b815260040160405180910390fd5b60228190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb6990602001612221565b6003546001600160a01b03163314613725576040516354348f0360e01b815260040160405180910390fd5b613730602582614d71565b61374d5760405163f25e6b9f60e01b815260040160405180910390fd5b806001600160a01b03166316f0115b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561378657600080fd5b505afa15801561379a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137be919061577d565b6001600160a01b038281166000908152601260205260409081902080546001600160a01b0319169383169384179055601d54905163696a437b60e01b815291169163696a437b916138129190600401615a86565b60206040518083038186803b15801561382a57600080fd5b505afa15801561383e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061386291906159ac565b6001600160a01b0382166000908152601360205260409020805460ff19169115159190911790556138928161106e565b6001600160a01b0382166000908152602a60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b161791909117815591810151600190920191909155517fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b90612221908390615a86565b6003546001600160a01b0316331461394a576040516354348f0360e01b815260040160405180910390fd5b601e8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b4390602001612221565b3360009081526005602052604090205460ff166139af57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600b602052604090205460ff166139e8576040516310cec38560e21b815260040160405180910390fd5b6139f484848484615017565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613a2a8486615bf5565b60405190815260200161158a565b613a436019826146b0565b15613a6157604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526018602052604090205460ff1615613a9b57604051632f3d320560e01b815260040160405180910390fd5b613aa6601982614d71565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613b29576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116613b505760405163d92e233d60e01b815260040160405180910390fd5b601c80546001600160a01b0319166001600160a01b0383161790556040517feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae25090612221908390615a86565b6003546001600160a01b03163314613bc6576040516354348f0360e01b815260040160405180910390fd5b62015180811015613bea57604051633f384aad60e21b815260040160405180910390fd5b60218190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d990602001612221565b60026000541415613c425760405162461bcd60e51b815260040161164790615b8f565b600260009081556001600160a01b03858116825260016020526040909120548591163314613c8357604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260246020908152604080832093881683529290522054613cb590603c90615bf5565b4211613cd457604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600d6020908152604080832093881683529290522054831115613d1a5760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600b602052604090205460ff1615613d545760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600d6020908152604080832093881683529290529081208054859290613d8b908490615c90565b90915550613da590506001600160a01b0385168385614e9d565b6001600160a01b038086166000908152600d6020908152604080832093881683529290522054613df3576001600160a01b0385166000908152601060205260409020613df19085614fec565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613e4291815260200190565b60405180910390a450506001600055505050565b336000818152600b602052604090205460ff1615613e875760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff1615613ec1576040516362e6201d60e01b815260040160405180910390fd5b613ecc6019826146b0565b613ee85760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600d6020908152604080832093881683529290522054821115613f2e5760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600d6020908152604080832093881683529290529081208054849290613f65908490615c90565b90915550613f7f90506001600160a01b0385168484614e9d565b826001600160a01b0316816001600160a01b0316856001600160a01b0316600080516020615d9a83398151915285613fb5614d57565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b03163314613ffe576040516354348f0360e01b815260040160405180910390fd5b60208181556040518281527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e79101612221565b6003546001600160a01b0316331461405c576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166140835760405163d92e233d60e01b815260040160405180910390fd5b601b80546001600160a01b0319166001600160a01b0383161790556040517f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf90612221908390615a86565b6003546001600160a01b031633146140f9576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1661413257604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19169055517f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e90612221908390615a86565b3360009081526005602052604090205460ff166141b257604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff166141eb576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b038316600090815260106020526040902061420d90836146b0565b61422a57604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600d602090815260408083209386168352929052205481111561426f5760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb926142a392909116908590600401615af6565b602060405180830381600087803b1580156142bd57600080fd5b505af19250505080156142ed575060408051601f3d908101601f191682019092526142ea918101906159ac565b60015b6142f6576142f8565b505b6001600160a01b038084166000908152600d602090815260408083209386168352929052908120805483929061432f908490615c90565b90915550506001600160a01b038084166000908152600d6020908152604080832093861683529290522054614382576001600160a01b03831660009081526010602052604090206143809083614fec565b505b336001600160a01b0316836001600160a01b03167f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d3183331048484604051612643929190615af6565b3360009081526006602052604090205460ff166143f757604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff1615614431576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600b6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b6000614489614d57565b602d556144976007876146b0565b80156144c857506001600160a01b038087166000908152600c60209081526040808320938916835292905220548411155b80156144ec57506001600160a01b0386166000908152600960205260409020548311155b801561451b57506001600160a01b0386166000908152600a602052604090205482906145189042615c90565b10155b1561455f577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602d5460405161455391815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b03163314614593576040516354348f0360e01b815260040160405180910390fd5b61459e6019836146b0565b6145bb57604051636211d34960e01b815260040160405180910390fd5b6145c482614ef3565b6001600160a01b0382166000908152600e6020526040812080548392906145ec908490615bf5565b90915550506001600160a01b038216600081815260286020908152604080832054600e909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d19261464c928252602082015260400190565b60405180910390a25050565b6000602154826146689190615cee565b610d7f9083615c90565b60006021548310156124fb5760215461468b8385615c21565b6146959190615c0d565b9050610d7f565b606060006146a98361516d565b9392505050565b6001600160a01b038116600090815260018301602052604081205415156146a9565b6000610d7f826021546022546151c9565b600260005414156147065760405162461bcd60e51b815260040161164790615b8f565b600260009081556001600160a01b038416815260116020526040902061472c90836146b0565b614748576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b0380841660009081526027602090815260408083209386168352929052205481111561478e5760405163435b562560e01b815260040160405180910390fd5b61479783615277565b60006147a6610d6f83856148f1565b6001600160a01b0385166000908152600f60205260409020549091501561485c576001600160a01b0384166000908152600f6020908152604080832054600e909252909120546147f7908390615c21565b6148019190615c0d565b6001600160a01b0385166000908152600e602052604081208054909190614829908490615c90565b90915550506001600160a01b0384166000908152600f602052604081208054839290614856908490615c90565b90915550505b6001600160a01b03808516600090815260276020908152604080832093871683529290529081208054849290614893908490615c90565b90915550506001600160a01b038085166000908152602760209081526040808320938716835292905220546148e6576001600160a01b03841660009081526011602052604090206148e49084614fec565b505b505060016000555050565b6001600160a01b0381166000908152602a602052604081206001015415610d7f576001600160a01b03821660009081526013602052604081205460ff16614963576001600160a01b0383166000908152602a602052604090205461495e90600160381b900460060b615d02565b614987565b6001600160a01b0383166000908152602a6020526040902054600160381b900460060b5b601d5460215460405163a0d2710760e01b81529293506001600160a01b039091169163a0d27107916149bf9188918691600401615bc6565b60206040518083038186803b1580156149d757600080fd5b505afa1580156149eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c669190615a23565b6000614a1a42614658565b6001600160a01b038316600090815260286020526040902054101561142f57614a4a60215442610b8a9190615c90565b6001600160a01b03831660009081526028602052604090205411614ac057614a7182615277565b6001600160a01b0382166000908152600f6020908152604080832054600e90925290912055614a9f42614658565b6001600160a01b038316600090815260286020526040902055506001919050565b6021546001600160a01b038316600090815260286020526040902054614ae69042615c90565b10614b4257614af482615277565b6001600160a01b0382166000908152600f6020908152604080832054600e83528184205560215460289092528220805491929091614b33908490615bf5565b909155506001915061142f9050565b614b4b42614658565b6001600160a01b038316600090815260296020526040902054101561142f576001600160a01b0382166000908152600f6020526040902054614b8c83615277565b6001600160a01b0383166000908152600f6020908152604080832054600e909252909120548291614bbc91615c21565b614bc69190615c0d565b6001600160a01b0384166000908152600e602052604090205550919050565b6001600160a01b038116600090815260286020526040902054614c2a90614c0c9042615c90565b6001600160a01b0383166000908152600f6020526040902054614672565b6001600160a01b0382166000908152600e602052604081208054909190614c52908490615bf5565b90915550506001600160a01b03166000908152602860205260409020429055565b6001600160a01b0383166000908152600e6020526040902054811115614cac5760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602960209081526040808320429055600e90915281208054839290614ce1908490615c90565b90915550506001600160a01b038083166000908152600c60209081526040808320601b5490941683529290529081208054839290614d20908490615bf5565b90915550506001600160a01b03821660009081526009602052604081208054839290614d4d908490615bf5565b9091555050505050565b6000603f5a614d67906040615c21565b610c7a9190615c0d565b60006146a9836001600160a01b03841661529c565b6001600160a01b038084166000908152600c6020908152604080832093861683529290529081208054839290614dbd908490615bf5565b9091555050601b546001600160a01b0383811691161415614e3757601b54604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c6890602401600060405180830381600087803b158015614e1e57600080fd5b505af1158015614e32573d6000803e3d6000fd5b505050505b505050565b601c5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401600060405180830381600087803b158015614e8257600080fd5b505af1158015614e96573d6000803e3d6000fd5b5050505050565b614e378363a9059cbb60e01b8484604051602401614ebc929190615af6565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526152eb565b614efc81614a0f565b50614f0681614be5565b6001600160a01b0381166000908152600e6020908152604080832054600f90925290912054614f3591906153bd565b6001600160a01b039091166000908152600e6020526040902055565b6040516001600160a01b0380851660248301528316604482015260648101829052614f899085906323b872dd60e01b90608401614ebc565b50505050565b6000808486602d54614fa19190615c90565b614fab9190615bf5565b9050670de0b6b3a764000084612710614fc48685615c21565b614fce9190615c0d565b614fd89190615c21565b614fe29190615c0d565b9695505050505050565b60006146a9836001600160a01b0384166153d3565b6000610d7f825490565b60006146a983836154c6565b601b546001600160a01b038481169116146150ef576003546001600160a01b038085169163a9059cbb911661504c8486615bf5565b6040518363ffffffff1660e01b8152600401615069929190615af6565b602060405180830381600087803b15801561508357600080fd5b505af19250505080156150b3575060408051601f3d908101601f191682019092526150b0918101906159ac565b60015b6150ed573d8080156150e1576040519150601f19603f3d011682016040523d82523d6000602084013e6150e6565b606091505b50506150ef565b505b6001600160a01b038085166000908152600c6020908152604080832093871683529290529081208054849290615126908490615c90565b90915550506001600160a01b03808516600090815260176020908152604080832093871683529290529081208054839290615162908490615c90565b909155505050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156151bd57602002820191906000526020600020905b8154815260200190600101908083116151a9575b50505050509050919050565b60008080600019858709858702925082811083820303915050806000141561520357600084116151f857600080fd5b5082900490506146a9565b80841161520f57600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b615280816154f0565b6001600160a01b039091166000908152600f6020526040902055565b60008181526001830160205260408120546152e357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d7f565b506000610d7f565b6000615340826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166156339092919063ffffffff16565b805190915015614e37578080602001905181019061535e91906159ac565b614e375760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611647565b60008183106153cc57816146a9565b5090919050565b600081815260018301602052604081205480156154bc5760006153f7600183615c90565b855490915060009061540b90600190615c90565b905081811461547057600086600001828154811061542b5761542b615d6b565b906000526020600020015490508087600001848154811061544e5761544e615d6b565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061548157615481615d55565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d7f565b6000915050610d7f565b60008260000182815481106154dd576154dd615d6b565b9060005260206000200154905092915050565b6000805b6001600160a01b038316600090815260116020526040902061551590615001565b8110156124fb576001600160a01b038316600090815260116020526040812061553e908361500b565b905061554b6025826146b0565b156156205761555942614658565b6001600160a01b0382166000908152602a6020526040902060010154146155df576155838161106e565b6001600160a01b0382166000908152602a60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b16179190911781559101516001909101555b6001600160a01b0380851660009081526027602090815260408083209385168352929052205461561390610d6f90836148f1565b61561d9084615bf5565b92505b508061562b81615cd3565b9150506154f4565b6060610c66848460008585843b61568c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611647565b600080866001600160a01b031685876040516156a89190615a6a565b60006040518083038185875af1925050503d80600081146156e5576040519150601f19603f3d011682016040523d82523d6000602084013e6156ea565b606091505b50915091506156fa828286615705565b979650505050505050565b606083156157145750816146a9565b8251156157245782518084602001fd5b8160405162461bcd60e51b81526004016116479190615b5c565b8051801515811461142f57600080fd5b8051600681900b811461142f57600080fd5b60006020828403121561577257600080fd5b81356146a981615d81565b60006020828403121561578f57600080fd5b81516146a981615d81565b600080604083850312156157ad57600080fd5b82356157b881615d81565b915060208301356157c881615d81565b809150509250929050565b6000806000606084860312156157e857600080fd5b83356157f381615d81565b9250602084013561580381615d81565b9150604084013561581381615d81565b809150509250925092565b60008060006060848603121561583357600080fd5b833561583e81615d81565b9250602084013561584e81615d81565b929592945050506040919091013590565b6000806000806080858703121561587557600080fd5b843561588081615d81565b9350602085013561589081615d81565b92506040850135915060608501356158a781615d81565b939692955090935050565b600080600080608085870312156158c857600080fd5b84356158d381615d81565b935060208501356158e381615d81565b93969395505050506040820135916060013590565b600080600080600060a0868803121561591057600080fd5b853561591b81615d81565b9450602086013561592b81615d81565b94979496505050506040830135926060810135926080909101359150565b6000806040838503121561595c57600080fd5b823561596781615d81565b946020939093013593505050565b60008060006060848603121561598a57600080fd5b833561599581615d81565b925060208401359150604084013561581381615d81565b6000602082840312156159be57600080fd5b6146a98261573e565b6000806000606084860312156159dc57600080fd5b6159e58461574e565b92506159f36020850161574e565b9150615a016040850161573e565b90509250925092565b600060208284031215615a1c57600080fd5b5035919050565b600060208284031215615a3557600080fd5b5051919050565b600080600060608486031215615a5157600080fd5b8351925060208401519150604084015190509250925092565b60008251615a7c818460208701615ca7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615ae957845163ffffffff1683529383019391830191600101615ac7565b5090979650505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015615b505783516001600160a01b031683529284019291840191600101615b2b565b50909695505050505050565b6020815260008251806020840152615b7b816040850160208701615ca7565b601f01601f19169190910160400192915050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b92835260069190910b6020830152604082015260600190565b9283526020830191909152604082015260600190565b60008219821115615c0857615c08615d29565b500190565b600082615c1c57615c1c615d3f565b500490565b6000816000190483118215151615615c3b57615c3b615d29565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615c6b57615c6b615d29565b81667fffffffffffff018313811615615c8657615c86615d29565b5090039392505050565b600082821015615ca257615ca2615d29565b500390565b60005b83811015615cc2578181015183820152602001615caa565b83811115614f895750506000910152565b6000600019821415615ce757615ce7615d29565b5060010190565b600082615cfd57615cfd615d3f565b500690565b60008160060b667fffffffffffff19811415615d2057615d20615d29565b60000392915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114615d9657600080fd5b5056fe46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfaee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a2646970667358221220deb9df8ff35657e1a12e81f8ef9afd471831f8295ea7f82180fa059863a3067564736f6c63430008070033", + "numDeployments": 5, + "solcInputHash": "0d224f905ebe4be6830f2d07ee9fcf58", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyAJob\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyAKeeper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Disputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasNotInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientJobTokenCredits\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityLessThanMin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationImpossible\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenCreditsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MinRewardPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDisputer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySlasher\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenUnallowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Activation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"BondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Bonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"Dispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"DustSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"FeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"InflationPeriodChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOwner\",\"type\":\"address\"}],\"name\":\"JobAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationSuccessful\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipAssent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_pendingOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashLiquidity\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"Keep3rHelperChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"Keep3rV1Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"Keep3rV1ProxyChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"KeeperRevoke\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"KeeperSlash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperValidation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_credit\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperWork\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityApproval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsForced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsReward\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"LiquidityMinimumChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityRevocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_resolver\",\"type\":\"address\"}],\"name\":\"Resolve\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"RewardPeriodTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"UnbondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeperOrJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_unbonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Unbonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"acceptJobMigration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"acceptJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"activate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"addDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"addJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addLiquidityToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"addSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addTokenCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"approveLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"approvedLiquidities\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"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\":[],\"name\":\"bondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"}],\"name\":\"bondedPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canActivateAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canWithdrawAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"changeJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"directTokenPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"dispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"firstSeen\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"forceLiquidityCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"hasBonded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"inflationPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minBond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_earned\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_age\",\"type\":\"uint256\"}],\"name\":\"isBondedKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isBondedKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"isKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobLiquidityCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobPendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobPeriodCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCreditsAddedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"jobs\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rHelper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1Proxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keepers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"liquidityAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidityMinimum\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"migrateJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"observeLiquidity\",\"outputs\":[{\"components\":[{\"internalType\":\"int56\",\"name\":\"current\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"difference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"}],\"internalType\":\"struct IKeep3rJobFundableLiquidity.TickCache\",\"name\":\"_tickCache\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingJobMigrations\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingUnbonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"quoteLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"removeDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"removeSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"resolve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"revoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"revokeLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardPeriodTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"rewardedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sendDust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"setBondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"setInflationPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"setKeep3rHelper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"setKeep3rV1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"setKeep3rV1Proxy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"setLiquidityMinimum\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"setRewardPeriodTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"setUnbondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bonded\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_bondAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_unbondAmount\",\"type\":\"uint256\"}],\"name\":\"slash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashTokenFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"slashers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"totalJobCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_credits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbondLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unbondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawTokenCreditsFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workCompleted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"worked\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptJobMigration(address,address)\":{\"details\":\"Unbond/withdraw process doesn't get migrated\",\"params\":{\"_fromJob\":\"The address of the job that requested to migrate\",\"_toJob\":\"The address to which the job wants to migrate to\"}},\"acceptJobOwnership(address)\":{\"params\":{\"_job\":\"The address of the job\"}},\"activate(address)\":{\"params\":{\"_bonding\":\"The asset being activated as bond collateral\"}},\"addJob(address)\":{\"params\":{\"_job\":\"Address of the contract for which work should be performed\"}},\"addLiquidityToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity tokens to add\",\"_job\":\"The address of the job to assign liquidity to\",\"_liquidity\":\"The liquidity being added\"}},\"addTokenCreditsToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of credit being added\",\"_job\":\"The address of the job being credited\",\"_token\":\"The address of the token being credited\"}},\"approveLiquidity(address)\":{\"params\":{\"_liquidity\":\"The address of the liquidity accepted\"}},\"approvedLiquidities()\":{\"returns\":{\"_list\":\"An array of addresses with all the approved liquidity pairs\"}},\"bond(address,uint256)\":{\"params\":{\"_amount\":\"The amount of bonding asset being bonded\",\"_bonding\":\"The asset being bonded\"}},\"bondedPayment(address,uint256)\":{\"details\":\"Pays the keeper that performs the work with KP3R\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\",\"_payment\":\"The reward that should be allocated for the job\"}},\"changeJobOwnership(address,address)\":{\"params\":{\"_job\":\"The address of the job\",\"_newOwner\":\"The address of the proposed new owner\"}},\"directTokenPayment(address,address,uint256)\":{\"details\":\"Pays the keeper that performs the work with a specific token\",\"params\":{\"_amount\":\"The reward that should be allocated\",\"_keeper\":\"Address of the keeper that performed the work\",\"_token\":\"The asset being awarded to the keeper\"}},\"dispute(address)\":{\"params\":{\"_jobOrKeeper\":\"The address in dispute\"}},\"forceLiquidityCreditsToJob(address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity credits to gift\",\"_job\":\"The address of the job being credited\"}},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"details\":\"Should be used for protected functions\",\"params\":{\"_age\":\"The minimum keeper age required\",\"_bond\":\"The bond token being evaluated\",\"_earned\":\"The minimum funds earned in the keepers lifetime\",\"_keeper\":\"The keeper to check\",\"_minBond\":\"The minimum amount of bonded tokens\"},\"returns\":{\"_isBondedKeeper\":\"Whether the `_keeper` meets the given requirements\"}},\"isKeeper(address)\":{\"details\":\"Can be used for general (non critical) functions\",\"params\":{\"_keeper\":\"The keeper being investigated\"},\"returns\":{\"_isKeeper\":\"Whether the address passed as a parameter is a keeper or not\"}},\"jobLiquidityCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the liquidity credits\"},\"returns\":{\"_liquidityCredits\":\"The liquidity credits of a given job\"}},\"jobPeriodCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the period credits\"},\"returns\":{\"_periodCredits\":\"The credits the given job has at the current period\"}},\"jobs()\":{\"returns\":{\"_list\":\"Array with all the jobs in _jobs\"}},\"keepers()\":{\"returns\":{\"_list\":\"Array with all the keepers in _keepers\"}},\"migrateJob(address,address)\":{\"params\":{\"_fromJob\":\"The address of the job that is requesting to migrate\",\"_toJob\":\"The address at which the job is requesting to migrate\"}},\"observeLiquidity(address)\":{\"params\":{\"_liquidity\":\"The address of the liquidity pair being observed\"},\"returns\":{\"_tickCache\":\"The updated TickCache\"}},\"quoteLiquidity(address,uint256)\":{\"details\":\"_periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\",\"params\":{\"_amount\":\"The amount of liquidity to provide\",\"_liquidity\":\"The address of the liquidity to provide\"},\"returns\":{\"_periodCredits\":\"The amount of KP3R periodically minted for the given liquidity\"}},\"resolve(address)\":{\"params\":{\"_jobOrKeeper\":\"The address cleared\"}},\"revoke(address)\":{\"params\":{\"_keeper\":\"The address being slashed\"}},\"revokeLiquidity(address)\":{\"params\":{\"_liquidity\":\"The liquidity no longer accepted\"}},\"sendDust(address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of the token that will be transferred\",\"_to\":\"The address that will receive the idle funds\",\"_token\":\"The token that will be transferred\"}},\"setBondTime(uint256)\":{\"params\":{\"_bond\":\"The new bond time\"}},\"setFee(uint256)\":{\"params\":{\"_fee\":\"The new fee\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setInflationPeriod(uint256)\":{\"params\":{\"_inflationPeriod\":\"The new inflation period\"}},\"setKeep3rHelper(address)\":{\"params\":{\"_keep3rHelper\":\"The Keep3rHelper address\"}},\"setKeep3rV1(address)\":{\"params\":{\"_keep3rV1\":\"The Keep3rV1 address\"}},\"setKeep3rV1Proxy(address)\":{\"params\":{\"_keep3rV1Proxy\":\"The Keep3rV1Proxy address\"}},\"setLiquidityMinimum(uint256)\":{\"params\":{\"_liquidityMinimum\":\"The new minimum amount of liquidity\"}},\"setRewardPeriodTime(uint256)\":{\"params\":{\"_rewardPeriodTime\":\"The new amount of time required to pass between rewards\"}},\"setUnbondTime(uint256)\":{\"params\":{\"_unbond\":\"The new unbond time\"}},\"slash(address,address,uint256,uint256)\":{\"params\":{\"_bondAmount\":\"The bonded amount being slashed\",\"_bonded\":\"The asset being slashed\",\"_keeper\":\"The address being slashed\",\"_unbondAmount\":\"The pending unbond amount being slashed\"}},\"slashLiquidityFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity that will be slashed\",\"_job\":\"The address being slashed\",\"_liquidity\":\"The address of the liquidity that will be slashed\"}},\"slashTokenFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of the token that will be slashed\",\"_job\":\"The address of the job from which the token will be slashed\",\"_token\":\"The address of the token that will be slashed\"}},\"totalJobCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the total credits\"},\"returns\":{\"_credits\":\"The total credits of the given job\"}},\"unbond(address,uint256)\":{\"params\":{\"_amount\":\"Allows for partial unbonding\",\"_bonding\":\"The asset being unbonded\"}},\"unbondLiquidityFromJob(address,address,uint256)\":{\"details\":\"Can only be called by the job's owner\",\"params\":{\"_amount\":\"The amount of liquidity being removed\",\"_job\":\"The address of the job being unbonded from\",\"_liquidity\":\"The liquidity being unbonded\"}},\"withdraw(address)\":{\"params\":{\"_bonding\":\"The asset to withdraw from the bonding pool\"}},\"withdrawLiquidityFromJob(address,address,address)\":{\"params\":{\"_job\":\"The address of the job being withdrawn from\",\"_liquidity\":\"The liquidity being withdrawn\",\"_receiver\":\"The address that will receive the withdrawn liquidity\"}},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of token to be withdrawn\",\"_job\":\"The address of the job from which the credits are withdrawn\",\"_receiver\":\"The user that will receive tokens\",\"_token\":\"The address of the token being withdrawn\"}},\"worked(address)\":{\"details\":\"Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"AlreadyAJob()\":[{\"notice\":\"Throws when the address that is trying to register as a job is already a job\"}],\"AlreadyAKeeper()\":[{\"notice\":\"Throws when the address that is trying to register as a keeper is already a keeper\"}],\"AlreadyDisputed()\":[{\"notice\":\"Throws when a job or keeper is already disputed\"}],\"BondsLocked()\":[{\"notice\":\"Throws if the time required to bond an asset has not passed yet\"}],\"BondsUnexistent()\":[{\"notice\":\"Throws if there are no bonded assets\"}],\"Disputed()\":[{\"notice\":\"Throws if either a job or a keeper is disputed\"}],\"DisputerExistent()\":[{\"notice\":\"Throws if the address is already a registered disputer\"}],\"DisputerUnexistent()\":[{\"notice\":\"Throws if caller is not a registered disputer\"}],\"GasNotInitialized()\":[{\"notice\":\"Throws if work method was called without calling isKeeper or isBondedKeeper\"}],\"InsufficientFunds()\":[{\"notice\":\"Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\"}],\"InsufficientJobTokenCredits()\":[{\"notice\":\"Throws when the user tries to withdraw more tokens than it has\"}],\"JobAlreadyAdded()\":[{\"notice\":\"Throws when trying to add a job that has already been added\"}],\"JobDisputed()\":[{\"notice\":\"Throws when an action that requires an undisputed job is applied on a disputed job\"}],\"JobLiquidityInsufficient()\":[{\"notice\":\"Throws when trying to remove more liquidity than the job has\"}],\"JobLiquidityLessThanMin()\":[{\"notice\":\"Throws when trying to add less liquidity than the minimum liquidity required\"}],\"JobLiquidityUnexistent()\":[{\"notice\":\"Throws when the job doesn't have the requested liquidity\"}],\"JobMigrationImpossible()\":[{\"notice\":\"Throws when the address of the job that requests to migrate wants to migrate to its same address\"}],\"JobMigrationLocked()\":[{\"notice\":\"Throws when cooldown between migrations has not yet passed\"}],\"JobMigrationUnavailable()\":[{\"notice\":\"Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\"}],\"JobTokenCreditsLocked()\":[{\"notice\":\"Throws when the token withdraw cooldown has not yet passed\"}],\"JobTokenInsufficient()\":[{\"notice\":\"Throws when someone tries to slash more tokens than the job has\"}],\"JobTokenUnexistent()\":[{\"notice\":\"Throws when the token trying to be slashed doesn't exist\"}],\"JobUnapproved()\":[{\"notice\":\"Throws if the address claiming to be a job is not in the list of approved jobs\"}],\"JobUnavailable()\":[{\"notice\":\"Throws when an address is passed as a job, but that address is not a job\"}],\"LiquidityPairApproved()\":[{\"notice\":\"Throws when the liquidity being approved has already been approved\"}],\"LiquidityPairUnapproved()\":[{\"notice\":\"Throws when trying to add liquidity to an unapproved pool\"}],\"LiquidityPairUnexistent()\":[{\"notice\":\"Throws when the liquidity being removed has not been approved\"}],\"MinRewardPeriod()\":[{\"notice\":\"Throws if the reward period is less than the minimum reward period time\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"NotDisputed()\":[{\"notice\":\"Throws when a job or keeper is not disputed and someone tries to resolve the dispute\"}],\"OnlyDisputer()\":[{\"notice\":\"Throws if the msg.sender is not a disputer or is not a part of governance\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the job owner\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"OnlyPendingJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the pending job owner\"}],\"OnlySlasher()\":[{\"notice\":\"Throws if the msg.sender is not a slasher or is not a part of governance\"}],\"SlasherExistent()\":[{\"notice\":\"Throws if the address is already a registered slasher\"}],\"SlasherUnexistent()\":[{\"notice\":\"Throws if caller is not a registered slasher\"}],\"TokenUnallowed()\":[{\"notice\":\"Throws when the token is KP3R, as it should not be used for direct token payments\"}],\"UnbondsLocked()\":[{\"notice\":\"Throws if the time required to withdraw the bonds has not passed yet\"}],\"UnbondsUnexistent()\":[{\"notice\":\"Throws if there are no bonds to withdraw\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"Activation(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#activate is called\"},\"BondTimeChange(uint256)\":{\"notice\":\"Emitted when bondTime is changed\"},\"Bonding(address,address,uint256)\":{\"notice\":\"Emitted when the bonding process of a new keeper begins\"},\"Dispute(address,address)\":{\"notice\":\"Emitted when a keeper or a job is disputed\"},\"DisputerAdded(address)\":{\"notice\":\"Emitted when a disputer is added\"},\"DisputerRemoved(address)\":{\"notice\":\"Emitted when a disputer is removed\"},\"DustSent(address,uint256,address)\":{\"notice\":\"Emitted when dust is sent\"},\"FeeChange(uint256)\":{\"notice\":\"Emitted when the fee is changed\"},\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"InflationPeriodChange(uint256)\":{\"notice\":\"Emitted when the inflationPeriod is changed\"},\"JobAddition(address,address)\":{\"notice\":\"Emitted when Keep3rJobManager#addJob is called\"},\"JobMigrationRequested(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#migrateJob function is called\"},\"JobMigrationSuccessful(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#acceptJobMigration function is called\"},\"JobOwnershipAssent(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\"},\"JobOwnershipChange(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#changeJobOwnership is called\"},\"JobSlashLiquidity(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\"},\"JobSlashToken(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashTokenFromJob is called\"},\"Keep3rHelperChange(address)\":{\"notice\":\"Emitted when the Keep3rHelper address is changed\"},\"Keep3rV1Change(address)\":{\"notice\":\"Emitted when the Keep3rV1 address is changed\"},\"Keep3rV1ProxyChange(address)\":{\"notice\":\"Emitted when the Keep3rV1Proxy address is changed\"},\"KeeperRevoke(address,address)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#revoke is called\"},\"KeeperSlash(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#slash is called\"},\"KeeperValidation(uint256)\":{\"notice\":\"Emitted when a keeper is validated before a job\"},\"KeeperWork(address,address,address,uint256,uint256)\":{\"notice\":\"Emitted when a keeper works a job\"},\"LiquidityAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityApproval(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\"},\"LiquidityCreditsForced(address,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\"},\"LiquidityCreditsReward(address,uint256,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityMinimumChange(uint256)\":{\"notice\":\"Emitted when _liquidityMinimum is changed\"},\"LiquidityRevocation(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\"},\"LiquidityWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\"},\"Resolve(address,address)\":{\"notice\":\"Emitted when a dispute is resolved\"},\"RewardPeriodTimeChange(uint256)\":{\"notice\":\"Emitted when _rewardPeriodTime is changed\"},\"SlasherAdded(address)\":{\"notice\":\"Emitted when a slasher is added\"},\"SlasherRemoved(address)\":{\"notice\":\"Emitted when a slasher is removed\"},\"TokenCreditAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\"},\"TokenCreditWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\"},\"UnbondTimeChange(uint256)\":{\"notice\":\"Emitted when _unbondTime is changed\"},\"Unbonding(address,address,uint256)\":{\"notice\":\"Emitted when a keeper or job begins the unbonding process to withdraw the funds\"},\"Withdrawal(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#withdraw is called\"}},\"kind\":\"user\",\"methods\":{\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"acceptJobMigration(address,address)\":{\"notice\":\"Completes the migration process for a job\"},\"acceptJobOwnership(address)\":{\"notice\":\"The proposed address accepts to be the owner of the job\"},\"activate(address)\":{\"notice\":\"End of the bonding process after bonding time has passed\"},\"addDisputer(address)\":{\"notice\":\"Registers a disputer by updating the disputers mapping\"},\"addJob(address)\":{\"notice\":\"Allows any caller to add a new job\"},\"addLiquidityToJob(address,address,uint256)\":{\"notice\":\"Allows anyone to fund a job with liquidity\"},\"addSlasher(address)\":{\"notice\":\"Registers a slasher by updating the slashers mapping\"},\"addTokenCreditsToJob(address,address,uint256)\":{\"notice\":\"Add credit to a job to be paid out for work\"},\"approveLiquidity(address)\":{\"notice\":\"Approve a liquidity pair for being accepted in future\"},\"approvedLiquidities()\":{\"notice\":\"Lists liquidity pairs\"},\"bond(address,uint256)\":{\"notice\":\"Beginning of the bonding process\"},\"bondTime()\":{\"notice\":\"The amount of time required to pass after a keeper has bonded assets for it to be able to activate\"},\"bondedPayment(address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"bonds(address,address)\":{\"notice\":\"Mapping (job => bonding => amount)\"},\"canActivateAfter(address,address)\":{\"notice\":\"Tracks when a bonding for a keeper can be activated\"},\"canWithdrawAfter(address,address)\":{\"notice\":\"Tracks when keeper bonds are ready to be withdrawn\"},\"changeJobOwnership(address,address)\":{\"notice\":\"Proposes a new address to be the owner of the job\"},\"directTokenPayment(address,address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"dispute(address)\":{\"notice\":\"Allows governance to create a dispute for a given keeper/job\"},\"disputers(address)\":{\"notice\":\"Tracks whether the address is a disputer or not\"},\"disputes(address)\":{\"notice\":\"Tracks if a keeper or job has a pending dispute\"},\"fee()\":{\"notice\":\"The fee to be sent to governance when a user adds liquidity to a job\"},\"firstSeen(address)\":{\"notice\":\"Tracks when a keeper was first registered\"},\"forceLiquidityCreditsToJob(address,uint256)\":{\"notice\":\"Gifts liquidity credits to the specified job\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"hasBonded(address)\":{\"notice\":\"Checks whether the address has ever bonded an asset\"},\"inflationPeriod()\":{\"notice\":\"The inflation period is the denominator used to regulate the emission of KP3R\"},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"notice\":\"Confirms if the current keeper is registered and has a minimum bond of any asset.\"},\"isKeeper(address)\":{\"notice\":\"Confirms if the current keeper is registered\"},\"jobLiquidityCredits(address)\":{\"notice\":\"Returns the liquidity credits of a given job\"},\"jobOwner(address)\":{\"notice\":\"Maps the job to the owner of the job\"},\"jobPendingOwner(address)\":{\"notice\":\"Maps the job to its pending owner\"},\"jobPeriodCredits(address)\":{\"notice\":\"Returns the credits of a given job for the current period\"},\"jobTokenCredits(address,address)\":{\"notice\":\"The current token credits available for a job\"},\"jobTokenCreditsAddedAt(address,address)\":{\"notice\":\"Last block where tokens were added to the job\"},\"jobs()\":{\"notice\":\"Lists all jobs\"},\"keep3rHelper()\":{\"notice\":\"Address of Keep3rHelper's contract\"},\"keep3rV1()\":{\"notice\":\"Address of Keep3rV1's contract\"},\"keep3rV1Proxy()\":{\"notice\":\"Address of Keep3rV1Proxy's contract\"},\"keepers()\":{\"notice\":\"Lists all keepers\"},\"liquidityAmount(address,address)\":{\"notice\":\"Amount of liquidity in a specified job\"},\"liquidityMinimum()\":{\"notice\":\"The minimum amount of liquidity required to fund a job per liquidity\"},\"migrateJob(address,address)\":{\"notice\":\"Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\"},\"observeLiquidity(address)\":{\"notice\":\"Observes the current state of the liquidity pair being observed and updates TickCache with the information\"},\"pendingBonds(address,address)\":{\"notice\":\"Tracks the amount of assets deposited in pending bonds\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"pendingJobMigrations(address)\":{\"notice\":\"Maps the jobs that have requested a migration to the address they have requested to migrate to\"},\"pendingUnbonds(address,address)\":{\"notice\":\"Tracks how much keeper bonds are to be withdrawn\"},\"quoteLiquidity(address,uint256)\":{\"notice\":\"Calculates how many credits should be rewarded periodically for a given liquidity amount\"},\"removeDisputer(address)\":{\"notice\":\"Removes a disputer by updating the disputers mapping\"},\"removeSlasher(address)\":{\"notice\":\"Removes a slasher by updating the slashers mapping\"},\"resolve(address)\":{\"notice\":\"Allows governance to resolve a dispute on a keeper/job\"},\"revoke(address)\":{\"notice\":\"Blacklists a keeper from participating in the network\"},\"revokeLiquidity(address)\":{\"notice\":\"Revoke a liquidity pair from being accepted in future\"},\"rewardPeriodTime()\":{\"notice\":\"The amount of time between each scheduled credits reward given to a job\"},\"rewardedAt(address)\":{\"notice\":\"Last time the job was rewarded liquidity credits\"},\"sendDust(address,uint256,address)\":{\"notice\":\"Allows an authorized user to transfer the tokens or eth that may have been left in a contract\"},\"setBondTime(uint256)\":{\"notice\":\"Sets the bond time required to activate as a keeper\"},\"setFee(uint256)\":{\"notice\":\"Sets the new fee\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setInflationPeriod(uint256)\":{\"notice\":\"Sets the new inflation period\"},\"setKeep3rHelper(address)\":{\"notice\":\"Sets the Keep3rHelper address\"},\"setKeep3rV1(address)\":{\"notice\":\"Sets the Keep3rV1 address\"},\"setKeep3rV1Proxy(address)\":{\"notice\":\"Sets the Keep3rV1Proxy address\"},\"setLiquidityMinimum(uint256)\":{\"notice\":\"Sets the minimum amount of liquidity required to fund a job\"},\"setRewardPeriodTime(uint256)\":{\"notice\":\"Sets the time required to pass between rewards for jobs\"},\"setUnbondTime(uint256)\":{\"notice\":\"Sets the unbond time required unbond what has been bonded\"},\"slash(address,address,uint256,uint256)\":{\"notice\":\"Allows governance to slash a keeper based on a dispute\"},\"slashLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Allows governance or a slasher to slash liquidity from a job\"},\"slashTokenFromJob(address,address,uint256)\":{\"notice\":\"Allows governance or slasher to slash a job specific token\"},\"slashers(address)\":{\"notice\":\"Tracks whether the address is a slasher or not\"},\"totalBonds()\":{\"notice\":\"Tracks the total amount of bonded KP3Rs in the contract\"},\"totalJobCredits(address)\":{\"notice\":\"Calculates the total credits of a given job\"},\"unbond(address,uint256)\":{\"notice\":\"Beginning of the unbonding process\"},\"unbondLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Unbond liquidity for a job\"},\"unbondTime()\":{\"notice\":\"The amount of time required to pass before a keeper can unbond what he has bonded\"},\"withdraw(address)\":{\"notice\":\"Withdraw funds after unbonding has finished\"},\"withdrawLiquidityFromJob(address,address,address)\":{\"notice\":\"Withdraw liquidity from a job\"},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"notice\":\"Withdraw credit from a job\"},\"workCompleted(address)\":{\"notice\":\"Tracks the total KP3R earnings of a keeper since it started working\"},\"worked(address)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"workedAt(address)\":{\"notice\":\"Last time the job was worked\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/testnet/Keep3rForTestnet.sol\":\"Keep3rForTestnet\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"solidity/contracts/Keep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../interfaces/IKeep3r.sol';\\nimport './peripherals/jobs/Keep3rJobs.sol';\\nimport './peripherals/keepers/Keep3rKeepers.sol';\\nimport './peripherals/DustCollector.sol';\\n\\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\\n constructor(\\n address _governance,\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\\n}\\n\",\"keccak256\":\"0x8b7a11409585a734b97d64773753921ea64b17ea6ee45d712d0478898990a8b0\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/DustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '../../contracts/peripherals/Governable.sol';\\nimport '../../interfaces/peripherals/IDustCollector.sol';\\n\\nabstract contract DustCollector is IDustCollector, Governable {\\n using SafeERC20 for IERC20;\\n\\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external override onlyGovernance {\\n if (_to == address(0)) revert ZeroAddress();\\n if (_token == _ETH_ADDRESS) {\\n payable(_to).transfer(_amount);\\n } else {\\n IERC20(_token).safeTransfer(_to, _amount);\\n }\\n emit DustSent(_token, _amount, _to);\\n }\\n}\\n\",\"keccak256\":\"0x246ac2c4057520bb627ea8040367549786f4477a04fd79358927cd607952bc2f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\\nimport './Keep3rRoles.sol';\\n\\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @notice List of all enabled keepers\\n EnumerableSet.AddressSet internal _keepers;\\n\\n /// @inheritdoc IKeep3rAccountance\\n uint256 public override totalBonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override workCompleted;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override firstSeen;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override disputes;\\n\\n /// @inheritdoc IKeep3rAccountance\\n /// @notice Mapping (job => bonding => amount)\\n mapping(address => mapping(address => uint256)) public override bonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\\n\\n /// @notice The current liquidity credits available for a job\\n mapping(address => uint256) internal _jobLiquidityCredits;\\n\\n /// @notice Map the address of a job to its correspondent periodCredits\\n mapping(address => uint256) internal _jobPeriodCredits;\\n\\n /// @notice Enumerable array of Job Tokens for Credits\\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\\n\\n /// @notice List of liquidities that a job has (job => liquidities)\\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\\n\\n /// @notice Liquidity pool to observe\\n mapping(address => address) internal _liquidityPool;\\n\\n /// @notice Tracks if a pool has KP3R as token0\\n mapping(address => bool) internal _isKP3RToken0;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingBonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override hasBonded;\\n\\n /// @notice List of all enabled jobs\\n EnumerableSet.AddressSet internal _jobs;\\n\\n /// @inheritdoc IKeep3rAccountance\\n function jobs() external view override returns (address[] memory _list) {\\n _list = _jobs.values();\\n }\\n\\n /// @inheritdoc IKeep3rAccountance\\n function keepers() external view override returns (address[] memory _list) {\\n _list = _keepers.values();\\n }\\n}\\n\",\"keccak256\":\"0xcd2a525e6567eea4f2a7f93e8eb686e484d2a078686f2744dde35a8383881730\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rParameters.sol';\\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\\n\\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\\n /// @inheritdoc IKeep3rDisputable\\n function dispute(address _jobOrKeeper) external override onlyDisputer {\\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\\n disputes[_jobOrKeeper] = true;\\n emit Dispute(_jobOrKeeper, msg.sender);\\n }\\n\\n /// @inheritdoc IKeep3rDisputable\\n function resolve(address _jobOrKeeper) external override onlyDisputer {\\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\\n disputes[_jobOrKeeper] = false;\\n emit Resolve(_jobOrKeeper, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x664b54040aa4e734f68a01fcfb5bf67cbb1a70efd03862cd3a456457536b1fb4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/IKeep3rHelper.sol';\\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\\nimport './Keep3rAccountance.sol';\\n\\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1Proxy;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rHelper;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override bondTime = 3 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override unbondTime = 14 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override liquidityMinimum = 3 ether;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override rewardPeriodTime = 5 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override inflationPeriod = 34 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override fee = 30;\\n\\n /// @notice The base that will be used to calculate the fee\\n uint256 internal constant _BASE = 10_000;\\n\\n /// @notice The minimum reward period\\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\\n\\n constructor(\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) {\\n keep3rHelper = _keep3rHelper;\\n keep3rV1 = _keep3rV1;\\n keep3rV1Proxy = _keep3rV1Proxy;\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\\n if (_keep3rHelper == address(0)) revert ZeroAddress();\\n keep3rHelper = _keep3rHelper;\\n emit Keep3rHelperChange(_keep3rHelper);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\\n if (_keep3rV1 == address(0)) revert ZeroAddress();\\n _mint(totalBonds);\\n\\n keep3rV1 = _keep3rV1;\\n emit Keep3rV1Change(_keep3rV1);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\\n keep3rV1Proxy = _keep3rV1Proxy;\\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\\n bondTime = _bondTime;\\n emit BondTimeChange(_bondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\\n unbondTime = _unbondTime;\\n emit UnbondTimeChange(_unbondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\\n liquidityMinimum = _liquidityMinimum;\\n emit LiquidityMinimumChange(_liquidityMinimum);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\\n rewardPeriodTime = _rewardPeriodTime;\\n emit RewardPeriodTimeChange(_rewardPeriodTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\\n inflationPeriod = _inflationPeriod;\\n emit InflationPeriodChange(_inflationPeriod);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setFee(uint256 _fee) external override onlyGovernance {\\n fee = _fee;\\n emit FeeChange(_fee);\\n }\\n\\n function _mint(uint256 _amount) internal {\\n totalBonds -= _amount;\\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\\n }\\n}\\n\",\"keccak256\":\"0x180349c0ff1fffec1566fba13b494595dcc5ca7eaf049d3f7a2a8d1c60de7d0f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport './DustCollector.sol';\\nimport './Governable.sol';\\n\\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override slashers;\\n\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override disputers;\\n\\n constructor(address _governance) Governable(_governance) DustCollector() {}\\n\\n /// @inheritdoc IKeep3rRoles\\n function addSlasher(address _slasher) external override onlyGovernance {\\n if (_slasher == address(0)) revert ZeroAddress();\\n if (slashers[_slasher]) revert SlasherExistent();\\n slashers[_slasher] = true;\\n emit SlasherAdded(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeSlasher(address _slasher) external override onlyGovernance {\\n if (!slashers[_slasher]) revert SlasherUnexistent();\\n delete slashers[_slasher];\\n emit SlasherRemoved(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function addDisputer(address _disputer) external override onlyGovernance {\\n if (_disputer == address(0)) revert ZeroAddress();\\n if (disputers[_disputer]) revert DisputerExistent();\\n disputers[_disputer] = true;\\n emit DisputerAdded(_disputer);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeDisputer(address _disputer) external override onlyGovernance {\\n if (!disputers[_disputer]) revert DisputerUnexistent();\\n delete disputers[_disputer];\\n emit DisputerRemoved(_disputer);\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a slasher or governance\\n modifier onlySlasher {\\n if (!slashers[msg.sender]) revert OnlySlasher();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a disputer or governance\\n modifier onlyDisputer {\\n if (!disputers[msg.sender]) revert OnlyDisputer();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x61a1cf0d52db8fe78fa8cfb76d9b02f93ef3adc23e6655969bc1a4bb83ea9a95\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\nimport '../Keep3rDisputable.sol';\\n\\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\\n\\n try IERC20(_token).transfer(governance, _amount) {} catch {}\\n jobTokenCredits[_job][_token] -= _amount;\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit JobSlashToken(_job, _token, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x86cdbf44dfa46c6b6e184e48e11cb8571e26cf50c793b6b07227c29e743da397\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice Cooldown between withdrawals\\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n // KP3R shouldn't be used for direct token payments\\n if (_token == keep3rV1) revert TokenUnallowed();\\n uint256 _before = IERC20(_token).balanceOf(address(this));\\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\\n uint256 _tokenFee = (_received * fee) / _BASE;\\n jobTokenCredits[_job][_token] += _received - _tokenFee;\\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\\n IERC20(_token).safeTransfer(governance, _tokenFee);\\n _jobTokens[_job].add(_token);\\n\\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external override nonReentrant onlyJobOwner(_job) {\\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\\n if (disputes[_job]) revert JobDisputed();\\n\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xb600d18903a008a1ca03743de7cef8330c2d5e66db52c900822551a4be75f7a5\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/IPairManager.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '../../libraries/FullMath.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice List of liquidities that are accepted in the system\\n EnumerableSet.AddressSet internal _approvedLiquidities;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override rewardedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override workedAt;\\n\\n /// @notice Tracks an address and returns its TickCache\\n mapping(address => TickCache) internal _tick;\\n\\n // Views\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approvedLiquidities() external view override returns (address[] memory _list) {\\n _list = _approvedLiquidities.values();\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n _periodCredits += _getReward(\\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\\n );\\n }\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n\\n // If the job was rewarded in the past 1 period time\\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\\n // If the job has period credits, update minted job credits to new twap\\n _liquidityCredits = _periodCredits > 0\\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\\n } else {\\n // Else return a full period worth of credits if current credits have expired\\n _liquidityCredits = _periodCredits;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n uint256 _cooldown = block.timestamp;\\n\\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\\n // Will calculate cooldown if it outdated\\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will calculate cooldown from last reward reference in this period\\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\\n } else {\\n // Will calculate cooldown from last reward timestamp\\n _cooldown -= rewardedAt[_job];\\n }\\n } else {\\n // Will calculate cooldown from period start if expired\\n _cooldown -= _period(block.timestamp);\\n }\\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\\n if (_tick[_liquidity].period == _period(block.timestamp)) {\\n // Will return cached twaps if liquidity is updated\\n _tickCache = _tick[_liquidity];\\n } else {\\n bool success;\\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\\n\\n if (_tick[_liquidity].period == lastPeriod) {\\n // Will only ask for current period accumulator if liquidity is outdated\\n uint32[] memory _secondsAgo = new uint32[](1);\\n int56 previousTick = _tick[_liquidity].current;\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n\\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - previousTick;\\n } else if (_tick[_liquidity].period < lastPeriod) {\\n // Will ask for 2 accumulators if liquidity is expired\\n uint32[] memory _secondsAgo = new uint32[](2);\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\\n\\n int56 _tickCumulative2;\\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - _tickCumulative2;\\n }\\n if (success) {\\n _tickCache.period = _period(block.timestamp);\\n } else {\\n delete _tickCache.period;\\n }\\n }\\n }\\n\\n // Methods\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n _settleJobAccountance(_job);\\n _jobLiquidityCredits[_job] += _amount;\\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n emit LiquidityApproval(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\\n delete _liquidityPool[_liquidity];\\n delete _isKP3RToken0[_liquidity];\\n delete _tick[_liquidity];\\n\\n emit LiquidityRevocation(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n\\n _jobLiquidities[_job].add(_liquidity);\\n\\n _settleJobAccountance(_job);\\n\\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\\n liquidityAmount[_job][_liquidity] += _amount;\\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlyJobOwner(_job) {\\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\\n pendingUnbonds[_job][_liquidity] += _amount;\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n\\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit Unbonding(_job, _liquidity, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external override onlyJobOwner(_job) {\\n if (_receiver == address(0)) revert ZeroAddress();\\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[_job]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[_job][_liquidity];\\n\\n delete pendingUnbonds[_job][_liquidity];\\n delete canWithdrawAfter[_job][_liquidity];\\n\\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\\n }\\n\\n // Internal functions\\n\\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\\n if (rewardedAt[_job] < _period(block.timestamp)) {\\n // Will exit function if job has been rewarded in current period\\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\\n // Will reset job to period syncronicity if a full period passed without rewards\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] = _period(block.timestamp);\\n _rewarded = true;\\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will reset job's syncronicity if last reward was more than epoch ago\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] += rewardPeriodTime;\\n _rewarded = true;\\n } else if (workedAt[_job] < _period(block.timestamp)) {\\n // First keeper on period has to update job accountance to current twaps\\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\\n // Updating job accountance does not reward job\\n }\\n }\\n }\\n\\n /// @notice Only called if _jobLiquidityCredits < payment\\n function _rewardJobCredits(address _job) internal {\\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\\n rewardedAt[_job] = block.timestamp;\\n }\\n\\n /// @notice Updates accountance for _jobPeriodCredits\\n function _updateJobPeriod(address _job) internal {\\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\\n }\\n\\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n if (_tick[_liquidity].period != _period(block.timestamp)) {\\n // Updates liquidity cache only if needed\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n }\\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\\n }\\n }\\n }\\n\\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\\n function _unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) internal nonReentrant {\\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\\n\\n // Ensures current twaps in job liquidities\\n _updateJobPeriod(_job);\\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\\n\\n // A liquidity can be revoked causing a job to have 0 periodCredits\\n if (_jobPeriodCredits[_job] > 0) {\\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\\n }\\n\\n liquidityAmount[_job][_liquidity] -= _amount;\\n if (liquidityAmount[_job][_liquidity] == 0) {\\n _jobLiquidities[_job].remove(_liquidity);\\n }\\n }\\n\\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\\n if (_timePassed < rewardPeriodTime) {\\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\\n } else _result = _multiplier;\\n }\\n\\n /// @notice Returns the start of the period of the provided timestamp\\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\\n return _timestamp - (_timestamp % rewardPeriodTime);\\n }\\n\\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\\n }\\n\\n /// @notice Returns underlying KP3R amount for a given liquidity amount\\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\\n if (_tick[_liquidity].period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\\n }\\n }\\n\\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\\n /// @dev Ensures a maximum of 1 period of credits\\n function _settleJobAccountance(address _job) internal virtual {\\n _updateJobCreditsIfNeeded(_job);\\n _rewardJobCredits(_job);\\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n}\\n\",\"keccak256\":\"0xe3b244460364baf1ea293db6f6feba8365fd376320ad77ae6d6813ed65b52929\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @inheritdoc IKeep3rJobManager\\n function addJob(address _job) external override {\\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\\n if (hasBonded[_job]) revert AlreadyAKeeper();\\n _jobs.add(_job);\\n jobOwner[_job] = msg.sender;\\n emit JobAddition(_job, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xf6e1577a6a34b674ca34a6d7530dc81349e3ad13d321281c37e0b25b7325d013\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\n\\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n mapping(address => address) public override pendingJobMigrations;\\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\\n if (_fromJob == _toJob) revert JobMigrationImpossible();\\n\\n pendingJobMigrations[_fromJob] = _toJob;\\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\\n\\n emit JobMigrationRequested(_fromJob, _toJob);\\n }\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\\n\\n // force job credits update for both jobs\\n _settleJobAccountance(_fromJob);\\n _settleJobAccountance(_toJob);\\n\\n // migrate tokens\\n while (_jobTokens[_fromJob].length() > 0) {\\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\\n _jobTokens[_fromJob].remove(_tokenToMigrate);\\n _jobTokens[_toJob].add(_tokenToMigrate);\\n }\\n\\n // migrate liquidities\\n while (_jobLiquidities[_fromJob].length() > 0) {\\n address _liquidity = _jobLiquidities[_fromJob].at(0);\\n\\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\\n delete liquidityAmount[_fromJob][_liquidity];\\n\\n _jobLiquidities[_toJob].add(_liquidity);\\n _jobLiquidities[_fromJob].remove(_liquidity);\\n }\\n\\n // migrate job balances\\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\\n delete _jobPeriodCredits[_fromJob];\\n\\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\\n delete _jobLiquidityCredits[_fromJob];\\n\\n // stop _fromJob from being a job\\n delete rewardedAt[_fromJob];\\n _jobs.remove(_fromJob);\\n\\n // delete unused data slots\\n delete jobOwner[_fromJob];\\n delete jobPendingOwner[_fromJob];\\n delete _migrationCreatedAt[_fromJob][_toJob];\\n delete pendingJobMigrations[_fromJob];\\n\\n emit JobMigrationSuccessful(_fromJob, _toJob);\\n }\\n}\\n\",\"keccak256\":\"0xd46c3c9ce970098d8d75f11966894a341824aceb40583fcfbbc0ebda93d869f9\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobPendingOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\\n jobPendingOwner[_job] = _newOwner;\\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\\n }\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\\n address _previousOwner = jobOwner[_job];\\n\\n jobOwner[_job] = jobPendingOwner[_job];\\n delete jobPendingOwner[_job];\\n\\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\\n }\\n\\n modifier onlyJobOwner(address _job) {\\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\\n _;\\n }\\n\\n modifier onlyPendingJobOwner(address _job) {\\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xa837590ade9cd5d25690e3f2d8b9a63e7202f7179b32e42eab4fa4c4324b9728\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobMigration.sol';\\nimport '../../../interfaces/IKeep3rHelper.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n uint256 internal _initialGas;\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\\n _initialGas = _getGasLeft();\\n if (_keepers.contains(_keeper)) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external override returns (bool _isBondedKeeper) {\\n _initialGas = _getGasLeft();\\n if (\\n _keepers.contains(_keeper) &&\\n bonds[_keeper][_bond] >= _minBond &&\\n workCompleted[_keeper] >= _earned &&\\n block.timestamp - firstSeen[_keeper] >= _age\\n ) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function worked(address _keeper) external virtual override {\\n if (_initialGas == 0) revert GasNotInitialized();\\n address _job = msg.sender;\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\\n\\n uint256 _gasLeft = _getGasLeft();\\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n _gasLeft = _getGasLeft();\\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n delete _initialGas;\\n\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function bondedPayment(address _keeper, uint256 _payment) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (disputes[_keeper]) revert Disputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_keeper, _amount);\\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\\n }\\n\\n function _bondedPayment(\\n address _job,\\n address _keeper,\\n uint256 _payment\\n ) internal {\\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\\n\\n workedAt[_job] = block.timestamp;\\n _jobLiquidityCredits[_job] -= _payment;\\n bonds[_keeper][keep3rV1] += _payment;\\n workCompleted[_keeper] += _payment;\\n totalBonds += _payment;\\n }\\n\\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\\n /// @param _gasLeft Amount of gas left after working the job\\n /// @param _extraGas Amount of expected unaccounted gas\\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\\n /// @return _payment Amount to be payed in KP3R tokens\\n function _calculatePayment(\\n uint256 _gasLeft,\\n uint256 _extraGas,\\n uint256 _oneEthQuote,\\n uint256 _boost\\n ) internal view returns (uint256 _payment) {\\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\\n }\\n\\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\\n _gasLeft = (gasleft() * 64) / 63;\\n }\\n}\\n\",\"keccak256\":\"0x7e113a0815d9125e760ee75c9d9c55fc93192ae2535afccdb8835984d17b510f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobManager.sol';\\nimport './Keep3rJobWorkable.sol';\\nimport './Keep3rJobDisputable.sol';\\n\\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\\n\",\"keccak256\":\"0x882e1a19891795de04c4c891dc58d50034ca0a32c8b61651aaf0f47d0bc321d4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rKeeperFundable.sol';\\nimport '../Keep3rDisputable.sol';\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function revoke(address _keeper) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _keepers.remove(_keeper);\\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\\n emit KeeperRevoke(_keeper, msg.sender);\\n }\\n\\n function _slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) internal {\\n if (_bonded != keep3rV1) {\\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\\n }\\n bonds[_keeper][_bonded] -= _bondAmount;\\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\\n }\\n}\\n\",\"keccak256\":\"0xa15b13218af4331d1fb3e8cfdfa9b69117f291ac9a462ede6b1b4fb5be8967de\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\\n if (disputes[msg.sender]) revert Disputed();\\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\\n\\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\\n\\n hasBonded[msg.sender] = true;\\n pendingBonds[msg.sender][_bonding] += _amount;\\n\\n emit Bonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function activate(address _bonding) external override {\\n address _keeper = msg.sender;\\n if (disputes[_keeper]) revert Disputed();\\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\\n if (_canActivateAfter == 0) revert BondsUnexistent();\\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\\n\\n if (firstSeen[_keeper] == 0) {\\n firstSeen[_keeper] = block.timestamp;\\n }\\n _keepers.add(_keeper);\\n\\n uint256 _amount = pendingBonds[_keeper][_bonding];\\n delete pendingBonds[_keeper][_bonding];\\n\\n // bond provided tokens\\n bonds[_keeper][_bonding] += _amount;\\n if (_bonding == keep3rV1) {\\n totalBonds += _amount;\\n _depositBonds(_amount);\\n }\\n\\n emit Activation(_keeper, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function unbond(address _bonding, uint256 _amount) external override {\\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\\n bonds[msg.sender][_bonding] -= _amount;\\n pendingUnbonds[msg.sender][_bonding] += _amount;\\n\\n emit Unbonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function withdraw(address _bonding) external override nonReentrant {\\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[msg.sender]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\\n\\n delete pendingUnbonds[msg.sender][_bonding];\\n delete canWithdrawAfter[msg.sender][_bonding];\\n\\n if (_bonding == keep3rV1) _mint(_amount);\\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\\n\\n emit Withdrawal(msg.sender, _bonding, _amount);\\n }\\n\\n function _depositBonds(uint256 _amount) internal virtual {\\n IKeep3rV1(keep3rV1).burn(_amount);\\n }\\n}\\n\",\"keccak256\":\"0x121dc11fa555731679912d54da3bb8282d26ad425deffae6d4d7085ef3c9290d\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\nimport './Keep3rKeeperDisputable.sol';\\n\\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\\n\",\"keccak256\":\"0xfc762d9fd6ff478acba446c3ab6fc19c7d49a85de097dc35f02c56e928153c5e\",\"license\":\"MIT\"},\"solidity/for-test/testnet/Keep3rForTestnet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../contracts/Keep3r.sol';\\n\\ncontract Keep3rForTestnet is Keep3r {\\n constructor(\\n address _governance,\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\\n bondTime = 0; // allows keepers to instantly register\\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\\n liquidityMinimum = 1; // allows job providers to add low liquidity\\n rewardPeriodTime = 1 days; // reduces twap calculation period\\n inflationPeriod = 5 days; // increases credit minting\\n }\\n}\\n\",\"keccak256\":\"0x4465378f7a00fc8d5d8eedf470fe039bdcf6e56e5eb68160932c80e70951420b\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct TokenOraclePool {\\n address poolAddress;\\n bool isTKNToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0x76f99ca04361c0459fc9e99f0387ddb76da18cc470ec5bc744e7dc3bf6e9d334\",\"license\":\"MIT\"},\"solidity/interfaces/IPairManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n/// @title Pair Manager interface\\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\\ninterface IPairManager is IERC20Metadata {\\n /// @notice Address of the factory from which the pair manager was created\\n /// @return _factory The address of the PairManager Factory\\n function factory() external view returns (address _factory);\\n\\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\\n /// @return _pool The address of the pool\\n function pool() external view returns (address _pool);\\n\\n /// @notice Token0 of the pool\\n /// @return _token0 The address of token0\\n function token0() external view returns (address _token0);\\n\\n /// @notice Token1 of the pool\\n /// @return _token1 The address of token1\\n function token1() external view returns (address _token1);\\n}\\n\",\"keccak256\":\"0x345c312b340c5775fb8f68d89ce851c7f75522940bd9bc64f2301a3f8312636a\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IGovernable.sol';\\n\\ninterface IKeep3rV1Proxy is IGovernable {\\n // Structs\\n struct Recipient {\\n address recipient;\\n uint256 caps;\\n }\\n\\n // Variables\\n function keep3rV1() external view returns (address);\\n\\n function minter() external view returns (address);\\n\\n function next(address) external view returns (uint256);\\n\\n function caps(address) external view returns (uint256);\\n\\n function recipients() external view returns (address[] memory);\\n\\n function recipientsCaps() external view returns (Recipient[] memory);\\n\\n // Errors\\n error Cooldown();\\n error NoDrawableAmount();\\n error ZeroAddress();\\n error OnlyMinter();\\n\\n // Methods\\n function addRecipient(address recipient, uint256 amount) external;\\n\\n function removeRecipient(address recipient) external;\\n\\n function draw() external returns (uint256 _amount);\\n\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n function setMinter(address _minter) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function mint(address _account, uint256 _amount) external;\\n\\n function setKeep3rV1Governance(address _governance) external;\\n\\n function acceptKeep3rV1Governance() external;\\n\\n function dispute(address _keeper) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function addJob(address _job) external;\\n\\n function removeJob(address _job) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n}\\n\",\"keccak256\":\"0xfb2e81fe347b39aabce849ef2d42c6df846b7ef0ed5ae952c85bbb708da99408\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0xf4748c236ddf409e45e7169c735e2fc54e627b2b3ccd189ebb438ad768f1deb1\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040526203f480601f55621275006020556729a2241af62c000060215562069780602255622cd300602355601e6024553480156200003e57600080fd5b5060405162005fcc38038062005fcc83398101604081905262000061916200012a565b60016000558383838382828286806001600160a01b038116620000965760405162b293ed60e81b815260040160405180910390fd5b600380546001600160a01b03199081166001600160a01b0393841617909155601e8054821696831696909617909555601c805486169482169490941790935550601d8054909316911617905550506000601f8190556020555050600160215550506201518060225550506206978060235562000187565b80516001600160a01b03811681146200012557600080fd5b919050565b600080600080608085870312156200014157600080fd5b6200014c856200010d565b93506200015c602086016200010d565b92506200016c604086016200010d565b91506200017c606086016200010d565b905092959194509250565b615e3580620001976000396000f3fe608060405234801561001057600080fd5b50600436106103e15760003560e01c8063951dc22c1161020d578063c7ae40d011610121578063c7ae40d0146109c3578063cb4be2bb146109d6578063cb54694d146109e9578063cd22af1b146109fc578063d55995fe14610a27578063dd2080d614610a3a578063ddca3f4314610a4d578063e326ac4314610a56578063ebbb619414610a76578063ec00cdfc14610a89578063ec8ca64314610a9c578063f0f346b914610ac5578063f11a1d1a14610ad8578063f136a09d14610aeb578063f25e311b14610b0b578063f263c47014610b1e578063f39c38a014610b27578063f75f9f7b14610b3a578063f9d46cf214610b4d578063fc253d2b14610b60578063fe75bc4614610b6957600080fd5b8063951dc22c146107d6578063966abd00146107de57806398e90a0f146107f15780639d5c33d81461081a578063a21458091461082d578063a39744b514610840578063a515366a1461086b578063a5d059ca1461087e578063a676f9ff14610891578063a7d2e784146108b1578063aac6aa9c146108ba578063ab033ea9146108cd578063af320e81146108e0578063b0103b1a146108f3578063b239223314610916578063b440027f14610929578063b600702a14610954578063b7e7734014610967578063b87fcbff1461097a578063c20297f01461099d578063c5198abc146109b057600080fd5b806359a2255e1161030457806359a2255e146106325780635aa6e675146106455780635ebe23f0146106585780635feeb79414610661578063633fb68f1461067457806364bb43ee1461067d57806368a9f19c14610690578063694798e6146106a357806369fe0e2d146106ce5780636ba42aaa146106e15780636cf262bc146106f45780636e2a9ca61461070757806372da828a1461071a57806374a8f1031461072d578063768b5d90146107405780637c8fce2314610749578063878c723e146107515780638bb6dfa81461077a5780638cb22b761461078d5780638fe204dd146107b057806390a4684e146107c357600080fd5b8063034d4c61146103e657806307b435c21461040c5780630c620bce146104375780630d6a1f871461044c5780631101eb411461045f57806311466d721461047457806315006b8214610487578063165e62e7146104b2578063168f92e7146104ef5780631b44555e1461051a5780631c5a9d9c1461053a5780631ef94b911461054d57806321040b011461056d578063238efcbc14610598578063274a8db4146105a057806351cff8d9146105d357806352a4de29146105e657806355ea6c47146105f9578063575288bf1461060c578063594a3a931461061f575b600080fd5b6103f96103f4366004615786565b610b7c565b6040519081526020015b60405180910390f35b6103f961041a3660046157c0565b601760209081526000928352604080842090915290825290205481565b61043f610c82565b6040516104039190615b35565b6103f961045a36600461596f565b610c93565b61047261046d366004615844565b610d99565b005b61047261048236600461596f565b610ef3565b6103f96104953660046157c0565b601560209081526000928352604080842090915290825290205481565b6104c56104c0366004615786565b611082565b604080518251600690810b825260208085015190910b908201529181015190820152606001610403565b6103f96104fd3660046157c0565b600e60209081526000928352604080842090915290825290205481565b6103f9610528366004615786565b600a6020526000908152604090205481565b610472610548366004615786565b611448565b601c54610560906001600160a01b031681565b6040516104039190615aac565b6103f961057b3660046157c0565b601860209081526000928352604080842090915290825290205481565b610472611603565b6105c36105ae366004615786565b60066020526000908152604090205460ff1681565b6040519015158152602001610403565b6104726105e1366004615786565b61168f565b6104726105f4366004615844565b611827565b610472610607366004615786565b611a58565b61047261061a366004615844565b611b0c565b61047261062d3660046157c0565b611dcf565b610472610640366004615786565b611e74565b600354610560906001600160a01b031681565b6103f9601f5481565b61047261066f366004615786565b611f26565b6103f960215481565b61047261068b366004615786565b6121b5565b61047261069e366004615786565b612296565b6103f96106b13660046157c0565b602860209081526000928352604080842090915290825290205481565b6104726106dc366004615a30565b612375565b6105c36106ef366004615786565b6123d5565b6103f9610702366004615786565b612435565b610472610715366004615844565b61256b565b610472610728366004615786565b6126ba565b61047261073b366004615786565b612757565b6103f960225481565b61043f612852565b61056061075f366004615786565b6001602052600090815260409020546001600160a01b031681565b6103f9610788366004615786565b61285e565b6105c361079b366004615786565b60196020526000908152604090205460ff1681565b6104726107be366004615a30565b612901565b6104726107d13660046157c0565b61295f565b61043f612a4d565b6104726107ec36600461599b565b612a59565b6105606107ff366004615786565b6002602052600090815260409020546001600160a01b031681565b610472610828366004615786565b612b6f565b61047261083b3660046157f9565b612c4e565b6103f961084e3660046157c0565b600d60209081526000928352604080842090915290825290205481565b61047261087936600461596f565b612e1e565b61047261088c36600461596f565b61307f565b6103f961089f366004615786565b60296020526000908152604090205481565b6103f960205481565b6104726108c8366004615786565b613159565b6104726108db366004615786565b61320d565b6104726108ee3660046157c0565b613283565b6105c3610901366004615786565b600c6020526000908152604090205460ff1681565b610472610924366004615a30565b613702565b6103f96109373660046157c0565b602560209081526000928352604080842090915290825290205481565b610472610962366004615786565b613762565b610472610975366004615a30565b613987565b6105c3610988366004615786565b60056020526000908152604090205460ff1681565b6104726109ab3660046158d8565b6139e7565b6104726109be366004615786565b613aa0565b601d54610560906001600160a01b031681565b6104726109e4366004615786565b613b66565b6104726109f7366004615a30565b613c03565b6103f9610a0a3660046157c0565b601660209081526000928352604080842090915290825290205481565b610472610a35366004615885565b613c87565b610472610a48366004615844565b613ebe565b6103f960245481565b6103f9610a64366004615786565b600b6020526000908152604090205481565b610472610a84366004615a30565b61403b565b610472610a97366004615786565b61409b565b610560610aaa366004615786565b602c602052600090815260409020546001600160a01b031681565b610472610ad3366004615786565b614143565b601e54610560906001600160a01b031681565b6103f9610af9366004615786565b602a6020526000908152604090205481565b610472610b19366004615844565b6141f7565b6103f960095481565b600454610560906001600160a01b031681565b610472610b48366004615786565b61443c565b6105c3610b5b36600461591e565b6144f4565b6103f960235481565b610472610b7736600461596f565b6145dd565b600080610b8883612435565b6022549091504290610ba390610b9e9083615cb6565b6146cd565b6001600160a01b0385166000908152602960205260409020541115610c47576022546001600160a01b038516600090815260296020526040902054610be89042615cb6565b10610c24576022546001600160a01b038516600090815260296020526040902054610c139190615c1b565b610c1d9082615cb6565b9050610c5d565b6001600160a01b038416600090815260296020526040902054610c1d9082615cb6565b610c50426146cd565b610c5a9082615cb6565b90505b610c6781836146e7565b610c708561285e565b610c7a9190615c1b565b949350505050565b6060610c8e6026614711565b905090565b6000610ca0602684614725565b15610d93576000610cb084611082565b90508060400151600014610d91576001600160a01b03841660009081526014602052604081205460ff16610cf1578160200151610cec90615d28565b610cf7565b81602001515b601e5460225460405163a0d2710760e01b8152929350610d88926001600160a01b039092169163a0d2710791610d339189918791600401615bec565b60206040518083038186803b158015610d4b57600080fd5b505afa158015610d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d839190615a49565b614747565b92505050610d93565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610dd557604051636efb4f4160e11b815260040160405180910390fd5b602054610de29042615c1b565b6001600160a01b03808616600081815260176020908152604080832094891680845294825280832095909555918152601882528381209281529190529081208054849290610e31908490615c1b565b90915550610e429050848484614758565b6001600160a01b038085166000908152602860209081526040808320938716835292905220548015801590610e815750602154610e7f8286614966565b105b15610e9f57604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de85604051610ee491815260200190565b60405180910390a35050505050565b336000818152600c602052604090205460ff1615610f245760405163ad2fdf3b60e01b815260040160405180910390fd5b610f2f601a82614725565b610f4b5760405162941a5760e11b815260040160405180910390fd5b610f5481614a84565b15610faf576001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615de083398151915293610fa69390929091615c05565b60405180910390a25b6001600160a01b0381166000908152600f602052604090205482111561102e57610fd881614c5a565b6001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615de0833981519152936110259390929091615c05565b60405180910390a25b611039818484614ce8565b601c546001600160a01b03808516918382169116600080516020615dc083398151915285611065614de5565b6040805192835260208301919091520160405180910390a4505050565b60408051606081018252600080825260208201819052918101919091526110a8426146cd565b6001600160a01b0383166000908152602b6020526040902060010154141561111e57506001600160a01b03166000908152602b602090815260409182902082516060810184528154600681810b810b810b8352600160381b909104810b810b900b92810192909252600101549181019190915290565b60008061113260225442610b9e9190615cb6565b6001600160a01b0385166000908152602b602052604090206001015490915081141561129657604080516001808252818301909252600091602080830190803683375050506001600160a01b0386166000908152602b602052604090205490915060060b61119f426146cd565b6111a99042615cb6565b826000815181106111bc576111bc615d91565b63ffffffff909216602092830291909101820152601e546001600160a01b038881166000908152601390935260409283902054925163dc686d9160e01b81529181169263dc686d91926112189291909116908690600401615ac0565b60606040518083038186803b15801561123057600080fd5b505afa158015611244573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126891906159ed565b600692830b90920b80885291955061128291839150615c66565b600690810b900b60208601525061141f9050565b6001600160a01b0384166000908152602b602052604090206001015481111561141f576040805160028082526060820183526000926020830190803683370190505090506112e3426146cd565b6112ed9042615cb6565b8160008151811061130057611300615d91565b602002602001019063ffffffff16908163ffffffff1681525050602254611326426146cd565b6113309042615cb6565b61133a9190615c1b565b8160018151811061134d5761134d615d91565b63ffffffff909216602092830291909101820152601e546001600160a01b0387811660009081526013909352604080842054905163dc686d9160e01b81529282169263dc686d91926113a59216908690600401615ac0565b60606040518083038186803b1580156113bd57600080fd5b505afa1580156113d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f591906159ed565b600692830b90920b8088529195509150611410908290615c66565b600690810b900b602086015250505b81156114385761142e426146cd565b6040840152611440565b600060408401525b50505b919050565b336000818152600c602052604090205460ff1615611479576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b03808216600090815260166020908152604080832093861683529290522054806114bd57604051636258f48160e01b815260040160405180910390fd5b4281106114dd57604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600b6020526040902054611516576001600160a01b0382166000908152600b602052604090204290555b611521600783614dff565b506001600160a01b038083166000818152601560209081526040808320948816808452948252808320805490849055938352600d8252808320948352939052918220805491928392611574908490615c1b565b9091555050601c546001600160a01b03858116911614156115b05780600960008282546115a19190615c1b565b909155506115b0905081614e14565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a75836040516115f591815260200190565b60405180910390a350505050565b6004546001600160a01b0316331461162e57604051637ef5703160e11b815260040160405180910390fd5b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161168591615aac565b60405180910390a1565b600260005414156116bb5760405162461bcd60e51b81526004016116b290615bb5565b60405180910390fd5b600260009081553381526018602090815260408083206001600160a01b03851684529091529020546117005760405163184c088160e21b815260040160405180910390fd5b3360009081526017602090815260408083206001600160a01b03851684529091529020544211611743576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600c602052604090205460ff1615611774576040516362e6201d60e01b815260040160405180910390fd5b3360008181526018602090815260408083206001600160a01b038681168086529184528285208054908690559585526017845282852082865290935290832092909255601c541614156117ca576117ca81614e76565b6117de6001600160a01b0383163383614ebe565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b6002600054141561184a5760405162461bcd60e51b81526004016116b290615bb5565b600260005561185a602683614725565b6118775760405163e0b6aead60e01b815260040160405180910390fd5b611882601a84614725565b61189f57604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526012602052604090206118c19083614dff565b506118cb83614f19565b6021546001600160a01b0380851660009081526028602090815260408083209387168352929052205461190990611903908490615c1b565b84614966565b101561192857604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615de0833981519152936119759390929091615c05565b60405180910390a26119926001600160a01b038316333084614f77565b6001600160a01b038084166000908152602860209081526040808320938616835292905290812080548392906119c9908490615c1b565b909155506119dc9050610d838284614966565b6001600160a01b03841660009081526010602052604081208054909190611a04908490615c1b565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff16611a8857604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16611ac1576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b60026000541415611b2f5760405162461bcd60e51b81526004016116b290615bb5565b6002600055611b3f601a84614725565b611b5c57604051636211d34960e01b815260040160405180910390fd5b601c546001600160a01b0383811691161415611b8a5760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038416906370a0823190611bb9903090600401615aac565b60206040518083038186803b158015611bd157600080fd5b505afa158015611be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c099190615a49565b9050611c206001600160a01b038416333085614f77565b600081846001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611c4f9190615aac565b60206040518083038186803b158015611c6757600080fd5b505afa158015611c7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9f9190615a49565b611ca99190615cb6565b9050600061271060245483611cbe9190615c47565b611cc89190615c33565b9050611cd48183615cb6565b6001600160a01b038088166000908152600e60209081526040808320938a1683529290529081208054909190611d0b908490615c1b565b90915550506001600160a01b0380871660009081526025602090815260408083208985168085529252909120429055600354611d48921683614ebe565b6001600160a01b0386166000908152601160205260409020611d6a9086614dff565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611dba91815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611e0b57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611eb05760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b602e54611f4657604051630262ab9b60e61b815260040160405180910390fd5b336000818152600c602052604090205460ff1615611f775760405163ad2fdf3b60e01b815260040160405180910390fd5b611f82601a82614725565b611f9e5760405162941a5760e11b815260040160405180910390fd5b611fa781614a84565b15612002576001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615de083398151915293611ff99390929091615c05565b60405180910390a25b601e546001600160a01b038381166000908152600d60209081526040808320601c548516845290915280822054905163435b21c160e01b8152600481019190915290928392839291169063435b21c19060240160606040518083038186803b15801561206d57600080fd5b505afa158015612081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a59190615a62565b92509250925060006120b5614de5565b905060006120c582848688614fb5565b6001600160a01b0387166000908152600f602052604090205490915081111561215f576120f186614c5a565b6001600160a01b038616600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615de08339815191529361213e9390929091615c05565b60405180910390a261214e614de5565b915061215c82848688614fb5565b90505b61216a868883614ce8565b6000602e55601c5460408051838152602081018590526001600160a01b038a8116938a821693911691600080516020615dc0833981519152910160405180910390a450505050505050565b6003546001600160a01b031633146121e0576040516354348f0360e01b815260040160405180910390fd5b6121eb602682615012565b61220857604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600090815260136020908152604080832080546001600160a01b031916905560148252808320805460ff19169055602b90915280822080546001600160701b031916815560010191909155517f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e569061228b908390615aac565b60405180910390a150565b6003546001600160a01b031633146122c1576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166122e85760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16156123225760405163546da66560e11b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b9061228b908390615aac565b6003546001600160a01b031633146123a0576040516354348f0360e01b815260040160405180910390fd5b60248190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d9060200161228b565b60006123df614de5565b602e556123ed600783614725565b15611443577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e5460405161242591815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b038316600090815260126020526040902061245a90615027565b811015612565576001600160a01b03831660009081526012602052604081206124839083615031565b9050612490602682614725565b156125525760006124a082611082565b90508060400151600014612550576001600160a01b03821660009081526014602052604081205460ff166124e15781602001516124dc90615d28565b6124e7565b81602001515b601e546001600160a01b03888116600090815260286020908152604080832089851684529091529081902054602254915163a0d2710760e01b815294955061254294929093169263a0d2710792610d33928791600401615bec565b61254c9086615c1b565b9450505b505b508061255d81615cf9565b915050612439565b50919050565b3360009081526005602052604090205460ff1661259b57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff166125d4576040516310cec38560e21b815260040160405180910390fd5b6125df838383614758565b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261261392909116908590600401615b1c565b602060405180830381600087803b15801561262d57600080fd5b505af192505050801561265d575060408051601f3d908101601f1916820190925261265a918101906159d2565b60015b61266657612668565b505b336001600160a01b0316836001600160a01b03167f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e84846040516126ad929190615b1c565b60405180910390a3505050565b6003546001600160a01b031633146126e5576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661270c5760405163d92e233d60e01b815260040160405180910390fd5b601e80546001600160a01b0319166001600160a01b0383161790556040517f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b09061228b908390615aac565b3360009081526005602052604090205460ff1661278757604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff166127c0576040516310cec38560e21b815260040160405180910390fd5b6127cb600782615012565b50601c546001600160a01b038083166000818152600d60209081526040808320949095168083529381528482205492825260188152848220848352905292909220546128199284929161503d565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610c8e601a614711565b60008061286a83612435565b6022546001600160a01b038516600090815260296020526040902054919250906128949042615cb6565b1015610d9357600081116128c0576001600160a01b0383166000908152600f60205260409020546128fa565b6001600160a01b038316600090815260106020908152604080832054600f909252909120546128f0908390615c47565b6128fa9190615c33565b9150612565565b6003546001600160a01b0316331461292c576040516354348f0360e01b815260040160405180910390fd5b60208181556040518281527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee2910161228b565b6001600160a01b03828116600090815260016020526040902054839116331461299b57604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156129ce5760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602c6020908152604080832080546001600160a01b0319169588169586179055602d825280832094835293905282902042905590517fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c90612a40908590615aac565b60405180910390a2505050565b6060610c8e6007614711565b6003546001600160a01b03163314612a84576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116612aab5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415612b0c576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015612b06573d6000803e3d6000fd5b50612b20565b612b206001600160a01b0384168284614ebe565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b03163314612b9a576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116612bc15760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1615612bfb5760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19166001179055517f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f9061228b908390615aac565b6001600160a01b038381166000908152600160205260409020548491163314612c8a57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b038216612cb15760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03808516600090815260186020908152604080832093871683529290522054612cf45760405163184c088160e21b815260040160405180910390fd5b6001600160a01b038085166000908152601760209081526040808320938716835292905220544211612d39576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff1615612d73576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b0380851660008181526018602090815260408083209488168084529482528083208054908490559383526017825280832085845290915281205590612dc0908483614ebe565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca792886284604051612e0f91815260200190565b60405180910390a45050505050565b60026000541415612e415760405162461bcd60e51b81526004016116b290615bb5565b60026000908155338152600c602052604090205460ff1615612e76576040516362e6201d60e01b815260040160405180910390fd5b612e81601a33614725565b15612e9f5760405163d7229c4360e01b815260040160405180910390fd5b601f54612eac9042615c1b565b3360009081526016602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81529091906370a0823190612ef7903090600401615aac565b60206040518083038186803b158015612f0f57600080fd5b505afa158015612f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f479190615a49565b9050612f5e6001600160a01b038416333085614f77565b6040516370a0823160e01b815281906001600160a01b038516906370a0823190612f8c903090600401615aac565b60206040518083038186803b158015612fa457600080fd5b505afa158015612fb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fdc9190615a49565b612fe69190615cb6565b336000908152601960209081526040808320805460ff19166001179055601582528083206001600160a01b0388168452909152812080549294508492909190613030908490615c1b565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b60205461308c9042615c1b565b3360008181526017602090815260408083206001600160a01b03881680855290835281842095909555928252600d815282822093825292909252812080548392906130d8908490615cb6565b90915550503360009081526018602090815260408083206001600160a01b038616845290915281208054839290613110908490615c1b565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b03163314613184576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff166131bd576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19169055517f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d0259061228b908390615aac565b6003546001600160a01b03163314613238576040516354348f0360e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f9061228b908390615aac565b6001600160a01b0381811660009081526001602052604090205482911633146132bf57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff16806132fe57506001600160a01b0382166000908152600c602052604090205460ff165b1561331c5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602c602052604090205481169083161461335957604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602d602090815260408083209386168352929052205461338b90603c90615c1b565b4210156133ab576040516356248e9760e01b815260040160405180910390fd5b6133b483614f19565b6133bd82614f19565b6001600160a01b03831660009081526011602052604081206133de90615027565b11156134c0576001600160a01b03831660009081526011602052604081206134069082615031565b6001600160a01b038086166000908152600e6020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613454908490615c1b565b90915550506001600160a01b038085166000818152600e6020908152604080832094861683529381528382208290559181526011909152206134969082615012565b506001600160a01b03831660009081526011602052604090206134b99082614dff565b50506133bd565b6001600160a01b03831660009081526012602052604081206134e190615027565b11156135c3576001600160a01b03831660009081526012602052604081206135099082615031565b6001600160a01b03808616600090815260286020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613557908490615c1b565b90915550506001600160a01b03808516600090815260286020908152604080832085851684528252808320839055928616825260129052206135999082614dff565b506001600160a01b03841660009081526012602052604090206135bc9082615012565b50506134c0565b6001600160a01b03808416600090815260106020526040808220549285168252812080549091906135f5908490615c1b565b90915550506001600160a01b038084166000908152601060209081526040808320839055600f90915280822054928516825281208054909190613639908490615c1b565b90915550506001600160a01b0383166000908152600f60209081526040808320839055602990915281205561366f601a84615012565b506001600160a01b03808416600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602d8352818420958816808552958352818420849055938352602c909152908190208054909216909155517f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f290612a40908690615aac565b6003546001600160a01b0316331461372d576040516354348f0360e01b815260040160405180910390fd5b60238190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb699060200161228b565b6003546001600160a01b0316331461378d576040516354348f0360e01b815260040160405180910390fd5b613798602682614dff565b6137b55760405163f25e6b9f60e01b815260040160405180910390fd5b806001600160a01b03166316f0115b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156137ee57600080fd5b505afa158015613802573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382691906157a3565b6001600160a01b038281166000908152601360205260409081902080546001600160a01b0319169383169384179055601e54905163696a437b60e01b815291169163696a437b9161387a9190600401615aac565b60206040518083038186803b15801561389257600080fd5b505afa1580156138a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ca91906159d2565b6001600160a01b0382166000908152601460205260409020805460ff19169115159190911790556138fa81611082565b6001600160a01b0382166000908152602b60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b161791909117815591810151600190920191909155517fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b9061228b908390615aac565b6003546001600160a01b031633146139b2576040516354348f0360e01b815260040160405180910390fd5b601f8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b439060200161228b565b3360009081526005602052604090205460ff16613a1757604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff16613a50576040516310cec38560e21b815260040160405180910390fd5b613a5c8484848461503d565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613a928486615c1b565b6040519081526020016115f5565b613aab601a82614725565b15613ac957604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526019602052604090205460ff1615613b0357604051632f3d320560e01b815260040160405180910390fd5b613b0e601a82614dff565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613b91576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116613bb85760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383161790556040517feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae2509061228b908390615aac565b6003546001600160a01b03163314613c2e576040516354348f0360e01b815260040160405180910390fd5b62015180811015613c5257604051633f384aad60e21b815260040160405180910390fd5b60228190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d99060200161228b565b60026000541415613caa5760405162461bcd60e51b81526004016116b290615bb5565b600260009081556001600160a01b03858116825260016020526040909120548591163314613ceb57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260256020908152604080832093881683529290522054613d1d90603c90615c1b565b4211613d3c57604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054831115613d825760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600c602052604090205460ff1615613dbc5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290529081208054859290613df3908490615cb6565b90915550613e0d90506001600160a01b0385168385614ebe565b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054613e5b576001600160a01b0385166000908152601160205260409020613e599085615012565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613eaa91815260200190565b60405180910390a450506001600055505050565b336000818152600c602052604090205460ff1615613eef5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1615613f29576040516362e6201d60e01b815260040160405180910390fd5b613f34601a82614725565b613f505760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290522054821115613f965760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290529081208054849290613fcd908490615cb6565b90915550613fe790506001600160a01b0385168484614ebe565b826001600160a01b0316816001600160a01b0316856001600160a01b0316600080516020615dc08339815191528561401d614de5565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b03163314614066576040516354348f0360e01b815260040160405180910390fd5b60218190556040518181527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e79060200161228b565b6003546001600160a01b031633146140c6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166140ed5760405163d92e233d60e01b815260040160405180910390fd5b6140f8600954614e76565b601c80546001600160a01b0319166001600160a01b0383161790556040517f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf9061228b908390615aac565b6003546001600160a01b0316331461416e576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff166141a757604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19169055517f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e9061228b908390615aac565b3360009081526005602052604090205460ff1661422757604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff16614260576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b03831660009081526011602052604090206142829083614725565b61429f57604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600e60209081526040808320938616835292905220548111156142e45760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261431892909116908590600401615b1c565b602060405180830381600087803b15801561433257600080fd5b505af1925050508015614362575060408051601f3d908101601f1916820190925261435f918101906159d2565b60015b61436b5761436d565b505b6001600160a01b038084166000908152600e60209081526040808320938616835292905290812080548392906143a4908490615cb6565b90915550506001600160a01b038084166000908152600e60209081526040808320938616835292905220546143f7576001600160a01b03831660009081526011602052604090206143f59083615012565b505b336001600160a01b0316836001600160a01b03167f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d31833310484846040516126ad929190615b1c565b3360009081526006602052604090205460ff1661446c57604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16156144a6576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b60006144fe614de5565b602e5561450c600787614725565b801561453d57506001600160a01b038087166000908152600d60209081526040808320938916835292905220548411155b801561456157506001600160a01b0386166000908152600a60205260409020548311155b801561459057506001600160a01b0386166000908152600b6020526040902054829061458d9042615cb6565b10155b156145d4577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e546040516145c891815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b03163314614608576040516354348f0360e01b815260040160405180910390fd5b614613601a83614725565b61463057604051636211d34960e01b815260040160405180910390fd5b61463982614f19565b6001600160a01b0382166000908152600f602052604081208054839290614661908490615c1b565b90915550506001600160a01b038216600081815260296020908152604080832054600f909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d1926146c1928252602082015260400190565b60405180910390a25050565b6000602254826146dd9190615d14565b610d939083615cb6565b6000602254831015612565576022546147008385615c47565b61470a9190615c33565b9050610d93565b6060600061471e83615193565b9392505050565b6001600160a01b0381166000908152600183016020526040812054151561471e565b6000610d93826022546023546151ef565b6002600054141561477b5760405162461bcd60e51b81526004016116b290615bb5565b600260009081556001600160a01b03841681526012602052604090206147a19083614725565b6147bd576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b038084166000908152602860209081526040808320938616835292905220548111156148035760405163435b562560e01b815260040160405180910390fd5b61480c8361529d565b600061481b610d838385614966565b6001600160a01b038516600090815260106020526040902054909150156148d1576001600160a01b038416600090815260106020908152604080832054600f9092529091205461486c908390615c47565b6148769190615c33565b6001600160a01b0385166000908152600f60205260408120805490919061489e908490615cb6565b90915550506001600160a01b038416600090815260106020526040812080548392906148cb908490615cb6565b90915550505b6001600160a01b03808516600090815260286020908152604080832093871683529290529081208054849290614908908490615cb6565b90915550506001600160a01b0380851660009081526028602090815260408083209387168352929052205461495b576001600160a01b03841660009081526012602052604090206149599084615012565b505b505060016000555050565b6001600160a01b0381166000908152602b602052604081206001015415610d93576001600160a01b03821660009081526014602052604081205460ff166149d8576001600160a01b0383166000908152602b60205260409020546149d390600160381b900460060b615d28565b6149fc565b6001600160a01b0383166000908152602b6020526040902054600160381b900460060b5b601e5460225460405163a0d2710760e01b81529293506001600160a01b039091169163a0d2710791614a349188918691600401615bec565b60206040518083038186803b158015614a4c57600080fd5b505afa158015614a60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7a9190615a49565b6000614a8f426146cd565b6001600160a01b038316600090815260296020526040902054101561144357614abf60225442610b9e9190615cb6565b6001600160a01b03831660009081526029602052604090205411614b3557614ae68261529d565b6001600160a01b038216600090815260106020908152604080832054600f90925290912055614b14426146cd565b6001600160a01b038316600090815260296020526040902055506001919050565b6022546001600160a01b038316600090815260296020526040902054614b5b9042615cb6565b10614bb757614b698261529d565b6001600160a01b038216600090815260106020908152604080832054600f83528184205560225460299092528220805491929091614ba8908490615c1b565b90915550600191506114439050565b614bc0426146cd565b6001600160a01b0383166000908152602a60205260409020541015611443576001600160a01b038216600090815260106020526040902054614c018361529d565b6001600160a01b038316600090815260106020908152604080832054600f909252909120548291614c3191615c47565b614c3b9190615c33565b6001600160a01b0384166000908152600f602052604090205550919050565b6001600160a01b038116600090815260296020526040902054614c9f90614c819042615cb6565b6001600160a01b0383166000908152601060205260409020546146e7565b6001600160a01b0382166000908152600f602052604081208054909190614cc7908490615c1b565b90915550506001600160a01b03166000908152602960205260409020429055565b6001600160a01b0383166000908152600f6020526040902054811115614d215760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602a60209081526040808320429055600f90915281208054839290614d56908490615cb6565b90915550506001600160a01b038083166000908152600d60209081526040808320601c5490941683529290529081208054839290614d95908490615c1b565b90915550506001600160a01b0382166000908152600a602052604081208054839290614dc2908490615c1b565b925050819055508060096000828254614ddb9190615c1b565b9091555050505050565b6000603f5a614df5906040615c47565b610c8e9190615c33565b600061471e836001600160a01b0384166152c2565b601c54604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c68906024015b600060405180830381600087803b158015614e5b57600080fd5b505af1158015614e6f573d6000803e3d6000fd5b5050505050565b8060096000828254614e889190615cb6565b9091555050601d5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401614e41565b614f148363a9059cbb60e01b8484604051602401614edd929190615b1c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152615311565b505050565b614f2281614a84565b50614f2c81614c5a565b6001600160a01b0381166000908152600f6020908152604080832054601090925290912054614f5b91906153e3565b6001600160a01b039091166000908152600f6020526040902055565b6040516001600160a01b0380851660248301528316604482015260648101829052614faf9085906323b872dd60e01b90608401614edd565b50505050565b6000808486602e54614fc79190615cb6565b614fd19190615c1b565b9050670de0b6b3a764000084612710614fea8685615c47565b614ff49190615c33565b614ffe9190615c47565b6150089190615c33565b9695505050505050565b600061471e836001600160a01b0384166153f9565b6000610d93825490565b600061471e83836154ec565b601c546001600160a01b03848116911614615115576003546001600160a01b038085169163a9059cbb91166150728486615c1b565b6040518363ffffffff1660e01b815260040161508f929190615b1c565b602060405180830381600087803b1580156150a957600080fd5b505af19250505080156150d9575060408051601f3d908101601f191682019092526150d6918101906159d2565b60015b615113573d808015615107576040519150601f19603f3d011682016040523d82523d6000602084013e61510c565b606091505b5050615115565b505b6001600160a01b038085166000908152600d602090815260408083209387168352929052908120805484929061514c908490615cb6565b90915550506001600160a01b03808516600090815260186020908152604080832093871683529290529081208054839290615188908490615cb6565b909155505050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156151e357602002820191906000526020600020905b8154815260200190600101908083116151cf575b50505050509050919050565b600080806000198587098587029250828110838203039150508060001415615229576000841161521e57600080fd5b50829004905061471e565b80841161523557600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6152a681615516565b6001600160a01b03909116600090815260106020526040902055565b600081815260018301602052604081205461530957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d93565b506000610d93565b6000615366826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166156599092919063ffffffff16565b805190915015614f14578080602001905181019061538491906159d2565b614f145760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016116b2565b60008183106153f2578161471e565b5090919050565b600081815260018301602052604081205480156154e257600061541d600183615cb6565b855490915060009061543190600190615cb6565b905081811461549657600086600001828154811061545157615451615d91565b906000526020600020015490508087600001848154811061547457615474615d91565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806154a7576154a7615d7b565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d93565b6000915050610d93565b600082600001828154811061550357615503615d91565b9060005260206000200154905092915050565b6000805b6001600160a01b038316600090815260126020526040902061553b90615027565b811015612565576001600160a01b03831660009081526012602052604081206155649083615031565b9050615571602682614725565b156156465761557f426146cd565b6001600160a01b0382166000908152602b602052604090206001015414615605576155a981611082565b6001600160a01b0382166000908152602b60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b16179190911781559101516001909101555b6001600160a01b0380851660009081526028602090815260408083209385168352929052205461563990610d839083614966565b6156439084615c1b565b92505b508061565181615cf9565b91505061551a565b6060610c7a848460008585843b6156b25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016116b2565b600080866001600160a01b031685876040516156ce9190615a90565b60006040518083038185875af1925050503d806000811461570b576040519150601f19603f3d011682016040523d82523d6000602084013e615710565b606091505b509150915061572082828661572b565b979650505050505050565b6060831561573a57508161471e565b82511561574a5782518084602001fd5b8160405162461bcd60e51b81526004016116b29190615b82565b8051801515811461144357600080fd5b8051600681900b811461144357600080fd5b60006020828403121561579857600080fd5b813561471e81615da7565b6000602082840312156157b557600080fd5b815161471e81615da7565b600080604083850312156157d357600080fd5b82356157de81615da7565b915060208301356157ee81615da7565b809150509250929050565b60008060006060848603121561580e57600080fd5b833561581981615da7565b9250602084013561582981615da7565b9150604084013561583981615da7565b809150509250925092565b60008060006060848603121561585957600080fd5b833561586481615da7565b9250602084013561587481615da7565b929592945050506040919091013590565b6000806000806080858703121561589b57600080fd5b84356158a681615da7565b935060208501356158b681615da7565b92506040850135915060608501356158cd81615da7565b939692955090935050565b600080600080608085870312156158ee57600080fd5b84356158f981615da7565b9350602085013561590981615da7565b93969395505050506040820135916060013590565b600080600080600060a0868803121561593657600080fd5b853561594181615da7565b9450602086013561595181615da7565b94979496505050506040830135926060810135926080909101359150565b6000806040838503121561598257600080fd5b823561598d81615da7565b946020939093013593505050565b6000806000606084860312156159b057600080fd5b83356159bb81615da7565b925060208401359150604084013561583981615da7565b6000602082840312156159e457600080fd5b61471e82615764565b600080600060608486031215615a0257600080fd5b615a0b84615774565b9250615a1960208501615774565b9150615a2760408501615764565b90509250925092565b600060208284031215615a4257600080fd5b5035919050565b600060208284031215615a5b57600080fd5b5051919050565b600080600060608486031215615a7757600080fd5b8351925060208401519150604084015190509250925092565b60008251615aa2818460208701615ccd565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615b0f57845163ffffffff1683529383019391830191600101615aed565b5090979650505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015615b765783516001600160a01b031683529284019291840191600101615b51565b50909695505050505050565b6020815260008251806020840152615ba1816040850160208701615ccd565b601f01601f19169190910160400192915050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b92835260069190910b6020830152604082015260600190565b9283526020830191909152604082015260600190565b60008219821115615c2e57615c2e615d4f565b500190565b600082615c4257615c42615d65565b500490565b6000816000190483118215151615615c6157615c61615d4f565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615c9157615c91615d4f565b81667fffffffffffff018313811615615cac57615cac615d4f565b5090039392505050565b600082821015615cc857615cc8615d4f565b500390565b60005b83811015615ce8578181015183820152602001615cd0565b83811115614faf5750506000910152565b6000600019821415615d0d57615d0d615d4f565b5060010190565b600082615d2357615d23615d65565b500690565b60008160060b667fffffffffffff19811415615d4657615d46615d4f565b60000392915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114615dbc57600080fd5b5056fe46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfaee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a2646970667358221220f7c882e8c48896d57ccb7e708bc5ded3a08e9dae708da84a8703db26482f042e64736f6c63430008070033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103e15760003560e01c8063951dc22c1161020d578063c7ae40d011610121578063c7ae40d0146109c3578063cb4be2bb146109d6578063cb54694d146109e9578063cd22af1b146109fc578063d55995fe14610a27578063dd2080d614610a3a578063ddca3f4314610a4d578063e326ac4314610a56578063ebbb619414610a76578063ec00cdfc14610a89578063ec8ca64314610a9c578063f0f346b914610ac5578063f11a1d1a14610ad8578063f136a09d14610aeb578063f25e311b14610b0b578063f263c47014610b1e578063f39c38a014610b27578063f75f9f7b14610b3a578063f9d46cf214610b4d578063fc253d2b14610b60578063fe75bc4614610b6957600080fd5b8063951dc22c146107d6578063966abd00146107de57806398e90a0f146107f15780639d5c33d81461081a578063a21458091461082d578063a39744b514610840578063a515366a1461086b578063a5d059ca1461087e578063a676f9ff14610891578063a7d2e784146108b1578063aac6aa9c146108ba578063ab033ea9146108cd578063af320e81146108e0578063b0103b1a146108f3578063b239223314610916578063b440027f14610929578063b600702a14610954578063b7e7734014610967578063b87fcbff1461097a578063c20297f01461099d578063c5198abc146109b057600080fd5b806359a2255e1161030457806359a2255e146106325780635aa6e675146106455780635ebe23f0146106585780635feeb79414610661578063633fb68f1461067457806364bb43ee1461067d57806368a9f19c14610690578063694798e6146106a357806369fe0e2d146106ce5780636ba42aaa146106e15780636cf262bc146106f45780636e2a9ca61461070757806372da828a1461071a57806374a8f1031461072d578063768b5d90146107405780637c8fce2314610749578063878c723e146107515780638bb6dfa81461077a5780638cb22b761461078d5780638fe204dd146107b057806390a4684e146107c357600080fd5b8063034d4c61146103e657806307b435c21461040c5780630c620bce146104375780630d6a1f871461044c5780631101eb411461045f57806311466d721461047457806315006b8214610487578063165e62e7146104b2578063168f92e7146104ef5780631b44555e1461051a5780631c5a9d9c1461053a5780631ef94b911461054d57806321040b011461056d578063238efcbc14610598578063274a8db4146105a057806351cff8d9146105d357806352a4de29146105e657806355ea6c47146105f9578063575288bf1461060c578063594a3a931461061f575b600080fd5b6103f96103f4366004615786565b610b7c565b6040519081526020015b60405180910390f35b6103f961041a3660046157c0565b601760209081526000928352604080842090915290825290205481565b61043f610c82565b6040516104039190615b35565b6103f961045a36600461596f565b610c93565b61047261046d366004615844565b610d99565b005b61047261048236600461596f565b610ef3565b6103f96104953660046157c0565b601560209081526000928352604080842090915290825290205481565b6104c56104c0366004615786565b611082565b604080518251600690810b825260208085015190910b908201529181015190820152606001610403565b6103f96104fd3660046157c0565b600e60209081526000928352604080842090915290825290205481565b6103f9610528366004615786565b600a6020526000908152604090205481565b610472610548366004615786565b611448565b601c54610560906001600160a01b031681565b6040516104039190615aac565b6103f961057b3660046157c0565b601860209081526000928352604080842090915290825290205481565b610472611603565b6105c36105ae366004615786565b60066020526000908152604090205460ff1681565b6040519015158152602001610403565b6104726105e1366004615786565b61168f565b6104726105f4366004615844565b611827565b610472610607366004615786565b611a58565b61047261061a366004615844565b611b0c565b61047261062d3660046157c0565b611dcf565b610472610640366004615786565b611e74565b600354610560906001600160a01b031681565b6103f9601f5481565b61047261066f366004615786565b611f26565b6103f960215481565b61047261068b366004615786565b6121b5565b61047261069e366004615786565b612296565b6103f96106b13660046157c0565b602860209081526000928352604080842090915290825290205481565b6104726106dc366004615a30565b612375565b6105c36106ef366004615786565b6123d5565b6103f9610702366004615786565b612435565b610472610715366004615844565b61256b565b610472610728366004615786565b6126ba565b61047261073b366004615786565b612757565b6103f960225481565b61043f612852565b61056061075f366004615786565b6001602052600090815260409020546001600160a01b031681565b6103f9610788366004615786565b61285e565b6105c361079b366004615786565b60196020526000908152604090205460ff1681565b6104726107be366004615a30565b612901565b6104726107d13660046157c0565b61295f565b61043f612a4d565b6104726107ec36600461599b565b612a59565b6105606107ff366004615786565b6002602052600090815260409020546001600160a01b031681565b610472610828366004615786565b612b6f565b61047261083b3660046157f9565b612c4e565b6103f961084e3660046157c0565b600d60209081526000928352604080842090915290825290205481565b61047261087936600461596f565b612e1e565b61047261088c36600461596f565b61307f565b6103f961089f366004615786565b60296020526000908152604090205481565b6103f960205481565b6104726108c8366004615786565b613159565b6104726108db366004615786565b61320d565b6104726108ee3660046157c0565b613283565b6105c3610901366004615786565b600c6020526000908152604090205460ff1681565b610472610924366004615a30565b613702565b6103f96109373660046157c0565b602560209081526000928352604080842090915290825290205481565b610472610962366004615786565b613762565b610472610975366004615a30565b613987565b6105c3610988366004615786565b60056020526000908152604090205460ff1681565b6104726109ab3660046158d8565b6139e7565b6104726109be366004615786565b613aa0565b601d54610560906001600160a01b031681565b6104726109e4366004615786565b613b66565b6104726109f7366004615a30565b613c03565b6103f9610a0a3660046157c0565b601660209081526000928352604080842090915290825290205481565b610472610a35366004615885565b613c87565b610472610a48366004615844565b613ebe565b6103f960245481565b6103f9610a64366004615786565b600b6020526000908152604090205481565b610472610a84366004615a30565b61403b565b610472610a97366004615786565b61409b565b610560610aaa366004615786565b602c602052600090815260409020546001600160a01b031681565b610472610ad3366004615786565b614143565b601e54610560906001600160a01b031681565b6103f9610af9366004615786565b602a6020526000908152604090205481565b610472610b19366004615844565b6141f7565b6103f960095481565b600454610560906001600160a01b031681565b610472610b48366004615786565b61443c565b6105c3610b5b36600461591e565b6144f4565b6103f960235481565b610472610b7736600461596f565b6145dd565b600080610b8883612435565b6022549091504290610ba390610b9e9083615cb6565b6146cd565b6001600160a01b0385166000908152602960205260409020541115610c47576022546001600160a01b038516600090815260296020526040902054610be89042615cb6565b10610c24576022546001600160a01b038516600090815260296020526040902054610c139190615c1b565b610c1d9082615cb6565b9050610c5d565b6001600160a01b038416600090815260296020526040902054610c1d9082615cb6565b610c50426146cd565b610c5a9082615cb6565b90505b610c6781836146e7565b610c708561285e565b610c7a9190615c1b565b949350505050565b6060610c8e6026614711565b905090565b6000610ca0602684614725565b15610d93576000610cb084611082565b90508060400151600014610d91576001600160a01b03841660009081526014602052604081205460ff16610cf1578160200151610cec90615d28565b610cf7565b81602001515b601e5460225460405163a0d2710760e01b8152929350610d88926001600160a01b039092169163a0d2710791610d339189918791600401615bec565b60206040518083038186803b158015610d4b57600080fd5b505afa158015610d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d839190615a49565b614747565b92505050610d93565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610dd557604051636efb4f4160e11b815260040160405180910390fd5b602054610de29042615c1b565b6001600160a01b03808616600081815260176020908152604080832094891680845294825280832095909555918152601882528381209281529190529081208054849290610e31908490615c1b565b90915550610e429050848484614758565b6001600160a01b038085166000908152602860209081526040808320938716835292905220548015801590610e815750602154610e7f8286614966565b105b15610e9f57604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de85604051610ee491815260200190565b60405180910390a35050505050565b336000818152600c602052604090205460ff1615610f245760405163ad2fdf3b60e01b815260040160405180910390fd5b610f2f601a82614725565b610f4b5760405162941a5760e11b815260040160405180910390fd5b610f5481614a84565b15610faf576001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615de083398151915293610fa69390929091615c05565b60405180910390a25b6001600160a01b0381166000908152600f602052604090205482111561102e57610fd881614c5a565b6001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615de0833981519152936110259390929091615c05565b60405180910390a25b611039818484614ce8565b601c546001600160a01b03808516918382169116600080516020615dc083398151915285611065614de5565b6040805192835260208301919091520160405180910390a4505050565b60408051606081018252600080825260208201819052918101919091526110a8426146cd565b6001600160a01b0383166000908152602b6020526040902060010154141561111e57506001600160a01b03166000908152602b602090815260409182902082516060810184528154600681810b810b810b8352600160381b909104810b810b900b92810192909252600101549181019190915290565b60008061113260225442610b9e9190615cb6565b6001600160a01b0385166000908152602b602052604090206001015490915081141561129657604080516001808252818301909252600091602080830190803683375050506001600160a01b0386166000908152602b602052604090205490915060060b61119f426146cd565b6111a99042615cb6565b826000815181106111bc576111bc615d91565b63ffffffff909216602092830291909101820152601e546001600160a01b038881166000908152601390935260409283902054925163dc686d9160e01b81529181169263dc686d91926112189291909116908690600401615ac0565b60606040518083038186803b15801561123057600080fd5b505afa158015611244573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126891906159ed565b600692830b90920b80885291955061128291839150615c66565b600690810b900b60208601525061141f9050565b6001600160a01b0384166000908152602b602052604090206001015481111561141f576040805160028082526060820183526000926020830190803683370190505090506112e3426146cd565b6112ed9042615cb6565b8160008151811061130057611300615d91565b602002602001019063ffffffff16908163ffffffff1681525050602254611326426146cd565b6113309042615cb6565b61133a9190615c1b565b8160018151811061134d5761134d615d91565b63ffffffff909216602092830291909101820152601e546001600160a01b0387811660009081526013909352604080842054905163dc686d9160e01b81529282169263dc686d91926113a59216908690600401615ac0565b60606040518083038186803b1580156113bd57600080fd5b505afa1580156113d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f591906159ed565b600692830b90920b8088529195509150611410908290615c66565b600690810b900b602086015250505b81156114385761142e426146cd565b6040840152611440565b600060408401525b50505b919050565b336000818152600c602052604090205460ff1615611479576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b03808216600090815260166020908152604080832093861683529290522054806114bd57604051636258f48160e01b815260040160405180910390fd5b4281106114dd57604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600b6020526040902054611516576001600160a01b0382166000908152600b602052604090204290555b611521600783614dff565b506001600160a01b038083166000818152601560209081526040808320948816808452948252808320805490849055938352600d8252808320948352939052918220805491928392611574908490615c1b565b9091555050601c546001600160a01b03858116911614156115b05780600960008282546115a19190615c1b565b909155506115b0905081614e14565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a75836040516115f591815260200190565b60405180910390a350505050565b6004546001600160a01b0316331461162e57604051637ef5703160e11b815260040160405180910390fd5b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161168591615aac565b60405180910390a1565b600260005414156116bb5760405162461bcd60e51b81526004016116b290615bb5565b60405180910390fd5b600260009081553381526018602090815260408083206001600160a01b03851684529091529020546117005760405163184c088160e21b815260040160405180910390fd5b3360009081526017602090815260408083206001600160a01b03851684529091529020544211611743576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600c602052604090205460ff1615611774576040516362e6201d60e01b815260040160405180910390fd5b3360008181526018602090815260408083206001600160a01b038681168086529184528285208054908690559585526017845282852082865290935290832092909255601c541614156117ca576117ca81614e76565b6117de6001600160a01b0383163383614ebe565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b6002600054141561184a5760405162461bcd60e51b81526004016116b290615bb5565b600260005561185a602683614725565b6118775760405163e0b6aead60e01b815260040160405180910390fd5b611882601a84614725565b61189f57604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526012602052604090206118c19083614dff565b506118cb83614f19565b6021546001600160a01b0380851660009081526028602090815260408083209387168352929052205461190990611903908490615c1b565b84614966565b101561192857604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615de0833981519152936119759390929091615c05565b60405180910390a26119926001600160a01b038316333084614f77565b6001600160a01b038084166000908152602860209081526040808320938616835292905290812080548392906119c9908490615c1b565b909155506119dc9050610d838284614966565b6001600160a01b03841660009081526010602052604081208054909190611a04908490615c1b565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff16611a8857604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16611ac1576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b60026000541415611b2f5760405162461bcd60e51b81526004016116b290615bb5565b6002600055611b3f601a84614725565b611b5c57604051636211d34960e01b815260040160405180910390fd5b601c546001600160a01b0383811691161415611b8a5760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038416906370a0823190611bb9903090600401615aac565b60206040518083038186803b158015611bd157600080fd5b505afa158015611be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c099190615a49565b9050611c206001600160a01b038416333085614f77565b600081846001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611c4f9190615aac565b60206040518083038186803b158015611c6757600080fd5b505afa158015611c7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9f9190615a49565b611ca99190615cb6565b9050600061271060245483611cbe9190615c47565b611cc89190615c33565b9050611cd48183615cb6565b6001600160a01b038088166000908152600e60209081526040808320938a1683529290529081208054909190611d0b908490615c1b565b90915550506001600160a01b0380871660009081526025602090815260408083208985168085529252909120429055600354611d48921683614ebe565b6001600160a01b0386166000908152601160205260409020611d6a9086614dff565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611dba91815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611e0b57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611eb05760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b602e54611f4657604051630262ab9b60e61b815260040160405180910390fd5b336000818152600c602052604090205460ff1615611f775760405163ad2fdf3b60e01b815260040160405180910390fd5b611f82601a82614725565b611f9e5760405162941a5760e11b815260040160405180910390fd5b611fa781614a84565b15612002576001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615de083398151915293611ff99390929091615c05565b60405180910390a25b601e546001600160a01b038381166000908152600d60209081526040808320601c548516845290915280822054905163435b21c160e01b8152600481019190915290928392839291169063435b21c19060240160606040518083038186803b15801561206d57600080fd5b505afa158015612081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a59190615a62565b92509250925060006120b5614de5565b905060006120c582848688614fb5565b6001600160a01b0387166000908152600f602052604090205490915081111561215f576120f186614c5a565b6001600160a01b038616600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615de08339815191529361213e9390929091615c05565b60405180910390a261214e614de5565b915061215c82848688614fb5565b90505b61216a868883614ce8565b6000602e55601c5460408051838152602081018590526001600160a01b038a8116938a821693911691600080516020615dc0833981519152910160405180910390a450505050505050565b6003546001600160a01b031633146121e0576040516354348f0360e01b815260040160405180910390fd5b6121eb602682615012565b61220857604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600090815260136020908152604080832080546001600160a01b031916905560148252808320805460ff19169055602b90915280822080546001600160701b031916815560010191909155517f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e569061228b908390615aac565b60405180910390a150565b6003546001600160a01b031633146122c1576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166122e85760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16156123225760405163546da66560e11b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b9061228b908390615aac565b6003546001600160a01b031633146123a0576040516354348f0360e01b815260040160405180910390fd5b60248190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d9060200161228b565b60006123df614de5565b602e556123ed600783614725565b15611443577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e5460405161242591815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b038316600090815260126020526040902061245a90615027565b811015612565576001600160a01b03831660009081526012602052604081206124839083615031565b9050612490602682614725565b156125525760006124a082611082565b90508060400151600014612550576001600160a01b03821660009081526014602052604081205460ff166124e15781602001516124dc90615d28565b6124e7565b81602001515b601e546001600160a01b03888116600090815260286020908152604080832089851684529091529081902054602254915163a0d2710760e01b815294955061254294929093169263a0d2710792610d33928791600401615bec565b61254c9086615c1b565b9450505b505b508061255d81615cf9565b915050612439565b50919050565b3360009081526005602052604090205460ff1661259b57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff166125d4576040516310cec38560e21b815260040160405180910390fd5b6125df838383614758565b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261261392909116908590600401615b1c565b602060405180830381600087803b15801561262d57600080fd5b505af192505050801561265d575060408051601f3d908101601f1916820190925261265a918101906159d2565b60015b61266657612668565b505b336001600160a01b0316836001600160a01b03167f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e84846040516126ad929190615b1c565b60405180910390a3505050565b6003546001600160a01b031633146126e5576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661270c5760405163d92e233d60e01b815260040160405180910390fd5b601e80546001600160a01b0319166001600160a01b0383161790556040517f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b09061228b908390615aac565b3360009081526005602052604090205460ff1661278757604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff166127c0576040516310cec38560e21b815260040160405180910390fd5b6127cb600782615012565b50601c546001600160a01b038083166000818152600d60209081526040808320949095168083529381528482205492825260188152848220848352905292909220546128199284929161503d565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610c8e601a614711565b60008061286a83612435565b6022546001600160a01b038516600090815260296020526040902054919250906128949042615cb6565b1015610d9357600081116128c0576001600160a01b0383166000908152600f60205260409020546128fa565b6001600160a01b038316600090815260106020908152604080832054600f909252909120546128f0908390615c47565b6128fa9190615c33565b9150612565565b6003546001600160a01b0316331461292c576040516354348f0360e01b815260040160405180910390fd5b60208181556040518281527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee2910161228b565b6001600160a01b03828116600090815260016020526040902054839116331461299b57604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156129ce5760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602c6020908152604080832080546001600160a01b0319169588169586179055602d825280832094835293905282902042905590517fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c90612a40908590615aac565b60405180910390a2505050565b6060610c8e6007614711565b6003546001600160a01b03163314612a84576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116612aab5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415612b0c576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015612b06573d6000803e3d6000fd5b50612b20565b612b206001600160a01b0384168284614ebe565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b03163314612b9a576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116612bc15760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1615612bfb5760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19166001179055517f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f9061228b908390615aac565b6001600160a01b038381166000908152600160205260409020548491163314612c8a57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b038216612cb15760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03808516600090815260186020908152604080832093871683529290522054612cf45760405163184c088160e21b815260040160405180910390fd5b6001600160a01b038085166000908152601760209081526040808320938716835292905220544211612d39576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff1615612d73576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b0380851660008181526018602090815260408083209488168084529482528083208054908490559383526017825280832085845290915281205590612dc0908483614ebe565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca792886284604051612e0f91815260200190565b60405180910390a45050505050565b60026000541415612e415760405162461bcd60e51b81526004016116b290615bb5565b60026000908155338152600c602052604090205460ff1615612e76576040516362e6201d60e01b815260040160405180910390fd5b612e81601a33614725565b15612e9f5760405163d7229c4360e01b815260040160405180910390fd5b601f54612eac9042615c1b565b3360009081526016602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81529091906370a0823190612ef7903090600401615aac565b60206040518083038186803b158015612f0f57600080fd5b505afa158015612f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f479190615a49565b9050612f5e6001600160a01b038416333085614f77565b6040516370a0823160e01b815281906001600160a01b038516906370a0823190612f8c903090600401615aac565b60206040518083038186803b158015612fa457600080fd5b505afa158015612fb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fdc9190615a49565b612fe69190615cb6565b336000908152601960209081526040808320805460ff19166001179055601582528083206001600160a01b0388168452909152812080549294508492909190613030908490615c1b565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b60205461308c9042615c1b565b3360008181526017602090815260408083206001600160a01b03881680855290835281842095909555928252600d815282822093825292909252812080548392906130d8908490615cb6565b90915550503360009081526018602090815260408083206001600160a01b038616845290915281208054839290613110908490615c1b565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b03163314613184576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff166131bd576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19169055517f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d0259061228b908390615aac565b6003546001600160a01b03163314613238576040516354348f0360e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f9061228b908390615aac565b6001600160a01b0381811660009081526001602052604090205482911633146132bf57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff16806132fe57506001600160a01b0382166000908152600c602052604090205460ff165b1561331c5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602c602052604090205481169083161461335957604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602d602090815260408083209386168352929052205461338b90603c90615c1b565b4210156133ab576040516356248e9760e01b815260040160405180910390fd5b6133b483614f19565b6133bd82614f19565b6001600160a01b03831660009081526011602052604081206133de90615027565b11156134c0576001600160a01b03831660009081526011602052604081206134069082615031565b6001600160a01b038086166000908152600e6020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613454908490615c1b565b90915550506001600160a01b038085166000818152600e6020908152604080832094861683529381528382208290559181526011909152206134969082615012565b506001600160a01b03831660009081526011602052604090206134b99082614dff565b50506133bd565b6001600160a01b03831660009081526012602052604081206134e190615027565b11156135c3576001600160a01b03831660009081526012602052604081206135099082615031565b6001600160a01b03808616600090815260286020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613557908490615c1b565b90915550506001600160a01b03808516600090815260286020908152604080832085851684528252808320839055928616825260129052206135999082614dff565b506001600160a01b03841660009081526012602052604090206135bc9082615012565b50506134c0565b6001600160a01b03808416600090815260106020526040808220549285168252812080549091906135f5908490615c1b565b90915550506001600160a01b038084166000908152601060209081526040808320839055600f90915280822054928516825281208054909190613639908490615c1b565b90915550506001600160a01b0383166000908152600f60209081526040808320839055602990915281205561366f601a84615012565b506001600160a01b03808416600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602d8352818420958816808552958352818420849055938352602c909152908190208054909216909155517f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f290612a40908690615aac565b6003546001600160a01b0316331461372d576040516354348f0360e01b815260040160405180910390fd5b60238190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb699060200161228b565b6003546001600160a01b0316331461378d576040516354348f0360e01b815260040160405180910390fd5b613798602682614dff565b6137b55760405163f25e6b9f60e01b815260040160405180910390fd5b806001600160a01b03166316f0115b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156137ee57600080fd5b505afa158015613802573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382691906157a3565b6001600160a01b038281166000908152601360205260409081902080546001600160a01b0319169383169384179055601e54905163696a437b60e01b815291169163696a437b9161387a9190600401615aac565b60206040518083038186803b15801561389257600080fd5b505afa1580156138a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ca91906159d2565b6001600160a01b0382166000908152601460205260409020805460ff19169115159190911790556138fa81611082565b6001600160a01b0382166000908152602b60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b161791909117815591810151600190920191909155517fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b9061228b908390615aac565b6003546001600160a01b031633146139b2576040516354348f0360e01b815260040160405180910390fd5b601f8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b439060200161228b565b3360009081526005602052604090205460ff16613a1757604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff16613a50576040516310cec38560e21b815260040160405180910390fd5b613a5c8484848461503d565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613a928486615c1b565b6040519081526020016115f5565b613aab601a82614725565b15613ac957604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526019602052604090205460ff1615613b0357604051632f3d320560e01b815260040160405180910390fd5b613b0e601a82614dff565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613b91576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116613bb85760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383161790556040517feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae2509061228b908390615aac565b6003546001600160a01b03163314613c2e576040516354348f0360e01b815260040160405180910390fd5b62015180811015613c5257604051633f384aad60e21b815260040160405180910390fd5b60228190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d99060200161228b565b60026000541415613caa5760405162461bcd60e51b81526004016116b290615bb5565b600260009081556001600160a01b03858116825260016020526040909120548591163314613ceb57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260256020908152604080832093881683529290522054613d1d90603c90615c1b565b4211613d3c57604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054831115613d825760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600c602052604090205460ff1615613dbc5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290529081208054859290613df3908490615cb6565b90915550613e0d90506001600160a01b0385168385614ebe565b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054613e5b576001600160a01b0385166000908152601160205260409020613e599085615012565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613eaa91815260200190565b60405180910390a450506001600055505050565b336000818152600c602052604090205460ff1615613eef5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1615613f29576040516362e6201d60e01b815260040160405180910390fd5b613f34601a82614725565b613f505760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290522054821115613f965760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290529081208054849290613fcd908490615cb6565b90915550613fe790506001600160a01b0385168484614ebe565b826001600160a01b0316816001600160a01b0316856001600160a01b0316600080516020615dc08339815191528561401d614de5565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b03163314614066576040516354348f0360e01b815260040160405180910390fd5b60218190556040518181527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e79060200161228b565b6003546001600160a01b031633146140c6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166140ed5760405163d92e233d60e01b815260040160405180910390fd5b6140f8600954614e76565b601c80546001600160a01b0319166001600160a01b0383161790556040517f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf9061228b908390615aac565b6003546001600160a01b0316331461416e576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff166141a757604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19169055517f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e9061228b908390615aac565b3360009081526005602052604090205460ff1661422757604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff16614260576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b03831660009081526011602052604090206142829083614725565b61429f57604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600e60209081526040808320938616835292905220548111156142e45760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261431892909116908590600401615b1c565b602060405180830381600087803b15801561433257600080fd5b505af1925050508015614362575060408051601f3d908101601f1916820190925261435f918101906159d2565b60015b61436b5761436d565b505b6001600160a01b038084166000908152600e60209081526040808320938616835292905290812080548392906143a4908490615cb6565b90915550506001600160a01b038084166000908152600e60209081526040808320938616835292905220546143f7576001600160a01b03831660009081526011602052604090206143f59083615012565b505b336001600160a01b0316836001600160a01b03167f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d31833310484846040516126ad929190615b1c565b3360009081526006602052604090205460ff1661446c57604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16156144a6576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b60006144fe614de5565b602e5561450c600787614725565b801561453d57506001600160a01b038087166000908152600d60209081526040808320938916835292905220548411155b801561456157506001600160a01b0386166000908152600a60205260409020548311155b801561459057506001600160a01b0386166000908152600b6020526040902054829061458d9042615cb6565b10155b156145d4577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e546040516145c891815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b03163314614608576040516354348f0360e01b815260040160405180910390fd5b614613601a83614725565b61463057604051636211d34960e01b815260040160405180910390fd5b61463982614f19565b6001600160a01b0382166000908152600f602052604081208054839290614661908490615c1b565b90915550506001600160a01b038216600081815260296020908152604080832054600f909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d1926146c1928252602082015260400190565b60405180910390a25050565b6000602254826146dd9190615d14565b610d939083615cb6565b6000602254831015612565576022546147008385615c47565b61470a9190615c33565b9050610d93565b6060600061471e83615193565b9392505050565b6001600160a01b0381166000908152600183016020526040812054151561471e565b6000610d93826022546023546151ef565b6002600054141561477b5760405162461bcd60e51b81526004016116b290615bb5565b600260009081556001600160a01b03841681526012602052604090206147a19083614725565b6147bd576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b038084166000908152602860209081526040808320938616835292905220548111156148035760405163435b562560e01b815260040160405180910390fd5b61480c8361529d565b600061481b610d838385614966565b6001600160a01b038516600090815260106020526040902054909150156148d1576001600160a01b038416600090815260106020908152604080832054600f9092529091205461486c908390615c47565b6148769190615c33565b6001600160a01b0385166000908152600f60205260408120805490919061489e908490615cb6565b90915550506001600160a01b038416600090815260106020526040812080548392906148cb908490615cb6565b90915550505b6001600160a01b03808516600090815260286020908152604080832093871683529290529081208054849290614908908490615cb6565b90915550506001600160a01b0380851660009081526028602090815260408083209387168352929052205461495b576001600160a01b03841660009081526012602052604090206149599084615012565b505b505060016000555050565b6001600160a01b0381166000908152602b602052604081206001015415610d93576001600160a01b03821660009081526014602052604081205460ff166149d8576001600160a01b0383166000908152602b60205260409020546149d390600160381b900460060b615d28565b6149fc565b6001600160a01b0383166000908152602b6020526040902054600160381b900460060b5b601e5460225460405163a0d2710760e01b81529293506001600160a01b039091169163a0d2710791614a349188918691600401615bec565b60206040518083038186803b158015614a4c57600080fd5b505afa158015614a60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7a9190615a49565b6000614a8f426146cd565b6001600160a01b038316600090815260296020526040902054101561144357614abf60225442610b9e9190615cb6565b6001600160a01b03831660009081526029602052604090205411614b3557614ae68261529d565b6001600160a01b038216600090815260106020908152604080832054600f90925290912055614b14426146cd565b6001600160a01b038316600090815260296020526040902055506001919050565b6022546001600160a01b038316600090815260296020526040902054614b5b9042615cb6565b10614bb757614b698261529d565b6001600160a01b038216600090815260106020908152604080832054600f83528184205560225460299092528220805491929091614ba8908490615c1b565b90915550600191506114439050565b614bc0426146cd565b6001600160a01b0383166000908152602a60205260409020541015611443576001600160a01b038216600090815260106020526040902054614c018361529d565b6001600160a01b038316600090815260106020908152604080832054600f909252909120548291614c3191615c47565b614c3b9190615c33565b6001600160a01b0384166000908152600f602052604090205550919050565b6001600160a01b038116600090815260296020526040902054614c9f90614c819042615cb6565b6001600160a01b0383166000908152601060205260409020546146e7565b6001600160a01b0382166000908152600f602052604081208054909190614cc7908490615c1b565b90915550506001600160a01b03166000908152602960205260409020429055565b6001600160a01b0383166000908152600f6020526040902054811115614d215760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602a60209081526040808320429055600f90915281208054839290614d56908490615cb6565b90915550506001600160a01b038083166000908152600d60209081526040808320601c5490941683529290529081208054839290614d95908490615c1b565b90915550506001600160a01b0382166000908152600a602052604081208054839290614dc2908490615c1b565b925050819055508060096000828254614ddb9190615c1b565b9091555050505050565b6000603f5a614df5906040615c47565b610c8e9190615c33565b600061471e836001600160a01b0384166152c2565b601c54604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c68906024015b600060405180830381600087803b158015614e5b57600080fd5b505af1158015614e6f573d6000803e3d6000fd5b5050505050565b8060096000828254614e889190615cb6565b9091555050601d5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401614e41565b614f148363a9059cbb60e01b8484604051602401614edd929190615b1c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152615311565b505050565b614f2281614a84565b50614f2c81614c5a565b6001600160a01b0381166000908152600f6020908152604080832054601090925290912054614f5b91906153e3565b6001600160a01b039091166000908152600f6020526040902055565b6040516001600160a01b0380851660248301528316604482015260648101829052614faf9085906323b872dd60e01b90608401614edd565b50505050565b6000808486602e54614fc79190615cb6565b614fd19190615c1b565b9050670de0b6b3a764000084612710614fea8685615c47565b614ff49190615c33565b614ffe9190615c47565b6150089190615c33565b9695505050505050565b600061471e836001600160a01b0384166153f9565b6000610d93825490565b600061471e83836154ec565b601c546001600160a01b03848116911614615115576003546001600160a01b038085169163a9059cbb91166150728486615c1b565b6040518363ffffffff1660e01b815260040161508f929190615b1c565b602060405180830381600087803b1580156150a957600080fd5b505af19250505080156150d9575060408051601f3d908101601f191682019092526150d6918101906159d2565b60015b615113573d808015615107576040519150601f19603f3d011682016040523d82523d6000602084013e61510c565b606091505b5050615115565b505b6001600160a01b038085166000908152600d602090815260408083209387168352929052908120805484929061514c908490615cb6565b90915550506001600160a01b03808516600090815260186020908152604080832093871683529290529081208054839290615188908490615cb6565b909155505050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156151e357602002820191906000526020600020905b8154815260200190600101908083116151cf575b50505050509050919050565b600080806000198587098587029250828110838203039150508060001415615229576000841161521e57600080fd5b50829004905061471e565b80841161523557600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6152a681615516565b6001600160a01b03909116600090815260106020526040902055565b600081815260018301602052604081205461530957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d93565b506000610d93565b6000615366826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166156599092919063ffffffff16565b805190915015614f14578080602001905181019061538491906159d2565b614f145760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016116b2565b60008183106153f2578161471e565b5090919050565b600081815260018301602052604081205480156154e257600061541d600183615cb6565b855490915060009061543190600190615cb6565b905081811461549657600086600001828154811061545157615451615d91565b906000526020600020015490508087600001848154811061547457615474615d91565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806154a7576154a7615d7b565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d93565b6000915050610d93565b600082600001828154811061550357615503615d91565b9060005260206000200154905092915050565b6000805b6001600160a01b038316600090815260126020526040902061553b90615027565b811015612565576001600160a01b03831660009081526012602052604081206155649083615031565b9050615571602682614725565b156156465761557f426146cd565b6001600160a01b0382166000908152602b602052604090206001015414615605576155a981611082565b6001600160a01b0382166000908152602b60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b16179190911781559101516001909101555b6001600160a01b0380851660009081526028602090815260408083209385168352929052205461563990610d839083614966565b6156439084615c1b565b92505b508061565181615cf9565b91505061551a565b6060610c7a848460008585843b6156b25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016116b2565b600080866001600160a01b031685876040516156ce9190615a90565b60006040518083038185875af1925050503d806000811461570b576040519150601f19603f3d011682016040523d82523d6000602084013e615710565b606091505b509150915061572082828661572b565b979650505050505050565b6060831561573a57508161471e565b82511561574a5782518084602001fd5b8160405162461bcd60e51b81526004016116b29190615b82565b8051801515811461144357600080fd5b8051600681900b811461144357600080fd5b60006020828403121561579857600080fd5b813561471e81615da7565b6000602082840312156157b557600080fd5b815161471e81615da7565b600080604083850312156157d357600080fd5b82356157de81615da7565b915060208301356157ee81615da7565b809150509250929050565b60008060006060848603121561580e57600080fd5b833561581981615da7565b9250602084013561582981615da7565b9150604084013561583981615da7565b809150509250925092565b60008060006060848603121561585957600080fd5b833561586481615da7565b9250602084013561587481615da7565b929592945050506040919091013590565b6000806000806080858703121561589b57600080fd5b84356158a681615da7565b935060208501356158b681615da7565b92506040850135915060608501356158cd81615da7565b939692955090935050565b600080600080608085870312156158ee57600080fd5b84356158f981615da7565b9350602085013561590981615da7565b93969395505050506040820135916060013590565b600080600080600060a0868803121561593657600080fd5b853561594181615da7565b9450602086013561595181615da7565b94979496505050506040830135926060810135926080909101359150565b6000806040838503121561598257600080fd5b823561598d81615da7565b946020939093013593505050565b6000806000606084860312156159b057600080fd5b83356159bb81615da7565b925060208401359150604084013561583981615da7565b6000602082840312156159e457600080fd5b61471e82615764565b600080600060608486031215615a0257600080fd5b615a0b84615774565b9250615a1960208501615774565b9150615a2760408501615764565b90509250925092565b600060208284031215615a4257600080fd5b5035919050565b600060208284031215615a5b57600080fd5b5051919050565b600080600060608486031215615a7757600080fd5b8351925060208401519150604084015190509250925092565b60008251615aa2818460208701615ccd565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615b0f57845163ffffffff1683529383019391830191600101615aed565b5090979650505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015615b765783516001600160a01b031683529284019291840191600101615b51565b50909695505050505050565b6020815260008251806020840152615ba1816040850160208701615ccd565b601f01601f19169190910160400192915050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b92835260069190910b6020830152604082015260600190565b9283526020830191909152604082015260600190565b60008219821115615c2e57615c2e615d4f565b500190565b600082615c4257615c42615d65565b500490565b6000816000190483118215151615615c6157615c61615d4f565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615c9157615c91615d4f565b81667fffffffffffff018313811615615cac57615cac615d4f565b5090039392505050565b600082821015615cc857615cc8615d4f565b500390565b60005b83811015615ce8578181015183820152602001615cd0565b83811115614faf5750506000910152565b6000600019821415615d0d57615d0d615d4f565b5060010190565b600082615d2357615d23615d65565b500690565b60008160060b667fffffffffffff19811415615d4657615d46615d4f565b60000392915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114615dbc57600080fd5b5056fe46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfaee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a2646970667358221220f7c882e8c48896d57ccb7e708bc5ded3a08e9dae708da84a8703db26482f042e64736f6c63430008070033", "devdoc": { "kind": "dev", "methods": { @@ -3395,6 +3408,9 @@ "slashers(address)": { "notice": "Tracks whether the address is a slasher or not" }, + "totalBonds()": { + "notice": "Tracks the total amount of bonded KP3Rs in the contract" + }, "totalJobCredits(address)": { "notice": "Calculates the total credits of a given job" }, @@ -3439,7 +3455,7 @@ "type": "t_uint256" }, { - "astId": 8417, + "astId": 8431, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "jobOwner", "offset": 0, @@ -3447,7 +3463,7 @@ "type": "t_mapping(t_address,t_address)" }, { - "astId": 8423, + "astId": 8437, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "jobPendingOwner", "offset": 0, @@ -3455,7 +3471,7 @@ "type": "t_mapping(t_address,t_address)" }, { - "astId": 5374, + "astId": 5362, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "governance", "offset": 0, @@ -3463,7 +3479,7 @@ "type": "t_address" }, { - "astId": 5378, + "astId": 5366, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "pendingGovernance", "offset": 0, @@ -3471,7 +3487,7 @@ "type": "t_address" }, { - "astId": 5985, + "astId": 5999, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "slashers", "offset": 0, @@ -3479,7 +3495,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 5991, + "astId": 6005, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "disputers", "offset": 0, @@ -3487,7 +3503,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 5479, + "astId": 5467, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_keepers", "offset": 0, @@ -3495,283 +3511,291 @@ "type": "t_struct(AddressSet)1631_storage" }, { - "astId": 5485, + "astId": 5471, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", - "label": "workCompleted", + "label": "totalBonds", "offset": 0, "slot": "9", + "type": "t_uint256" + }, + { + "astId": 5477, + "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", + "label": "workCompleted", + "offset": 0, + "slot": "10", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 5491, + "astId": 5483, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "firstSeen", "offset": 0, - "slot": "10", + "slot": "11", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 5497, + "astId": 5489, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "disputes", "offset": 0, - "slot": "11", + "slot": "12", "type": "t_mapping(t_address,t_bool)" }, { - "astId": 5505, + "astId": 5497, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "bonds", "offset": 0, - "slot": "12", + "slot": "13", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5513, + "astId": 5505, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "jobTokenCredits", "offset": 0, - "slot": "13", + "slot": "14", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5518, + "astId": 5510, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_jobLiquidityCredits", "offset": 0, - "slot": "14", + "slot": "15", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 5523, + "astId": 5515, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_jobPeriodCredits", "offset": 0, - "slot": "15", + "slot": "16", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 5529, + "astId": 5521, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_jobTokens", "offset": 0, - "slot": "16", + "slot": "17", "type": "t_mapping(t_address,t_struct(AddressSet)1631_storage)" }, { - "astId": 5535, + "astId": 5527, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_jobLiquidities", "offset": 0, - "slot": "17", + "slot": "18", "type": "t_mapping(t_address,t_struct(AddressSet)1631_storage)" }, { - "astId": 5540, + "astId": 5532, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_liquidityPool", "offset": 0, - "slot": "18", + "slot": "19", "type": "t_mapping(t_address,t_address)" }, { - "astId": 5545, + "astId": 5537, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_isKP3RToken0", "offset": 0, - "slot": "19", + "slot": "20", "type": "t_mapping(t_address,t_bool)" }, { - "astId": 5553, + "astId": 5545, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "pendingBonds", "offset": 0, - "slot": "20", + "slot": "21", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5561, + "astId": 5553, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "canActivateAfter", "offset": 0, - "slot": "21", + "slot": "22", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5569, + "astId": 5561, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "canWithdrawAfter", "offset": 0, - "slot": "22", + "slot": "23", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5577, + "astId": 5569, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "pendingUnbonds", "offset": 0, - "slot": "23", + "slot": "24", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5583, + "astId": 5575, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "hasBonded", "offset": 0, - "slot": "24", + "slot": "25", "type": "t_mapping(t_address,t_bool)" }, { - "astId": 5587, + "astId": 5579, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_jobs", "offset": 0, - "slot": "25", + "slot": "26", "type": "t_struct(AddressSet)1631_storage" }, { - "astId": 5699, + "astId": 5692, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "keep3rV1", "offset": 0, - "slot": "27", + "slot": "28", "type": "t_address" }, { - "astId": 5703, + "astId": 5696, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "keep3rV1Proxy", "offset": 0, - "slot": "28", + "slot": "29", "type": "t_address" }, { - "astId": 5707, + "astId": 5700, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "keep3rHelper", "offset": 0, - "slot": "29", + "slot": "30", "type": "t_address" }, { - "astId": 5712, + "astId": 5705, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "bondTime", "offset": 0, - "slot": "30", + "slot": "31", "type": "t_uint256" }, { - "astId": 5717, + "astId": 5710, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "unbondTime", "offset": 0, - "slot": "31", + "slot": "32", "type": "t_uint256" }, { - "astId": 5722, + "astId": 5715, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "liquidityMinimum", "offset": 0, - "slot": "32", + "slot": "33", "type": "t_uint256" }, { - "astId": 5727, + "astId": 5720, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "rewardPeriodTime", "offset": 0, - "slot": "33", + "slot": "34", "type": "t_uint256" }, { - "astId": 5732, + "astId": 5725, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "inflationPeriod", "offset": 0, - "slot": "34", + "slot": "35", "type": "t_uint256" }, { - "astId": 5737, + "astId": 5730, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "fee", "offset": 0, - "slot": "35", + "slot": "36", "type": "t_uint256" }, { - "astId": 6418, + "astId": 6432, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "jobTokenCreditsAddedAt", "offset": 0, - "slot": "36", + "slot": "37", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 6661, + "astId": 6675, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_approvedLiquidities", "offset": 0, - "slot": "37", + "slot": "38", "type": "t_struct(AddressSet)1631_storage" }, { - "astId": 6669, + "astId": 6683, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "liquidityAmount", "offset": 0, - "slot": "39", + "slot": "40", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 6675, + "astId": 6689, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "rewardedAt", "offset": 0, - "slot": "40", + "slot": "41", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 6681, + "astId": 6695, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "workedAt", "offset": 0, - "slot": "41", + "slot": "42", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 6687, + "astId": 6701, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_tick", "offset": 0, - "slot": "42", - "type": "t_mapping(t_address,t_struct(TickCache)14724_storage)" + "slot": "43", + "type": "t_mapping(t_address,t_struct(TickCache)14589_storage)" }, { - "astId": 8138, + "astId": 8152, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "pendingJobMigrations", "offset": 0, - "slot": "43", + "slot": "44", "type": "t_mapping(t_address,t_address)" }, { - "astId": 8144, + "astId": 8158, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_migrationCreatedAt", "offset": 0, - "slot": "44", + "slot": "45", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 8541, + "astId": 8555, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "_initialGas", "offset": 0, - "slot": "45", + "slot": "46", "type": "t_uint256" } ], @@ -3830,12 +3854,12 @@ "numberOfBytes": "32", "value": "t_struct(AddressSet)1631_storage" }, - "t_mapping(t_address,t_struct(TickCache)14724_storage)": { + "t_mapping(t_address,t_struct(TickCache)14589_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct IKeep3rJobFundableLiquidity.TickCache)", "numberOfBytes": "32", - "value": "t_struct(TickCache)14724_storage" + "value": "t_struct(TickCache)14589_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -3889,12 +3913,12 @@ ], "numberOfBytes": "64" }, - "t_struct(TickCache)14724_storage": { + "t_struct(TickCache)14589_storage": { "encoding": "inplace", "label": "struct IKeep3rJobFundableLiquidity.TickCache", "members": [ { - "astId": 14719, + "astId": 14584, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "current", "offset": 0, @@ -3902,7 +3926,7 @@ "type": "t_int56" }, { - "astId": 14721, + "astId": 14586, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "difference", "offset": 7, @@ -3910,7 +3934,7 @@ "type": "t_int56" }, { - "astId": 14723, + "astId": 14588, "contract": "solidity/for-test/testnet/Keep3rForTestnet.sol:Keep3rForTestnet", "label": "period", "offset": 0, diff --git a/deployments/goerli/Keep3rHelperForTestnet.json b/deployments/goerli/Keep3rHelperForTestnet.json index b072a1d..1889f95 100644 --- a/deployments/goerli/Keep3rHelperForTestnet.json +++ b/deployments/goerli/Keep3rHelperForTestnet.json @@ -1,5 +1,5 @@ { - "address": "0xe8b291495aB1505A96317b2FCB04a370bA1AE3c2", + "address": "0x399394ca069dCDE2C4d2a32E00a06C3D5fE17E3A", "abi": [ { "inputs": [ @@ -448,7 +448,7 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "_pool", "type": "address" } ], @@ -456,7 +456,7 @@ "outputs": [ { "internalType": "bool", - "name": "", + "name": "_isKP3RToken0", "type": "bool" } ], @@ -782,46 +782,46 @@ "type": "function" } ], - "transactionHash": "0xbf276a3d6f39d35f39c92410a8f68f10fdad23a31a41fb54461f1ef82dd7c43b", + "transactionHash": "0x8c0898fdccc22a29ca19fa44f5f79e8962f43a6f2fd4b94df15d47315cd7c208", "receipt": { "to": null, "from": "0x258b180E741157763236F5277619D71ECf00B906", - "contractAddress": "0xe8b291495aB1505A96317b2FCB04a370bA1AE3c2", - "transactionIndex": 18, - "gasUsed": "1757513", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000040000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe6a5131e49594da23f0e482692ec8c4588a348a25d92bf23795ac75a9c08cb00", - "transactionHash": "0xbf276a3d6f39d35f39c92410a8f68f10fdad23a31a41fb54461f1ef82dd7c43b", + "contractAddress": "0x399394ca069dCDE2C4d2a32E00a06C3D5fE17E3A", + "transactionIndex": 66, + "gasUsed": "1887545", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x3493fcdf8b9c69919dea006bf270e0539cfcfc8c196d620b14cf80653598d12b", + "transactionHash": "0x8c0898fdccc22a29ca19fa44f5f79e8962f43a6f2fd4b94df15d47315cd7c208", "logs": [ { - "transactionIndex": 18, - "blockNumber": 8042998, - "transactionHash": "0xbf276a3d6f39d35f39c92410a8f68f10fdad23a31a41fb54461f1ef82dd7c43b", - "address": "0xe8b291495aB1505A96317b2FCB04a370bA1AE3c2", + "transactionIndex": 66, + "blockNumber": 8091006, + "transactionHash": "0x8c0898fdccc22a29ca19fa44f5f79e8962f43a6f2fd4b94df15d47315cd7c208", + "address": "0x399394ca069dCDE2C4d2a32E00a06C3D5fE17E3A", "topics": [ "0x554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf4108" ], - "data": "0x000000000000000000000000050bba5e4abde750ea5610d8412cd46171c665e70000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 39, - "blockHash": "0xe6a5131e49594da23f0e482692ec8c4588a348a25d92bf23795ac75a9c08cb00" + "data": "0x000000000000000000000000317cecd3eb02158f97df0b67b788edcda4e066e50000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 145, + "blockHash": "0x3493fcdf8b9c69919dea006bf270e0539cfcfc8c196d620b14cf80653598d12b" } ], - "blockNumber": 8042998, - "cumulativeGasUsed": "3916355", + "blockNumber": 8091006, + "cumulativeGasUsed": "13188511", "status": 1, "byzantium": true }, "args": [ "0x16F63C5036d3F48A239358656a8f123eCE85789C", - "0x229d018065019c3164B899F4B9c2d4ffEae9B92b", + "0x85063437C02Ba7F4f82F898859e4992380DEd3bb", "0x258b180E741157763236F5277619D71ECf00B906", - "0x050BBA5E4abde750Ea5610D8412cD46171C665e7" + "0x317ceCd3eB02158f97DF0B67B788edCda4E066e5" ], - "numDeployments": 2, - "solcInputHash": "a2dd8c00aab95ba5d841446478d867fa", - "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_kp3r\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kp3rWethPool\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidOraclePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"Keep3rV2Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isKP3RToken0\",\"type\":\"bool\"}],\"name\":\"Kp3rWethPoolChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"MaxBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"MinBaseFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"MinBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"MinPriorityFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"QuoteTwapTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"TargetBondChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"WorkExtraGasChange\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BOOST_BASE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"KP3R\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountBonded\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityAmount\",\"type\":\"uint256\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getKP3RsAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3rAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getPaymentParams\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_boost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_oneEthQuote\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_extra\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"}],\"name\":\"getPoolTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token1\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_baseAmount\",\"type\":\"uint128\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getQuoteAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_quoteAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmountFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3r\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getRewardBoostFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardBoost\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isKP3RToken0\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV2\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"kp3rWethPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isTKNToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBaseFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minPriorityFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"},{\"internalType\":\"uint32[]\",\"name\":\"_secondsAgo\",\"type\":\"uint32[]\"}],\"name\":\"observe\",\"outputs\":[{\"internalType\":\"int56\",\"name\":\"_tickCumulative1\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"_tickCumulative2\",\"type\":\"int56\"},{\"internalType\":\"bool\",\"name\":\"_success\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eth\",\"type\":\"uint256\"}],\"name\":\"quote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"quoteTwapTime\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"setKeep3rV2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddress\",\"type\":\"address\"}],\"name\":\"setKp3rWethPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"setMaxBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"setMinBaseFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"setMinBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"setMinPriorityFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"setQuoteTwapTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"setTargetBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"setWorkExtraGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetBond\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"workExtraGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bonds(address)\":{\"params\":{\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_amountBonded\":\"The amount of KP3R the keeper has bonded\"}},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"params\":{\"_liquidityAmount\":\"Amount of liquidity to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_kp3rAmount\":\"Amount of KP3R tokens underlying on the given liquidity\"}},\"getPaymentParams(uint256)\":{\"params\":{\"_bonds\":\"Amount of bonded KP3R owned by the keeper\"},\"returns\":{\"_boost\":\"Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\",\"_extra\":\"Amount of extra gas that should be added to the gas spent\",\"_oneEthQuote\":\"Amount of KP3R tokens equivalent to 1 ETH\"}},\"getPoolTokens(address)\":{\"params\":{\"_pool\":\"Address of the correspondant pool\"},\"returns\":{\"_token0\":\"Address of the first token of the pair\",\"_token1\":\"Address of the second token of the pair\"}},\"getQuoteAtTick(uint128,int56,uint256)\":{\"params\":{\"_baseAmount\":\"Amount of token to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_quoteAmount\":\"Amount of credits deserved for the baseAmount at the tick value\"}},\"getRewardAmount(uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\"},\"returns\":{\"_amount\":\"The amount of KP3R that should be awarded to tx.origin\"}},\"getRewardAmountFor(address,uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\",\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_kp3r\":\"The amount of KP3R that should be awarded to the keeper\"}},\"getRewardBoostFor(uint256)\":{\"details\":\"If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\",\"params\":{\"_bonds\":\"The amount of KP3R tokens bonded by the keeper\"},\"returns\":{\"_rewardBoost\":\"The reward boost that corresponds to the keeper\"}},\"isKP3RToken0(address)\":{\"details\":\"Overrides token comparison with KP3R address\"},\"observe(address,uint32[])\":{\"params\":{\"_pool\":\"Address of the pool to observe\",\"_secondsAgo\":\"Array with time references to observe\"},\"returns\":{\"_success\":\"Boolean indicating if the observe call was succesfull\",\"_tickCumulative1\":\"Cumulative sum of ticks until first time reference\",\"_tickCumulative2\":\"Cumulative sum of ticks until second time reference\"}},\"quote(uint256)\":{\"details\":\"This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\",\"params\":{\"_eth\":\"The amount of ETH\"},\"returns\":{\"_amountOut\":\"The amount of KP3R\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setKeep3rV2(address)\":{\"params\":{\"_keep3rV2\":\"The address of Keep3r V2\"}},\"setKp3rWethPool(address)\":{\"params\":{\"_poolAddress\":\"The address of the KP3R-WETH pool\"}},\"setMaxBoost(uint256)\":{\"params\":{\"_maxBoost\":\"The maximum boost multiplier\"}},\"setMinBaseFee(uint256)\":{\"params\":{\"_minBaseFee\":\"The minimum rewarded gas fee\"}},\"setMinBoost(uint256)\":{\"params\":{\"_minBoost\":\"The minimum boost multiplier\"}},\"setMinPriorityFee(uint256)\":{\"params\":{\"_minPriorityFee\":\"The minimum rewarded priority fee\"}},\"setQuoteTwapTime(uint32)\":{\"params\":{\"_quoteTwapTime\":\"The twap time for quoting\"}},\"setTargetBond(uint256)\":{\"params\":{\"_targetBond\":\"The target bond amount\"}},\"setWorkExtraGas(uint256)\":{\"params\":{\"_workExtraGas\":\"The work extra gas\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidOraclePool()\":[{\"notice\":\"Throws when pool does not have KP3R as token0 nor token1\"}],\"LiquidityPairInvalid()\":[{\"notice\":\"Throws when none of the tokens in the liquidity pair is KP3R\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"Keep3rV2Change(address)\":{\"notice\":\"Emitted when the Keep3r V2 address is changed\"},\"Kp3rWethPoolChange(address,bool)\":{\"notice\":\"Emitted when the kp3r weth pool is changed\"},\"MaxBoostChange(uint256)\":{\"notice\":\"Emitted when the maximum boost multiplier is changed\"},\"MinBaseFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded gas fee is changed\"},\"MinBoostChange(uint256)\":{\"notice\":\"Emitted when the minimum boost multiplier is changed\"},\"MinPriorityFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded priority fee is changed\"},\"QuoteTwapTimeChange(uint32)\":{\"notice\":\"Emitted when the quote twap time is changed\"},\"TargetBondChange(uint256)\":{\"notice\":\"Emitted when the target bond amount is changed\"},\"WorkExtraGasChange(uint256)\":{\"notice\":\"Emitted when the work extra gas amount is changed\"}},\"kind\":\"user\",\"methods\":{\"BOOST_BASE()\":{\"notice\":\"The boost base used to calculate the boost rewards for the keeper\"},\"KP3R()\":{\"notice\":\"Address of KP3R token\"},\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"bonds(address)\":{\"notice\":\"Returns the amount of KP3R the keeper has bonded\"},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"notice\":\"Given a tick and a liquidity amount, calculates the underlying KP3R tokens\"},\"getPaymentParams(uint256)\":{\"notice\":\"Get multiplier, quote, and extra, in order to calculate keeper payment\"},\"getPoolTokens(address)\":{\"notice\":\"Given a pool address, returns the underlying tokens of the pair\"},\"getQuoteAtTick(uint128,int56,uint256)\":{\"notice\":\"Given a tick and a token amount, calculates the output in correspondant token\"},\"getRewardAmount(uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\"},\"getRewardAmountFor(address,uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to a keeper for using gas\"},\"getRewardBoostFor(uint256)\":{\"notice\":\"Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"keep3rV2()\":{\"notice\":\"Address of Keep3r V2\"},\"kp3rWethPool()\":{\"notice\":\"KP3R-WETH pool that is being used as oracle\"},\"maxBoost()\":{\"notice\":\"The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\"},\"minBaseFee()\":{\"notice\":\"The minimum base fee that is used to calculate keeper rewards\"},\"minBoost()\":{\"notice\":\"The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\"},\"minPriorityFee()\":{\"notice\":\"The minimum priority fee that is also rewarded for keepers\"},\"observe(address,uint32[])\":{\"notice\":\"Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"quote(uint256)\":{\"notice\":\"Calculates the amount of KP3R that corresponds to the ETH passed into the function\"},\"quoteTwapTime()\":{\"notice\":\"The twap time for quoting\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setKeep3rV2(address)\":{\"notice\":\"Sets the Keep3r V2 address\"},\"setKp3rWethPool(address)\":{\"notice\":\"Sets KP3R-WETH pool\"},\"setMaxBoost(uint256)\":{\"notice\":\"Sets the maximum boost multiplier\"},\"setMinBaseFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas fee\"},\"setMinBoost(uint256)\":{\"notice\":\"Sets the minimum boost multiplier\"},\"setMinPriorityFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas priority fee\"},\"setQuoteTwapTime(uint32)\":{\"notice\":\"Sets the quote twap time\"},\"setTargetBond(uint256)\":{\"notice\":\"Sets the target bond amount\"},\"setWorkExtraGas(uint256)\":{\"notice\":\"Sets the work extra gas amount\"},\"targetBond()\":{\"notice\":\"The targeted amount of bonded KP3Rs to max-up reward multiplier For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\"},\"workExtraGas()\":{\"notice\":\"The amount of unaccounted gas that is going to be added to keeper payments\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/testnet/Keep3rHelperForTestnet.sol\":\"Keep3rHelperForTestnet\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\nimport './pool/IUniswapV3PoolImmutables.sol';\\nimport './pool/IUniswapV3PoolState.sol';\\nimport './pool/IUniswapV3PoolDerivedState.sol';\\nimport './pool/IUniswapV3PoolActions.sol';\\nimport './pool/IUniswapV3PoolOwnerActions.sol';\\nimport './pool/IUniswapV3PoolEvents.sol';\\n\\n/// @title The interface for a Uniswap V3 Pool\\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\\n/// to the ERC20 specification\\n/// @dev The pool interface is broken up into many smaller pieces\\ninterface IUniswapV3Pool is\\n IUniswapV3PoolImmutables,\\n IUniswapV3PoolState,\\n IUniswapV3PoolDerivedState,\\n IUniswapV3PoolActions,\\n IUniswapV3PoolOwnerActions,\\n IUniswapV3PoolEvents\\n{\\n\\n}\\n\",\"keccak256\":\"0xfe6113d518466cd6652c85b111e01f33eb62157f49ae5ed7d5a3947a2044adb1\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissionless pool actions\\n/// @notice Contains pool methods that can be called by anyone\\ninterface IUniswapV3PoolActions {\\n /// @notice Sets the initial price for the pool\\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\\n function initialize(uint160 sqrtPriceX96) external;\\n\\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\\n /// @param recipient The address for which the liquidity will be created\\n /// @param tickLower The lower tick of the position in which to add liquidity\\n /// @param tickUpper The upper tick of the position in which to add liquidity\\n /// @param amount The amount of liquidity to mint\\n /// @param data Any data that should be passed through to the callback\\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n function mint(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount,\\n bytes calldata data\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Collects tokens owed to a position\\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\\n /// @param recipient The address which should receive the fees collected\\n /// @param tickLower The lower tick of the position for which to collect fees\\n /// @param tickUpper The upper tick of the position for which to collect fees\\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\\n /// @return amount0 The amount of fees collected in token0\\n /// @return amount1 The amount of fees collected in token1\\n function collect(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n\\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\\n /// @dev Fees must be collected separately via a call to #collect\\n /// @param tickLower The lower tick of the position for which to burn liquidity\\n /// @param tickUpper The upper tick of the position for which to burn liquidity\\n /// @param amount How much liquidity to burn\\n /// @return amount0 The amount of token0 sent to the recipient\\n /// @return amount1 The amount of token1 sent to the recipient\\n function burn(\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Swap token0 for token1, or token1 for token0\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\\n /// @param recipient The address to receive the output of the swap\\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\\n /// @param data Any data to be passed through to the callback\\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\\n /// @param recipient The address which will receive the token0 and token1 amounts\\n /// @param amount0 The amount of token0 to send\\n /// @param amount1 The amount of token1 to send\\n /// @param data Any data to be passed through to the callback\\n function flash(\\n address recipient,\\n uint256 amount0,\\n uint256 amount1,\\n bytes calldata data\\n ) external;\\n\\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\\n /// the input observationCardinalityNext.\\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0x9453dd0e7442188667d01d9b65de3f1e14e9511ff3e303179a15f6fc267f7634\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that is not stored\\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\\n/// blockchain. The functions here may have variable gas costs.\\ninterface IUniswapV3PoolDerivedState {\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\\n /// you must call it with secondsAgos = [3600, 0].\\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\\n /// timestamp\\n function observe(uint32[] calldata secondsAgos)\\n external\\n view\\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\\n\\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\\n /// snapshot is taken and the second snapshot is taken.\\n /// @param tickLower The lower tick of the range\\n /// @param tickUpper The upper tick of the range\\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\\n /// @return secondsInside The snapshot of seconds per liquidity for the range\\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\\n external\\n view\\n returns (\\n int56 tickCumulativeInside,\\n uint160 secondsPerLiquidityInsideX128,\\n uint32 secondsInside\\n );\\n}\\n\",\"keccak256\":\"0xe603ac5b17ecdee73ba2b27efdf386c257a19c14206e87eee77e2017b742d9e5\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Events emitted by a pool\\n/// @notice Contains all events emitted by the pool\\ninterface IUniswapV3PoolEvents {\\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\\n event Initialize(uint160 sqrtPriceX96, int24 tick);\\n\\n /// @notice Emitted when liquidity is minted for a given position\\n /// @param sender The address that minted the liquidity\\n /// @param owner The owner of the position and recipient of any minted liquidity\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity minted to the position range\\n /// @param amount0 How much token0 was required for the minted liquidity\\n /// @param amount1 How much token1 was required for the minted liquidity\\n event Mint(\\n address sender,\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted when fees are collected by the owner of a position\\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\\n /// @param owner The owner of the position for which fees are collected\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount0 The amount of token0 fees collected\\n /// @param amount1 The amount of token1 fees collected\\n event Collect(\\n address indexed owner,\\n address recipient,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount0,\\n uint128 amount1\\n );\\n\\n /// @notice Emitted when a position's liquidity is removed\\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\\n /// @param owner The owner of the position for which liquidity is removed\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity to remove\\n /// @param amount0 The amount of token0 withdrawn\\n /// @param amount1 The amount of token1 withdrawn\\n event Burn(\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted by the pool for any swaps between token0 and token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the output of the swap\\n /// @param amount0 The delta of the token0 balance of the pool\\n /// @param amount1 The delta of the token1 balance of the pool\\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param liquidity The liquidity of the pool after the swap\\n /// @param tick The log base 1.0001 of price of the pool after the swap\\n event Swap(\\n address indexed sender,\\n address indexed recipient,\\n int256 amount0,\\n int256 amount1,\\n uint160 sqrtPriceX96,\\n uint128 liquidity,\\n int24 tick\\n );\\n\\n /// @notice Emitted by the pool for any flashes of token0/token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the tokens from flash\\n /// @param amount0 The amount of token0 that was flashed\\n /// @param amount1 The amount of token1 that was flashed\\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\\n event Flash(\\n address indexed sender,\\n address indexed recipient,\\n uint256 amount0,\\n uint256 amount1,\\n uint256 paid0,\\n uint256 paid1\\n );\\n\\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\\n /// just before a mint/swap/burn.\\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(\\n uint16 observationCardinalityNextOld,\\n uint16 observationCardinalityNextNew\\n );\\n\\n /// @notice Emitted when the protocol fee is changed by the pool\\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\\n /// @param feeProtocol0New The updated value of the token0 protocol fee\\n /// @param feeProtocol1New The updated value of the token1 protocol fee\\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\\n\\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\\n /// @param sender The address that collects the protocol fees\\n /// @param recipient The address that receives the collected protocol fees\\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x8071514d0fe5d17d6fbd31c191cdfb703031c24e0ece3621d88ab10e871375cd\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that never changes\\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\\ninterface IUniswapV3PoolImmutables {\\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\\n /// @return The contract address\\n function factory() external view returns (address);\\n\\n /// @notice The first of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token0() external view returns (address);\\n\\n /// @notice The second of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token1() external view returns (address);\\n\\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\\n /// @return The fee\\n function fee() external view returns (uint24);\\n\\n /// @notice The pool tick spacing\\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\\n /// This value is an int24 to avoid casting even though it is always positive.\\n /// @return The tick spacing\\n function tickSpacing() external view returns (int24);\\n\\n /// @notice The maximum amount of position liquidity that can use any tick in the range\\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\\n /// @return The max amount of liquidity per tick\\n function maxLiquidityPerTick() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xf6e5d2cd1139c4c276bdbc8e1d2b256e456c866a91f1b868da265c6d2685c3f7\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissioned pool actions\\n/// @notice Contains pool methods that may only be called by the factory owner\\ninterface IUniswapV3PoolOwnerActions {\\n /// @notice Set the denominator of the protocol's % share of the fees\\n /// @param feeProtocol0 new protocol fee for token0 of the pool\\n /// @param feeProtocol1 new protocol fee for token1 of the pool\\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\\n\\n /// @notice Collect the protocol fee accrued to the pool\\n /// @param recipient The address to which collected protocol fees should be sent\\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\\n /// @return amount0 The protocol fee collected in token0\\n /// @return amount1 The protocol fee collected in token1\\n function collectProtocol(\\n address recipient,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x759b78a2918af9e99e246dc3af084f654e48ef32bb4e4cb8a966aa3dcaece235\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that can change\\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\\n/// per transaction\\ninterface IUniswapV3PoolState {\\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\\n /// when accessed externally.\\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\\n /// boundary.\\n /// observationIndex The index of the last oracle observation that was written,\\n /// observationCardinality The current maximum number of observations stored in the pool,\\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// feeProtocol The protocol fee for both tokens of the pool.\\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\\n /// unlocked Whether the pool is currently locked to reentrancy\\n function slot0()\\n external\\n view\\n returns (\\n uint160 sqrtPriceX96,\\n int24 tick,\\n uint16 observationIndex,\\n uint16 observationCardinality,\\n uint16 observationCardinalityNext,\\n uint8 feeProtocol,\\n bool unlocked\\n );\\n\\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal0X128() external view returns (uint256);\\n\\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal1X128() external view returns (uint256);\\n\\n /// @notice The amounts of token0 and token1 that are owed to the protocol\\n /// @dev Protocol fees will never exceed uint128 max in either token\\n function protocolFees() external view returns (uint128 token0, uint128 token1);\\n\\n /// @notice The currently in range liquidity available to the pool\\n /// @dev This value has no relationship to the total liquidity across all ticks\\n function liquidity() external view returns (uint128);\\n\\n /// @notice Look up information about a specific tick in the pool\\n /// @param tick The tick to look up\\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\\n /// tick upper,\\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\\n /// a specific position.\\n function ticks(int24 tick)\\n external\\n view\\n returns (\\n uint128 liquidityGross,\\n int128 liquidityNet,\\n uint256 feeGrowthOutside0X128,\\n uint256 feeGrowthOutside1X128,\\n int56 tickCumulativeOutside,\\n uint160 secondsPerLiquidityOutsideX128,\\n uint32 secondsOutside,\\n bool initialized\\n );\\n\\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\\n function tickBitmap(int16 wordPosition) external view returns (uint256);\\n\\n /// @notice Returns the information about a position by the position's key\\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\\n /// @return _liquidity The amount of liquidity in the position,\\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\\n function positions(bytes32 key)\\n external\\n view\\n returns (\\n uint128 _liquidity,\\n uint256 feeGrowthInside0LastX128,\\n uint256 feeGrowthInside1LastX128,\\n uint128 tokensOwed0,\\n uint128 tokensOwed1\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param index The element of the observations array to fetch\\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\\n /// ago, rather than at a specific index in the array.\\n /// @return blockTimestamp The timestamp of the observation,\\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// Returns initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 index)\\n external\\n view\\n returns (\\n uint32 blockTimestamp,\\n int56 tickCumulative,\\n uint160 secondsPerLiquidityCumulativeX128,\\n bool initialized\\n );\\n}\\n\",\"keccak256\":\"0x852dc1f5df7dcf7f11e7bb3eed79f0cea72ad4b25f6a9d2c35aafb48925fd49f\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/Keep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2003\\u2003\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2003\\u2003\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/IKeep3rHelper.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\\n\\n /// @inheritdoc IKeep3rHelper\\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\\n uint32[] memory _secondsAgos = new uint32[](2);\\n _secondsAgos[1] = quoteTwapTime;\\n\\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\\n // solhint-disable-next-line avoid-tx-origin\\n return getRewardAmountFor(tx.origin, _gasUsed);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\\n _bonds = Math.min(_bonds, targetBond);\\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\\n _rewardBoost = _cap * _getBasefee();\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\\n address _token0;\\n address _token1;\\n (_token0, _token1) = getPoolTokens(_pool);\\n if (_token0 == KP3R) {\\n return true;\\n } else if (_token1 != KP3R) {\\n revert LiquidityPairInvalid();\\n }\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n override\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n )\\n {\\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\\n _tickCumulative1 = _uniswapResponse[0];\\n if (_uniswapResponse.length > 1) {\\n _tickCumulative2 = _uniswapResponse[1];\\n }\\n _success = true;\\n } catch (bytes memory) {}\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n override\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n )\\n {\\n _oneEthQuote = quote(1 ether);\\n _boost = getRewardBoostFor(_bonds);\\n _extra = workExtraGas;\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure override returns (uint256 _kp3rAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) public pure override returns (uint256 _quoteAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n\\n if (sqrtRatioX96 <= type(uint128).max) {\\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\\n } else {\\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\\n }\\n }\\n\\n /// @notice Gets the gas basefee cost to calculate keeper rewards\\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\\n }\\n}\\n\",\"keccak256\":\"0x88844b43c69ff137c86106096e251dea858bc45ddb198ea08c97735dc6bf4951\",\"license\":\"MIT\"},\"solidity/contracts/Keep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/peripherals/IBaseErrors.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/external/IKeep3rV1.sol';\\nimport '../interfaces/IKeep3rHelperParameters.sol';\\nimport './peripherals/Governable.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\\n /// @inheritdoc IKeep3rHelperParameters\\n address public immutable override KP3R;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public constant override BOOST_BASE = 10_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBoost = 11_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override maxBoost = 12_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override targetBond = 200 ether;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override workExtraGas = 30_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint32 public override quoteTwapTime = 10 minutes;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBaseFee = 15e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minPriorityFee = 2e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n address public override keep3rV2;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\\n\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Governable(_governance) {\\n KP3R = _kp3r;\\n keep3rV2 = _keep3rV2;\\n\\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\\n if (_poolAddress == address(0)) revert ZeroAddress();\\n _setKp3rWethPool(_poolAddress);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\\n minBoost = _minBoost;\\n emit MinBoostChange(minBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\\n maxBoost = _maxBoost;\\n emit MaxBoostChange(maxBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\\n targetBond = _targetBond;\\n emit TargetBondChange(targetBond);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\\n if (_keep3rV2 == address(0)) revert ZeroAddress();\\n keep3rV2 = _keep3rV2;\\n emit Keep3rV2Change(keep3rV2);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\\n workExtraGas = _workExtraGas;\\n emit WorkExtraGasChange(workExtraGas);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\\n _setQuoteTwapTime(_quoteTwapTime);\\n }\\n\\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\\n quoteTwapTime = _quoteTwapTime;\\n emit QuoteTwapTimeChange(quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\\n minBaseFee = _minBaseFee;\\n emit MinBaseFeeChange(minBaseFee);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\\n minPriorityFee = _minPriorityFee;\\n emit MinPriorityFeeChange(minPriorityFee);\\n }\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function _setKp3rWethPool(address _poolAddress) internal {\\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\\n }\\n\\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\\n\\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\\n\\n return TokenOraclePool(_poolAddress, _isTKNToken0);\\n }\\n}\\n\",\"keccak256\":\"0xd16cb900c60b28a7eda5467b43c9d47ca9d48b1d7aab967bf1083c1449d39113\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n// solhint-disable\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\\n\\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n // Second inequality must be < because the price can never reach the price at the max tick\\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n}\\n\",\"keccak256\":\"0x11b965ba576ff91b4a6e9533c0f334f2b7b6024ee1c54e36d21799de5580899d\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/for-test/testnet/Keep3rHelperForTestnet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../contracts/Keep3rHelper.sol';\\n\\ncontract Keep3rHelperForTestnet is Keep3rHelper {\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\\n\\n function _getBasefee() internal view override returns (uint256) {\\n return 1;\\n }\\n\\n /// @dev Overrides oracle validation that uses KP3R and WETH addresses\\n function _validateOraclePool(address _poolAddress, address) internal view virtual override returns (TokenOraclePool memory _oraclePool) {\\n return TokenOraclePool(_poolAddress, true);\\n }\\n\\n /// @dev Overrides token comparison with KP3R address\\n function isKP3RToken0(address) public view virtual override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xf4850164f9a61fa857a1f87c1943530ae8903daea4c01f696c8684f1a3d584cd\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct TokenOraclePool {\\n address poolAddress;\\n bool isTKNToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0x76f99ca04361c0459fc9e99f0387ddb76da18cc470ec5bc744e7dc3bf6e9d334\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0x060f701c6991d323bcf360738568714956013b17b3e3443ea21d825a70c3947c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a0604052612af8600255612ee0600355680ad78ebc5ac62000006004556175306005556006805463ffffffff191661025817905564037e11d60060075563773594006008553480156200005257600080fd5b5060405162001cbf38038062001cbf83398101604081905262000075916200019a565b8383838383838383816001600160a01b038116620000a55760405162b293ed60e81b815260040160405180910390fd5b600080546001600160a01b03199081166001600160a01b03938416178255606087901b6001600160601b0319166080526009805490911686841617905560408051808201825282815260209081019290925280518082018252848416808252600191840191909152600a8054600160a01b6001600160a81b0319909116909217821790819055825194811685520460ff1615159183019190915280517f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf41089281900390910190a1505050505050505050505050620001f7565b80516001600160a01b03811681146200019557600080fd5b919050565b60008060008060808587031215620001b157600080fd5b620001bc856200017d565b9350620001cc602086016200017d565b9250620001dc604086016200017d565b9150620001ec606086016200017d565b905092959194509250565b60805160601c611aa26200021d600039600081816101bb0152610e690152611aa26000f3fe608060405234801561001057600080fd5b50600436106101b15760003560e01c80637b40c913116100f55780637b40c9131461032c5780638561579c146103595780638a9b1b09146103625780639aaad6791461036b578063a0d2710714610390578063a62611a2146103a3578063ab033ea9146103ac578063ab5dce00146103bf578063ab8cedc5146103d2578063b2e0df96146103e5578063b93f5af0146103f8578063c84993af1461040b578063ca4f28031461041e578063dc686d911461043f578063e244208b14610477578063ed1bd76c1461048a578063f39c38a01461049d578063fe10d774146104b057600080fd5b806305e0b9a0146101b65780630c525835146101f3578063117cfc1b14610208578063160e1e311461021b5780632248e82d1461022e578063238efcbc1461024f57806325f09e61146102575780632742b9e714610260578063289adb441461026957806337090c2f1461027c5780633cc7ab30146102855780633facf24214610298578063435b21c1146102a1578063516c3323146102cf5780635aa6e675146102e2578063607e48d4146102f5578063696a437b14610308575b600080fd5b6101dd7f000000000000000000000000000000000000000000000000000000000000000081565b6040516101ea91906117bc565b60405180910390f35b610206610201366004611748565b6104c3565b005b6009546101dd906001600160a01b031681565b610206610229366004611517565b61052a565b61024161023c366004611604565b610588565b6040519081526020016101ea565b6102066105bb565b61024161271081565b61024160045481565b610206610277366004611748565b610647565b61024160035481565b610206610293366004611517565b6106a7565b61024160055481565b6102b46102af366004611748565b610745565b604080519384526020840192909252908201526060016101ea565b6102416102dd366004611748565b610773565b6000546101dd906001600160a01b031681565b610206610303366004611748565b6107ce565b61031c610316366004611517565b50600190565b60405190151581526020016101ea565b600a5461034b906001600160a01b03811690600160a01b900460ff1682565b6040516101ea9291906117ea565b61024160025481565b61024160085481565b60065461037b9063ffffffff1681565b60405163ffffffff90911681526020016101ea565b61024161039e36600461177a565b61082e565b61024160075481565b6102066103ba366004611517565b61086a565b6102066103cd366004611748565b6108e0565b6102416103e03660046116fb565b610940565b6102066103f3366004611748565b6109e4565b6102066104063660046117a1565b610a44565b610241610419366004611748565b610a78565b61043161042c366004611517565b610a8a565b6040516101ea9291906117d0565b61045261044d366004611551565b610b78565b60408051600694850b81529290930b60208301521515918101919091526060016101ea565b610206610485366004611748565b610c83565b610241610498366004611748565b610ce3565b6001546101dd906001600160a01b031681565b6102416104be366004611517565b610e3e565b6000546001600160a01b031633146104ee576040516354348f0360e01b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b03163314610555576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661057c5760405163d92e233d60e01b815260040160405180910390fd5b61058581610ee1565b50565b6000806105976102dd85610e3e565b90506105b36127106105a983866118fc565b61049891906118e8565b949350505050565b6001546001600160a01b031633146105e657604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161063d916117bc565b60405180910390a1565b6000546001600160a01b03163314610672576040516354348f0360e01b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b9060200161051f565b6000546001600160a01b031633146106d2576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166106f95760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a9161051f916117bc565b600080600061075b670de0b6b3a7640000610ce3565b915061076684610773565b6005549095929450925050565b600061078182600454610f69565b9150600060045483600254600354610799919061196b565b6107a391906118fc565b6107ad91906118e8565b6002546107ba91906118a2565b90506107c76001826118fc565b9392505050565b6000546001600160a01b031633146107f9576040516354348f0360e01b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b9060200161051f565b60008061084761084284600687900b6118ba565b610f7f565b9050610861600160601b86836001600160a01b031661138d565b95945050505050565b6000546001600160a01b03163314610895576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f9061051f9083906117bc565b6000546001600160a01b0316331461090b576040516354348f0360e01b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e9060200161051f565b60008061095461084284600687900b6118ba565b90506001600160801b036001600160a01b038216116109a45760006109826001600160a01b038316806118fc565b905061099c600160c01b876001600160801b03168361138d565b9250506109dc565b60006109be6001600160a01b03831680600160401b61138d565b90506109d8600160801b876001600160801b03168361138d565b9250505b509392505050565b6000546001600160a01b03163314610a0f576040516354348f0360e01b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa9060200161051f565b6000546001600160a01b03163314610a6f576040516354348f0360e01b815260040160405180910390fd5b6105858161143b565b6000610a843283610588565b92915050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610ac657600080fd5b505afa158015610ada573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610afe9190611534565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610b3757600080fd5b505afa158015610b4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6f9190611534565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b8152600401610ba99190611805565b60006040518083038186803b158015610bc157600080fd5b505afa925050508015610bf657506040513d6000823e601f3d908101601f19168201604052610bf39190810190611630565b60015b610c30573d808015610c24576040519150601f19603f3d011682016040523d82523d6000602084013e610c29565b606091505b5050610c7c565b81600081518110610c4357610c43611a1c565b60200260200101519450600182511115610c755781600181518110610c6a57610c6a611a1c565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b03163314610cae576040516354348f0360e01b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d541592219060200161051f565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff16918391506001908110610d2757610d27611a1c565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd90610d6d908590600401611805565b60006040518083038186803b158015610d8557600080fd5b505afa158015610d99573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dc19190810190611630565b509050600081600181518110610dd957610dd9611a1c565b602002602001015182600081518110610df457610df4611a1c565b6020026020010151610e06919061191b565b600a54909150610861908690600160a01b900460ff16610e2e57610e29836119d6565b610e30565b825b60065463ffffffff16610940565b60095460405163a39744b560e01b81526000916001600160a01b03169063a39744b590610e919085907f0000000000000000000000000000000000000000000000000000000000000000906004016117d0565b60206040518083038186803b158015610ea957600080fd5b505afa158015610ebd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a849190611761565b6040805180820182526000808252602091820152815180830183526001600160a01b0384811680835260019290930191909152600a80546001600160a81b031916909217600160a01b9081179283905592517f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf41089361051f939283169260ff91900416906117ea565b6000818310610f7857816107c7565b5090919050565b60008060008360020b12610f96578260020b610fa3565b8260020b610fa3906119b9565b9050610fb2620d89e719611996565b60020b811115610fec5760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b60006001821661100057600160801b611012565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b031690506002821615611047576080611042826ffff97272373d413259a46990580e213a6118fc565b901c90505b600482161561107157608061106c826ffff2e50f5f656932ef12357cf3c7fdcc6118fc565b901c90505b600882161561109b576080611096826fffe5caca7e10e4e61c3624eaa0941cd06118fc565b901c90505b60108216156110c55760806110c0826fffcb9843d60f6159c9db58835c9266446118fc565b901c90505b60208216156110ef5760806110ea826fff973b41fa98c081472e6896dfb254c06118fc565b901c90505b6040821615611119576080611114826fff2ea16466c96a3843ec78b326b528616118fc565b901c90505b608082161561114357608061113e826ffe5dee046a99a2a811c461f1969c30536118fc565b901c90505b61010082161561116e576080611169826ffcbe86c7900a88aedcffc83b479aa3a46118fc565b901c90505b610200821615611199576080611194826ff987a7253ac413176f2b074cf7815e546118fc565b901c90505b6104008216156111c45760806111bf826ff3392b0822b70005940c7a398e4b70f36118fc565b901c90505b6108008216156111ef5760806111ea826fe7159475a2c29b7443b29c7fa6e889d96118fc565b901c90505b61100082161561121a576080611215826fd097f3bdfd2022b8845ad8f792aa58256118fc565b901c90505b612000821615611245576080611240826fa9f746462d870fdf8a65dc1f90e061e56118fc565b901c90505b61400082161561127057608061126b826f70d869a156d2a1b890bb3df62baf32f76118fc565b901c90505b61800082161561129b576080611296826f31be135f97d08fd981231505542fcfa66118fc565b901c90505b620100008216156112c75760806112c2826f09aa508b5b7a84e1c677de54f3e99bc96118fc565b901c90505b620200008216156112f25760806112ed826e5d6af8dedb81196699c329225ee6046118fc565b901c90505b6204000082161561131c576080611317826d2216e584f5fa1ea926041bedfe986118fc565b901c90505b6208000082161561134457608061133f826b048a170391f7dc42444e8fa26118fc565b901c90505b60008460020b131561135f5761135c816000196118e8565b90505b61136d600160201b82611982565b1561137957600161137c565b60005b6105b39060ff16602083901c6118a2565b6000808060001985870985870292508281108382030391505080600014156113c757600084116113bc57600080fd5b5082900490506107c7565b8084116113d357600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de9060200161051f565b600082601f83011261149457600080fd5b815160206114a96114a48361187f565b61184f565b80838252828201915082860187848660051b89010111156114c957600080fd5b60005b858110156114f15781516114df81611a48565b845292840192908401906001016114cc565b5090979650505050505050565b803563ffffffff8116811461151257600080fd5b919050565b60006020828403121561152957600080fd5b81356107c781611a48565b60006020828403121561154657600080fd5b81516107c781611a48565b6000806040838503121561156457600080fd5b823561156f81611a48565b91506020838101356001600160401b0381111561158b57600080fd5b8401601f8101861361159c57600080fd5b80356115aa6114a48261187f565b80828252848201915084840189868560051b87010111156115ca57600080fd5b600094505b838510156115f4576115e0816114fe565b8352600194909401939185019185016115cf565b5080955050505050509250929050565b6000806040838503121561161757600080fd5b823561162281611a48565b946020939093013593505050565b6000806040838503121561164357600080fd5b82516001600160401b038082111561165a57600080fd5b818501915085601f83011261166e57600080fd5b8151602061167e6114a48361187f565b8083825282820191508286018a848660051b890101111561169e57600080fd5b600096505b848710156116ca5780516116b681611a5d565b8352600196909601959183019183016116a3565b50918801519196509093505050808211156116e457600080fd5b506116f185828601611483565b9150509250929050565b60008060006060848603121561171057600080fd5b83356001600160801b038116811461172757600080fd5b9250602084013561173781611a5d565b929592945050506040919091013590565b60006020828403121561175a57600080fd5b5035919050565b60006020828403121561177357600080fd5b5051919050565b60008060006060848603121561178f57600080fd5b83359250602084013561173781611a5d565b6000602082840312156117b357600080fd5b6107c7826114fe565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561184357835163ffffffff1683529284019291840191600101611821565b50909695505050505050565b604051601f8201601f191681016001600160401b038111828210171561187757611877611a32565b604052919050565b60006001600160401b0382111561189857611898611a32565b5060051b60200190565b600082198211156118b5576118b56119f0565b500190565b6000826118c9576118c9611a06565b600160ff1b8214600019841416156118e3576118e36119f0565b500590565b6000826118f7576118f7611a06565b500490565b6000816000190483118215151615611916576119166119f0565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615611946576119466119f0565b81667fffffffffffff018313811615611961576119616119f0565b5090039392505050565b60008282101561197d5761197d6119f0565b500390565b60008261199157611991611a06565b500690565b60008160020b627fffff198114156119b0576119b06119f0565b60000392915050565b6000600160ff1b8214156119cf576119cf6119f0565b5060000390565b60008160060b667fffffffffffff198114156119b0576119b05b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461058557600080fd5b8060060b811461058557600080fdfea2646970667358221220e31b6e4bcba9c7bdff81001ffe0761058a7c9175286970ab89be3f2061144c3d64736f6c63430008070033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101b15760003560e01c80637b40c913116100f55780637b40c9131461032c5780638561579c146103595780638a9b1b09146103625780639aaad6791461036b578063a0d2710714610390578063a62611a2146103a3578063ab033ea9146103ac578063ab5dce00146103bf578063ab8cedc5146103d2578063b2e0df96146103e5578063b93f5af0146103f8578063c84993af1461040b578063ca4f28031461041e578063dc686d911461043f578063e244208b14610477578063ed1bd76c1461048a578063f39c38a01461049d578063fe10d774146104b057600080fd5b806305e0b9a0146101b65780630c525835146101f3578063117cfc1b14610208578063160e1e311461021b5780632248e82d1461022e578063238efcbc1461024f57806325f09e61146102575780632742b9e714610260578063289adb441461026957806337090c2f1461027c5780633cc7ab30146102855780633facf24214610298578063435b21c1146102a1578063516c3323146102cf5780635aa6e675146102e2578063607e48d4146102f5578063696a437b14610308575b600080fd5b6101dd7f000000000000000000000000000000000000000000000000000000000000000081565b6040516101ea91906117bc565b60405180910390f35b610206610201366004611748565b6104c3565b005b6009546101dd906001600160a01b031681565b610206610229366004611517565b61052a565b61024161023c366004611604565b610588565b6040519081526020016101ea565b6102066105bb565b61024161271081565b61024160045481565b610206610277366004611748565b610647565b61024160035481565b610206610293366004611517565b6106a7565b61024160055481565b6102b46102af366004611748565b610745565b604080519384526020840192909252908201526060016101ea565b6102416102dd366004611748565b610773565b6000546101dd906001600160a01b031681565b610206610303366004611748565b6107ce565b61031c610316366004611517565b50600190565b60405190151581526020016101ea565b600a5461034b906001600160a01b03811690600160a01b900460ff1682565b6040516101ea9291906117ea565b61024160025481565b61024160085481565b60065461037b9063ffffffff1681565b60405163ffffffff90911681526020016101ea565b61024161039e36600461177a565b61082e565b61024160075481565b6102066103ba366004611517565b61086a565b6102066103cd366004611748565b6108e0565b6102416103e03660046116fb565b610940565b6102066103f3366004611748565b6109e4565b6102066104063660046117a1565b610a44565b610241610419366004611748565b610a78565b61043161042c366004611517565b610a8a565b6040516101ea9291906117d0565b61045261044d366004611551565b610b78565b60408051600694850b81529290930b60208301521515918101919091526060016101ea565b610206610485366004611748565b610c83565b610241610498366004611748565b610ce3565b6001546101dd906001600160a01b031681565b6102416104be366004611517565b610e3e565b6000546001600160a01b031633146104ee576040516354348f0360e01b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b03163314610555576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661057c5760405163d92e233d60e01b815260040160405180910390fd5b61058581610ee1565b50565b6000806105976102dd85610e3e565b90506105b36127106105a983866118fc565b61049891906118e8565b949350505050565b6001546001600160a01b031633146105e657604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161063d916117bc565b60405180910390a1565b6000546001600160a01b03163314610672576040516354348f0360e01b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b9060200161051f565b6000546001600160a01b031633146106d2576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166106f95760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a9161051f916117bc565b600080600061075b670de0b6b3a7640000610ce3565b915061076684610773565b6005549095929450925050565b600061078182600454610f69565b9150600060045483600254600354610799919061196b565b6107a391906118fc565b6107ad91906118e8565b6002546107ba91906118a2565b90506107c76001826118fc565b9392505050565b6000546001600160a01b031633146107f9576040516354348f0360e01b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b9060200161051f565b60008061084761084284600687900b6118ba565b610f7f565b9050610861600160601b86836001600160a01b031661138d565b95945050505050565b6000546001600160a01b03163314610895576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f9061051f9083906117bc565b6000546001600160a01b0316331461090b576040516354348f0360e01b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e9060200161051f565b60008061095461084284600687900b6118ba565b90506001600160801b036001600160a01b038216116109a45760006109826001600160a01b038316806118fc565b905061099c600160c01b876001600160801b03168361138d565b9250506109dc565b60006109be6001600160a01b03831680600160401b61138d565b90506109d8600160801b876001600160801b03168361138d565b9250505b509392505050565b6000546001600160a01b03163314610a0f576040516354348f0360e01b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa9060200161051f565b6000546001600160a01b03163314610a6f576040516354348f0360e01b815260040160405180910390fd5b6105858161143b565b6000610a843283610588565b92915050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610ac657600080fd5b505afa158015610ada573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610afe9190611534565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610b3757600080fd5b505afa158015610b4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6f9190611534565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b8152600401610ba99190611805565b60006040518083038186803b158015610bc157600080fd5b505afa925050508015610bf657506040513d6000823e601f3d908101601f19168201604052610bf39190810190611630565b60015b610c30573d808015610c24576040519150601f19603f3d011682016040523d82523d6000602084013e610c29565b606091505b5050610c7c565b81600081518110610c4357610c43611a1c565b60200260200101519450600182511115610c755781600181518110610c6a57610c6a611a1c565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b03163314610cae576040516354348f0360e01b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d541592219060200161051f565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff16918391506001908110610d2757610d27611a1c565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd90610d6d908590600401611805565b60006040518083038186803b158015610d8557600080fd5b505afa158015610d99573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dc19190810190611630565b509050600081600181518110610dd957610dd9611a1c565b602002602001015182600081518110610df457610df4611a1c565b6020026020010151610e06919061191b565b600a54909150610861908690600160a01b900460ff16610e2e57610e29836119d6565b610e30565b825b60065463ffffffff16610940565b60095460405163a39744b560e01b81526000916001600160a01b03169063a39744b590610e919085907f0000000000000000000000000000000000000000000000000000000000000000906004016117d0565b60206040518083038186803b158015610ea957600080fd5b505afa158015610ebd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a849190611761565b6040805180820182526000808252602091820152815180830183526001600160a01b0384811680835260019290930191909152600a80546001600160a81b031916909217600160a01b9081179283905592517f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf41089361051f939283169260ff91900416906117ea565b6000818310610f7857816107c7565b5090919050565b60008060008360020b12610f96578260020b610fa3565b8260020b610fa3906119b9565b9050610fb2620d89e719611996565b60020b811115610fec5760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b60006001821661100057600160801b611012565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b031690506002821615611047576080611042826ffff97272373d413259a46990580e213a6118fc565b901c90505b600482161561107157608061106c826ffff2e50f5f656932ef12357cf3c7fdcc6118fc565b901c90505b600882161561109b576080611096826fffe5caca7e10e4e61c3624eaa0941cd06118fc565b901c90505b60108216156110c55760806110c0826fffcb9843d60f6159c9db58835c9266446118fc565b901c90505b60208216156110ef5760806110ea826fff973b41fa98c081472e6896dfb254c06118fc565b901c90505b6040821615611119576080611114826fff2ea16466c96a3843ec78b326b528616118fc565b901c90505b608082161561114357608061113e826ffe5dee046a99a2a811c461f1969c30536118fc565b901c90505b61010082161561116e576080611169826ffcbe86c7900a88aedcffc83b479aa3a46118fc565b901c90505b610200821615611199576080611194826ff987a7253ac413176f2b074cf7815e546118fc565b901c90505b6104008216156111c45760806111bf826ff3392b0822b70005940c7a398e4b70f36118fc565b901c90505b6108008216156111ef5760806111ea826fe7159475a2c29b7443b29c7fa6e889d96118fc565b901c90505b61100082161561121a576080611215826fd097f3bdfd2022b8845ad8f792aa58256118fc565b901c90505b612000821615611245576080611240826fa9f746462d870fdf8a65dc1f90e061e56118fc565b901c90505b61400082161561127057608061126b826f70d869a156d2a1b890bb3df62baf32f76118fc565b901c90505b61800082161561129b576080611296826f31be135f97d08fd981231505542fcfa66118fc565b901c90505b620100008216156112c75760806112c2826f09aa508b5b7a84e1c677de54f3e99bc96118fc565b901c90505b620200008216156112f25760806112ed826e5d6af8dedb81196699c329225ee6046118fc565b901c90505b6204000082161561131c576080611317826d2216e584f5fa1ea926041bedfe986118fc565b901c90505b6208000082161561134457608061133f826b048a170391f7dc42444e8fa26118fc565b901c90505b60008460020b131561135f5761135c816000196118e8565b90505b61136d600160201b82611982565b1561137957600161137c565b60005b6105b39060ff16602083901c6118a2565b6000808060001985870985870292508281108382030391505080600014156113c757600084116113bc57600080fd5b5082900490506107c7565b8084116113d357600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de9060200161051f565b600082601f83011261149457600080fd5b815160206114a96114a48361187f565b61184f565b80838252828201915082860187848660051b89010111156114c957600080fd5b60005b858110156114f15781516114df81611a48565b845292840192908401906001016114cc565b5090979650505050505050565b803563ffffffff8116811461151257600080fd5b919050565b60006020828403121561152957600080fd5b81356107c781611a48565b60006020828403121561154657600080fd5b81516107c781611a48565b6000806040838503121561156457600080fd5b823561156f81611a48565b91506020838101356001600160401b0381111561158b57600080fd5b8401601f8101861361159c57600080fd5b80356115aa6114a48261187f565b80828252848201915084840189868560051b87010111156115ca57600080fd5b600094505b838510156115f4576115e0816114fe565b8352600194909401939185019185016115cf565b5080955050505050509250929050565b6000806040838503121561161757600080fd5b823561162281611a48565b946020939093013593505050565b6000806040838503121561164357600080fd5b82516001600160401b038082111561165a57600080fd5b818501915085601f83011261166e57600080fd5b8151602061167e6114a48361187f565b8083825282820191508286018a848660051b890101111561169e57600080fd5b600096505b848710156116ca5780516116b681611a5d565b8352600196909601959183019183016116a3565b50918801519196509093505050808211156116e457600080fd5b506116f185828601611483565b9150509250929050565b60008060006060848603121561171057600080fd5b83356001600160801b038116811461172757600080fd5b9250602084013561173781611a5d565b929592945050506040919091013590565b60006020828403121561175a57600080fd5b5035919050565b60006020828403121561177357600080fd5b5051919050565b60008060006060848603121561178f57600080fd5b83359250602084013561173781611a5d565b6000602082840312156117b357600080fd5b6107c7826114fe565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561184357835163ffffffff1683529284019291840191600101611821565b50909695505050505050565b604051601f8201601f191681016001600160401b038111828210171561187757611877611a32565b604052919050565b60006001600160401b0382111561189857611898611a32565b5060051b60200190565b600082198211156118b5576118b56119f0565b500190565b6000826118c9576118c9611a06565b600160ff1b8214600019841416156118e3576118e36119f0565b500590565b6000826118f7576118f7611a06565b500490565b6000816000190483118215151615611916576119166119f0565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615611946576119466119f0565b81667fffffffffffff018313811615611961576119616119f0565b5090039392505050565b60008282101561197d5761197d6119f0565b500390565b60008261199157611991611a06565b500690565b60008160020b627fffff198114156119b0576119b06119f0565b60000392915050565b6000600160ff1b8214156119cf576119cf6119f0565b5060000390565b60008160060b667fffffffffffff198114156119b0576119b05b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461058557600080fd5b8060060b811461058557600080fdfea2646970667358221220e31b6e4bcba9c7bdff81001ffe0761058a7c9175286970ab89be3f2061144c3d64736f6c63430008070033", + "numDeployments": 5, + "solcInputHash": "0d224f905ebe4be6830f2d07ee9fcf58", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_kp3r\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kp3rWethPool\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidOraclePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"Keep3rV2Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isKP3RToken0\",\"type\":\"bool\"}],\"name\":\"Kp3rWethPoolChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"MaxBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"MinBaseFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"MinBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"MinPriorityFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"QuoteTwapTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"TargetBondChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"WorkExtraGasChange\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BOOST_BASE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"KP3R\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountBonded\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityAmount\",\"type\":\"uint256\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getKP3RsAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3rAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getPaymentParams\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_boost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_oneEthQuote\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_extra\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"}],\"name\":\"getPoolTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token1\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_baseAmount\",\"type\":\"uint128\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getQuoteAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_quoteAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmountFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3r\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getRewardBoostFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardBoost\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"}],\"name\":\"isKP3RToken0\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isKP3RToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV2\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"kp3rWethPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isTKNToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBaseFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minPriorityFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"},{\"internalType\":\"uint32[]\",\"name\":\"_secondsAgo\",\"type\":\"uint32[]\"}],\"name\":\"observe\",\"outputs\":[{\"internalType\":\"int56\",\"name\":\"_tickCumulative1\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"_tickCumulative2\",\"type\":\"int56\"},{\"internalType\":\"bool\",\"name\":\"_success\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eth\",\"type\":\"uint256\"}],\"name\":\"quote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"quoteTwapTime\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"setKeep3rV2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddress\",\"type\":\"address\"}],\"name\":\"setKp3rWethPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"setMaxBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"setMinBaseFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"setMinBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"setMinPriorityFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"setQuoteTwapTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"setTargetBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"setWorkExtraGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetBond\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"workExtraGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bonds(address)\":{\"params\":{\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_amountBonded\":\"The amount of KP3R the keeper has bonded\"}},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"params\":{\"_liquidityAmount\":\"Amount of liquidity to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_kp3rAmount\":\"Amount of KP3R tokens underlying on the given liquidity\"}},\"getPaymentParams(uint256)\":{\"params\":{\"_bonds\":\"Amount of bonded KP3R owned by the keeper\"},\"returns\":{\"_boost\":\"Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\",\"_extra\":\"Amount of extra gas that should be added to the gas spent\",\"_oneEthQuote\":\"Amount of KP3R tokens equivalent to 1 ETH\"}},\"getPoolTokens(address)\":{\"params\":{\"_pool\":\"Address of the correspondant pool\"},\"returns\":{\"_token0\":\"Address of the first token of the pair\",\"_token1\":\"Address of the second token of the pair\"}},\"getQuoteAtTick(uint128,int56,uint256)\":{\"params\":{\"_baseAmount\":\"Amount of token to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_quoteAmount\":\"Amount of credits deserved for the baseAmount at the tick value\"}},\"getRewardAmount(uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\"},\"returns\":{\"_amount\":\"The amount of KP3R that should be awarded to tx.origin\"}},\"getRewardAmountFor(address,uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\",\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_kp3r\":\"The amount of KP3R that should be awarded to the keeper\"}},\"getRewardBoostFor(uint256)\":{\"details\":\"If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\",\"params\":{\"_bonds\":\"The amount of KP3R tokens bonded by the keeper\"},\"returns\":{\"_rewardBoost\":\"The reward boost that corresponds to the keeper\"}},\"isKP3RToken0(address)\":{\"params\":{\"_pool\":\"Address of the correspondant pool\"},\"returns\":{\"_isKP3RToken0\":\"Boolean indicating the order of the tokens in the pair\"}},\"observe(address,uint32[])\":{\"params\":{\"_pool\":\"Address of the pool to observe\",\"_secondsAgo\":\"Array with time references to observe\"},\"returns\":{\"_success\":\"Boolean indicating if the observe call was succesfull\",\"_tickCumulative1\":\"Cumulative sum of ticks until first time reference\",\"_tickCumulative2\":\"Cumulative sum of ticks until second time reference\"}},\"quote(uint256)\":{\"details\":\"This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\",\"params\":{\"_eth\":\"The amount of ETH\"},\"returns\":{\"_amountOut\":\"The amount of KP3R\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setKeep3rV2(address)\":{\"params\":{\"_keep3rV2\":\"The address of Keep3r V2\"}},\"setKp3rWethPool(address)\":{\"params\":{\"_poolAddress\":\"The address of the KP3R-WETH pool\"}},\"setMaxBoost(uint256)\":{\"params\":{\"_maxBoost\":\"The maximum boost multiplier\"}},\"setMinBaseFee(uint256)\":{\"params\":{\"_minBaseFee\":\"The minimum rewarded gas fee\"}},\"setMinBoost(uint256)\":{\"params\":{\"_minBoost\":\"The minimum boost multiplier\"}},\"setMinPriorityFee(uint256)\":{\"params\":{\"_minPriorityFee\":\"The minimum rewarded priority fee\"}},\"setQuoteTwapTime(uint32)\":{\"params\":{\"_quoteTwapTime\":\"The twap time for quoting\"}},\"setTargetBond(uint256)\":{\"params\":{\"_targetBond\":\"The target bond amount\"}},\"setWorkExtraGas(uint256)\":{\"params\":{\"_workExtraGas\":\"The work extra gas\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidOraclePool()\":[{\"notice\":\"Throws when pool does not have KP3R as token0 nor token1\"}],\"LiquidityPairInvalid()\":[{\"notice\":\"Throws when none of the tokens in the liquidity pair is KP3R\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"Keep3rV2Change(address)\":{\"notice\":\"Emitted when the Keep3r V2 address is changed\"},\"Kp3rWethPoolChange(address,bool)\":{\"notice\":\"Emitted when the kp3r weth pool is changed\"},\"MaxBoostChange(uint256)\":{\"notice\":\"Emitted when the maximum boost multiplier is changed\"},\"MinBaseFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded gas fee is changed\"},\"MinBoostChange(uint256)\":{\"notice\":\"Emitted when the minimum boost multiplier is changed\"},\"MinPriorityFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded priority fee is changed\"},\"QuoteTwapTimeChange(uint32)\":{\"notice\":\"Emitted when the quote twap time is changed\"},\"TargetBondChange(uint256)\":{\"notice\":\"Emitted when the target bond amount is changed\"},\"WorkExtraGasChange(uint256)\":{\"notice\":\"Emitted when the work extra gas amount is changed\"}},\"kind\":\"user\",\"methods\":{\"BOOST_BASE()\":{\"notice\":\"The boost base used to calculate the boost rewards for the keeper\"},\"KP3R()\":{\"notice\":\"Address of KP3R token\"},\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"bonds(address)\":{\"notice\":\"Returns the amount of KP3R the keeper has bonded\"},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"notice\":\"Given a tick and a liquidity amount, calculates the underlying KP3R tokens\"},\"getPaymentParams(uint256)\":{\"notice\":\"Get multiplier, quote, and extra, in order to calculate keeper payment\"},\"getPoolTokens(address)\":{\"notice\":\"Given a pool address, returns the underlying tokens of the pair\"},\"getQuoteAtTick(uint128,int56,uint256)\":{\"notice\":\"Given a tick and a token amount, calculates the output in correspondant token\"},\"getRewardAmount(uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\"},\"getRewardAmountFor(address,uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to a keeper for using gas\"},\"getRewardBoostFor(uint256)\":{\"notice\":\"Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"isKP3RToken0(address)\":{\"notice\":\"Defines the order of the tokens in the pair for twap calculations\"},\"keep3rV2()\":{\"notice\":\"Address of Keep3r V2\"},\"kp3rWethPool()\":{\"notice\":\"KP3R-WETH pool that is being used as oracle\"},\"maxBoost()\":{\"notice\":\"The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\"},\"minBaseFee()\":{\"notice\":\"The minimum base fee that is used to calculate keeper rewards\"},\"minBoost()\":{\"notice\":\"The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\"},\"minPriorityFee()\":{\"notice\":\"The minimum priority fee that is also rewarded for keepers\"},\"observe(address,uint32[])\":{\"notice\":\"Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"quote(uint256)\":{\"notice\":\"Calculates the amount of KP3R that corresponds to the ETH passed into the function\"},\"quoteTwapTime()\":{\"notice\":\"The twap time for quoting\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setKeep3rV2(address)\":{\"notice\":\"Sets the Keep3r V2 address\"},\"setKp3rWethPool(address)\":{\"notice\":\"Sets KP3R-WETH pool\"},\"setMaxBoost(uint256)\":{\"notice\":\"Sets the maximum boost multiplier\"},\"setMinBaseFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas fee\"},\"setMinBoost(uint256)\":{\"notice\":\"Sets the minimum boost multiplier\"},\"setMinPriorityFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas priority fee\"},\"setQuoteTwapTime(uint32)\":{\"notice\":\"Sets the quote twap time\"},\"setTargetBond(uint256)\":{\"notice\":\"Sets the target bond amount\"},\"setWorkExtraGas(uint256)\":{\"notice\":\"Sets the work extra gas amount\"},\"targetBond()\":{\"notice\":\"The targeted amount of bonded KP3Rs to max-up reward multiplier For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\"},\"workExtraGas()\":{\"notice\":\"The amount of unaccounted gas that is going to be added to keeper payments\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/testnet/Keep3rHelperForTestnet.sol\":\"Keep3rHelperForTestnet\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\nimport './pool/IUniswapV3PoolImmutables.sol';\\nimport './pool/IUniswapV3PoolState.sol';\\nimport './pool/IUniswapV3PoolDerivedState.sol';\\nimport './pool/IUniswapV3PoolActions.sol';\\nimport './pool/IUniswapV3PoolOwnerActions.sol';\\nimport './pool/IUniswapV3PoolEvents.sol';\\n\\n/// @title The interface for a Uniswap V3 Pool\\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\\n/// to the ERC20 specification\\n/// @dev The pool interface is broken up into many smaller pieces\\ninterface IUniswapV3Pool is\\n IUniswapV3PoolImmutables,\\n IUniswapV3PoolState,\\n IUniswapV3PoolDerivedState,\\n IUniswapV3PoolActions,\\n IUniswapV3PoolOwnerActions,\\n IUniswapV3PoolEvents\\n{\\n\\n}\\n\",\"keccak256\":\"0xfe6113d518466cd6652c85b111e01f33eb62157f49ae5ed7d5a3947a2044adb1\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissionless pool actions\\n/// @notice Contains pool methods that can be called by anyone\\ninterface IUniswapV3PoolActions {\\n /// @notice Sets the initial price for the pool\\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\\n function initialize(uint160 sqrtPriceX96) external;\\n\\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\\n /// @param recipient The address for which the liquidity will be created\\n /// @param tickLower The lower tick of the position in which to add liquidity\\n /// @param tickUpper The upper tick of the position in which to add liquidity\\n /// @param amount The amount of liquidity to mint\\n /// @param data Any data that should be passed through to the callback\\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n function mint(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount,\\n bytes calldata data\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Collects tokens owed to a position\\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\\n /// @param recipient The address which should receive the fees collected\\n /// @param tickLower The lower tick of the position for which to collect fees\\n /// @param tickUpper The upper tick of the position for which to collect fees\\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\\n /// @return amount0 The amount of fees collected in token0\\n /// @return amount1 The amount of fees collected in token1\\n function collect(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n\\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\\n /// @dev Fees must be collected separately via a call to #collect\\n /// @param tickLower The lower tick of the position for which to burn liquidity\\n /// @param tickUpper The upper tick of the position for which to burn liquidity\\n /// @param amount How much liquidity to burn\\n /// @return amount0 The amount of token0 sent to the recipient\\n /// @return amount1 The amount of token1 sent to the recipient\\n function burn(\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Swap token0 for token1, or token1 for token0\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\\n /// @param recipient The address to receive the output of the swap\\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\\n /// @param data Any data to be passed through to the callback\\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\\n /// @param recipient The address which will receive the token0 and token1 amounts\\n /// @param amount0 The amount of token0 to send\\n /// @param amount1 The amount of token1 to send\\n /// @param data Any data to be passed through to the callback\\n function flash(\\n address recipient,\\n uint256 amount0,\\n uint256 amount1,\\n bytes calldata data\\n ) external;\\n\\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\\n /// the input observationCardinalityNext.\\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0x9453dd0e7442188667d01d9b65de3f1e14e9511ff3e303179a15f6fc267f7634\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that is not stored\\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\\n/// blockchain. The functions here may have variable gas costs.\\ninterface IUniswapV3PoolDerivedState {\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\\n /// you must call it with secondsAgos = [3600, 0].\\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\\n /// timestamp\\n function observe(uint32[] calldata secondsAgos)\\n external\\n view\\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\\n\\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\\n /// snapshot is taken and the second snapshot is taken.\\n /// @param tickLower The lower tick of the range\\n /// @param tickUpper The upper tick of the range\\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\\n /// @return secondsInside The snapshot of seconds per liquidity for the range\\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\\n external\\n view\\n returns (\\n int56 tickCumulativeInside,\\n uint160 secondsPerLiquidityInsideX128,\\n uint32 secondsInside\\n );\\n}\\n\",\"keccak256\":\"0xe603ac5b17ecdee73ba2b27efdf386c257a19c14206e87eee77e2017b742d9e5\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Events emitted by a pool\\n/// @notice Contains all events emitted by the pool\\ninterface IUniswapV3PoolEvents {\\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\\n event Initialize(uint160 sqrtPriceX96, int24 tick);\\n\\n /// @notice Emitted when liquidity is minted for a given position\\n /// @param sender The address that minted the liquidity\\n /// @param owner The owner of the position and recipient of any minted liquidity\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity minted to the position range\\n /// @param amount0 How much token0 was required for the minted liquidity\\n /// @param amount1 How much token1 was required for the minted liquidity\\n event Mint(\\n address sender,\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted when fees are collected by the owner of a position\\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\\n /// @param owner The owner of the position for which fees are collected\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount0 The amount of token0 fees collected\\n /// @param amount1 The amount of token1 fees collected\\n event Collect(\\n address indexed owner,\\n address recipient,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount0,\\n uint128 amount1\\n );\\n\\n /// @notice Emitted when a position's liquidity is removed\\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\\n /// @param owner The owner of the position for which liquidity is removed\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity to remove\\n /// @param amount0 The amount of token0 withdrawn\\n /// @param amount1 The amount of token1 withdrawn\\n event Burn(\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted by the pool for any swaps between token0 and token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the output of the swap\\n /// @param amount0 The delta of the token0 balance of the pool\\n /// @param amount1 The delta of the token1 balance of the pool\\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param liquidity The liquidity of the pool after the swap\\n /// @param tick The log base 1.0001 of price of the pool after the swap\\n event Swap(\\n address indexed sender,\\n address indexed recipient,\\n int256 amount0,\\n int256 amount1,\\n uint160 sqrtPriceX96,\\n uint128 liquidity,\\n int24 tick\\n );\\n\\n /// @notice Emitted by the pool for any flashes of token0/token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the tokens from flash\\n /// @param amount0 The amount of token0 that was flashed\\n /// @param amount1 The amount of token1 that was flashed\\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\\n event Flash(\\n address indexed sender,\\n address indexed recipient,\\n uint256 amount0,\\n uint256 amount1,\\n uint256 paid0,\\n uint256 paid1\\n );\\n\\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\\n /// just before a mint/swap/burn.\\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(\\n uint16 observationCardinalityNextOld,\\n uint16 observationCardinalityNextNew\\n );\\n\\n /// @notice Emitted when the protocol fee is changed by the pool\\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\\n /// @param feeProtocol0New The updated value of the token0 protocol fee\\n /// @param feeProtocol1New The updated value of the token1 protocol fee\\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\\n\\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\\n /// @param sender The address that collects the protocol fees\\n /// @param recipient The address that receives the collected protocol fees\\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x8071514d0fe5d17d6fbd31c191cdfb703031c24e0ece3621d88ab10e871375cd\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that never changes\\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\\ninterface IUniswapV3PoolImmutables {\\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\\n /// @return The contract address\\n function factory() external view returns (address);\\n\\n /// @notice The first of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token0() external view returns (address);\\n\\n /// @notice The second of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token1() external view returns (address);\\n\\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\\n /// @return The fee\\n function fee() external view returns (uint24);\\n\\n /// @notice The pool tick spacing\\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\\n /// This value is an int24 to avoid casting even though it is always positive.\\n /// @return The tick spacing\\n function tickSpacing() external view returns (int24);\\n\\n /// @notice The maximum amount of position liquidity that can use any tick in the range\\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\\n /// @return The max amount of liquidity per tick\\n function maxLiquidityPerTick() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xf6e5d2cd1139c4c276bdbc8e1d2b256e456c866a91f1b868da265c6d2685c3f7\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissioned pool actions\\n/// @notice Contains pool methods that may only be called by the factory owner\\ninterface IUniswapV3PoolOwnerActions {\\n /// @notice Set the denominator of the protocol's % share of the fees\\n /// @param feeProtocol0 new protocol fee for token0 of the pool\\n /// @param feeProtocol1 new protocol fee for token1 of the pool\\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\\n\\n /// @notice Collect the protocol fee accrued to the pool\\n /// @param recipient The address to which collected protocol fees should be sent\\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\\n /// @return amount0 The protocol fee collected in token0\\n /// @return amount1 The protocol fee collected in token1\\n function collectProtocol(\\n address recipient,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x759b78a2918af9e99e246dc3af084f654e48ef32bb4e4cb8a966aa3dcaece235\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that can change\\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\\n/// per transaction\\ninterface IUniswapV3PoolState {\\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\\n /// when accessed externally.\\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\\n /// boundary.\\n /// observationIndex The index of the last oracle observation that was written,\\n /// observationCardinality The current maximum number of observations stored in the pool,\\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// feeProtocol The protocol fee for both tokens of the pool.\\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\\n /// unlocked Whether the pool is currently locked to reentrancy\\n function slot0()\\n external\\n view\\n returns (\\n uint160 sqrtPriceX96,\\n int24 tick,\\n uint16 observationIndex,\\n uint16 observationCardinality,\\n uint16 observationCardinalityNext,\\n uint8 feeProtocol,\\n bool unlocked\\n );\\n\\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal0X128() external view returns (uint256);\\n\\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal1X128() external view returns (uint256);\\n\\n /// @notice The amounts of token0 and token1 that are owed to the protocol\\n /// @dev Protocol fees will never exceed uint128 max in either token\\n function protocolFees() external view returns (uint128 token0, uint128 token1);\\n\\n /// @notice The currently in range liquidity available to the pool\\n /// @dev This value has no relationship to the total liquidity across all ticks\\n function liquidity() external view returns (uint128);\\n\\n /// @notice Look up information about a specific tick in the pool\\n /// @param tick The tick to look up\\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\\n /// tick upper,\\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\\n /// a specific position.\\n function ticks(int24 tick)\\n external\\n view\\n returns (\\n uint128 liquidityGross,\\n int128 liquidityNet,\\n uint256 feeGrowthOutside0X128,\\n uint256 feeGrowthOutside1X128,\\n int56 tickCumulativeOutside,\\n uint160 secondsPerLiquidityOutsideX128,\\n uint32 secondsOutside,\\n bool initialized\\n );\\n\\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\\n function tickBitmap(int16 wordPosition) external view returns (uint256);\\n\\n /// @notice Returns the information about a position by the position's key\\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\\n /// @return _liquidity The amount of liquidity in the position,\\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\\n function positions(bytes32 key)\\n external\\n view\\n returns (\\n uint128 _liquidity,\\n uint256 feeGrowthInside0LastX128,\\n uint256 feeGrowthInside1LastX128,\\n uint128 tokensOwed0,\\n uint128 tokensOwed1\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param index The element of the observations array to fetch\\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\\n /// ago, rather than at a specific index in the array.\\n /// @return blockTimestamp The timestamp of the observation,\\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// Returns initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 index)\\n external\\n view\\n returns (\\n uint32 blockTimestamp,\\n int56 tickCumulative,\\n uint160 secondsPerLiquidityCumulativeX128,\\n bool initialized\\n );\\n}\\n\",\"keccak256\":\"0x852dc1f5df7dcf7f11e7bb3eed79f0cea72ad4b25f6a9d2c35aafb48925fd49f\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/Keep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2003\\u2003\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2003\\u2003\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/IKeep3rHelper.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\\n\\n /// @inheritdoc IKeep3rHelper\\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\\n uint32[] memory _secondsAgos = new uint32[](2);\\n _secondsAgos[1] = quoteTwapTime;\\n\\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\\n // solhint-disable-next-line avoid-tx-origin\\n return getRewardAmountFor(tx.origin, _gasUsed);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\\n _bonds = Math.min(_bonds, targetBond);\\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\\n _rewardBoost = _cap * _getBasefee();\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\\n address _token0;\\n address _token1;\\n (_token0, _token1) = getPoolTokens(_pool);\\n if (_token0 == KP3R) {\\n return true;\\n } else if (_token1 != KP3R) {\\n revert LiquidityPairInvalid();\\n }\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n override\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n )\\n {\\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\\n _tickCumulative1 = _uniswapResponse[0];\\n if (_uniswapResponse.length > 1) {\\n _tickCumulative2 = _uniswapResponse[1];\\n }\\n _success = true;\\n } catch (bytes memory) {}\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n virtual\\n override\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n )\\n {\\n _oneEthQuote = quote(1 ether);\\n _boost = getRewardBoostFor(_bonds);\\n _extra = workExtraGas;\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure override returns (uint256 _kp3rAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) public pure override returns (uint256 _quoteAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n\\n if (sqrtRatioX96 <= type(uint128).max) {\\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\\n } else {\\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\\n }\\n }\\n\\n /// @notice Gets the gas basefee cost to calculate keeper rewards\\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\\n }\\n}\\n\",\"keccak256\":\"0x022987525462636329608fd3032553a123451854d6191d863f068de237302d17\",\"license\":\"MIT\"},\"solidity/contracts/Keep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/peripherals/IBaseErrors.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/external/IKeep3rV1.sol';\\nimport '../interfaces/IKeep3rHelperParameters.sol';\\nimport './peripherals/Governable.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\\n /// @inheritdoc IKeep3rHelperParameters\\n address public immutable override KP3R;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public constant override BOOST_BASE = 10_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBoost = 11_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override maxBoost = 12_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override targetBond = 200 ether;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override workExtraGas = 34_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint32 public override quoteTwapTime = 10 minutes;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBaseFee = 15e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minPriorityFee = 2e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n address public override keep3rV2;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\\n\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Governable(_governance) {\\n KP3R = _kp3r;\\n keep3rV2 = _keep3rV2;\\n\\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\\n if (_poolAddress == address(0)) revert ZeroAddress();\\n _setKp3rWethPool(_poolAddress);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\\n minBoost = _minBoost;\\n emit MinBoostChange(minBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\\n maxBoost = _maxBoost;\\n emit MaxBoostChange(maxBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\\n targetBond = _targetBond;\\n emit TargetBondChange(targetBond);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\\n if (_keep3rV2 == address(0)) revert ZeroAddress();\\n keep3rV2 = _keep3rV2;\\n emit Keep3rV2Change(keep3rV2);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\\n workExtraGas = _workExtraGas;\\n emit WorkExtraGasChange(workExtraGas);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\\n _setQuoteTwapTime(_quoteTwapTime);\\n }\\n\\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\\n quoteTwapTime = _quoteTwapTime;\\n emit QuoteTwapTimeChange(quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\\n minBaseFee = _minBaseFee;\\n emit MinBaseFeeChange(minBaseFee);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\\n minPriorityFee = _minPriorityFee;\\n emit MinPriorityFeeChange(minPriorityFee);\\n }\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function _setKp3rWethPool(address _poolAddress) internal {\\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\\n }\\n\\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\\n\\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\\n\\n return TokenOraclePool(_poolAddress, _isTKNToken0);\\n }\\n}\\n\",\"keccak256\":\"0xff1d1cdd8acec9bed3ac67c0980c1e211e6e09483e30a090c05ed4698a5c0dd4\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n// solhint-disable\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\\n\\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n // Second inequality must be < because the price can never reach the price at the max tick\\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n}\\n\",\"keccak256\":\"0x11b965ba576ff91b4a6e9533c0f334f2b7b6024ee1c54e36d21799de5580899d\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/for-test/testnet/Keep3rHelperForTestnet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../contracts/Keep3rHelper.sol';\\n\\ncontract Keep3rHelperForTestnet is Keep3rHelper {\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\\n\\n function _getBasefee() internal pure override returns (uint256) {\\n return 1;\\n }\\n}\\n\",\"keccak256\":\"0x81fa0474c36c30674ca643a4829295d512573e7ad61b88024385887ee795f799\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct TokenOraclePool {\\n address poolAddress;\\n bool isTKNToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0x76f99ca04361c0459fc9e99f0387ddb76da18cc470ec5bc744e7dc3bf6e9d334\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0xf4748c236ddf409e45e7169c735e2fc54e627b2b3ccd189ebb438ad768f1deb1\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a0604052612af8600255612ee0600355680ad78ebc5ac62000006004556184d06005556006805463ffffffff191661025817905564037e11d60060075563773594006008553480156200005257600080fd5b50604051620020a2380380620020a2833981016040819052620000759162000338565b8383838383838383816001600160a01b038116620000a55760405162b293ed60e81b815260040160405180910390fd5b600080546001600160a01b03199081166001600160a01b0393841617909155606086901b6001600160601b03191660805260098054909116918516919091179055620000f281856200017c565b8051600a80546020938401511515600160a01b9081026001600160a81b03199092166001600160a01b03948516179190911791829055604080519383168452910460ff161515928201929092527f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf4108910160405180910390a150505050505050505050505062000395565b60408051808201909152600080825260208201526000826001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015620001d657600080fd5b505afa158015620001eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000211919062000313565b6001600160a01b0316149050801581620002b15750826001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156200026a57600080fd5b505afa1580156200027f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002a5919062000313565b6001600160a01b031614155b15620002d05760405163db60809d60e01b815260040160405180910390fd5b604080518082019091526001600160a01b03851681529015156020820152905092915050565b80516001600160a01b03811681146200030e57600080fd5b919050565b6000602082840312156200032657600080fd5b6200033182620002f6565b9392505050565b600080600080608085870312156200034f57600080fd5b6200035a85620002f6565b93506200036a60208601620002f6565b92506200037a60408601620002f6565b91506200038a60608601620002f6565b905092959194509250565b60805160601c611cd2620003d0600039600081816101bb015281816108450152818161088901528181610f1b0152610f990152611cd26000f3fe608060405234801561001057600080fd5b50600436106101b15760003560e01c80637b40c913116100f55780637b40c9131461032b5780638561579c146103585780638a9b1b09146103615780639aaad6791461036a578063a0d271071461038f578063a62611a2146103a2578063ab033ea9146103ab578063ab5dce00146103be578063ab8cedc5146103d1578063b2e0df96146103e4578063b93f5af0146103f7578063c84993af1461040a578063ca4f28031461041d578063dc686d911461043e578063e244208b14610476578063ed1bd76c14610489578063f39c38a01461049c578063fe10d774146104af57600080fd5b806305e0b9a0146101b65780630c525835146101f3578063117cfc1b14610208578063160e1e311461021b5780632248e82d1461022e578063238efcbc1461024f57806325f09e61146102575780632742b9e714610260578063289adb441461026957806337090c2f1461027c5780633cc7ab30146102855780633facf24214610298578063435b21c1146102a1578063516c3323146102cf5780635aa6e675146102e2578063607e48d4146102f5578063696a437b14610308575b600080fd5b6101dd7f000000000000000000000000000000000000000000000000000000000000000081565b6040516101ea91906119ec565b60405180910390f35b610206610201366004611978565b6104c2565b005b6009546101dd906001600160a01b031681565b610206610229366004611747565b610529565b61024161023c366004611834565b610587565b6040519081526020016101ea565b6102066105ba565b61024161271081565b61024160045481565b610206610277366004611978565b610646565b61024160035481565b610206610293366004611747565b6106a6565b61024160055481565b6102b46102af366004611978565b610744565b604080519384526020840192909252908201526060016101ea565b6102416102dd366004611978565b610772565b6000546101dd906001600160a01b031681565b610206610303366004611978565b6107cd565b61031b610316366004611747565b61082d565b60405190151581526020016101ea565b600a5461034a906001600160a01b03811690600160a01b900460ff1682565b6040516101ea929190611a1a565b61024160025481565b61024160085481565b60065461037a9063ffffffff1681565b60405163ffffffff90911681526020016101ea565b61024161039d3660046119aa565b6108e0565b61024160075481565b6102066103b9366004611747565b61091c565b6102066103cc366004611978565b610992565b6102416103df36600461192b565b6109f2565b6102066103f2366004611978565b610a96565b6102066104053660046119d1565b610af6565b610241610418366004611978565b610b2a565b61043061042b366004611747565b610b3c565b6040516101ea929190611a00565b61045161044c366004611781565b610c2a565b60408051600694850b81529290930b60208301521515918101919091526060016101ea565b610206610484366004611978565b610d35565b610241610497366004611978565b610d95565b6001546101dd906001600160a01b031681565b6102416104bd366004611747565b610ef0565b6000546001600160a01b031633146104ed576040516354348f0360e01b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b03163314610554576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661057b5760405163d92e233d60e01b815260040160405180910390fd5b61058481610f93565b50565b6000806105966102dd85610ef0565b90506105b26127106105a88386611b2c565b6104979190611b18565b949350505050565b6001546001600160a01b031633146105e557604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161063c916119ec565b60405180910390a1565b6000546001600160a01b03163314610671576040516354348f0360e01b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b9060200161051e565b6000546001600160a01b031633146106d1576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166106f85760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a9161051e916119ec565b600080600061075a670de0b6b3a7640000610d95565b915061076584610772565b6005549095929450925050565b600061078082600454611029565b91506000600454836002546003546107989190611b9b565b6107a29190611b2c565b6107ac9190611b18565b6002546107b99190611ad2565b90506107c6600182611b2c565b9392505050565b6000546001600160a01b031633146107f8576040516354348f0360e01b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b9060200161051e565b600080600061083b84610b3c565b80925081935050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610887575060019392505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316146108d957604051637d7c8f2760e11b815260040160405180910390fd5b5050919050565b6000806108f96108f484600687900b611aea565b61103f565b9050610913600160601b86836001600160a01b031661144d565b95945050505050565b6000546001600160a01b03163314610947576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f9061051e9083906119ec565b6000546001600160a01b031633146109bd576040516354348f0360e01b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e9060200161051e565b600080610a066108f484600687900b611aea565b90506001600160801b036001600160a01b03821611610a56576000610a346001600160a01b03831680611b2c565b9050610a4e600160c01b876001600160801b03168361144d565b925050610a8e565b6000610a706001600160a01b03831680600160401b61144d565b9050610a8a600160801b876001600160801b03168361144d565b9250505b509392505050565b6000546001600160a01b03163314610ac1576040516354348f0360e01b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa9060200161051e565b6000546001600160a01b03163314610b21576040516354348f0360e01b815260040160405180910390fd5b610584816114fb565b6000610b363283610587565b92915050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610b7857600080fd5b505afa158015610b8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb09190611764565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610be957600080fd5b505afa158015610bfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c219190611764565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b8152600401610c5b9190611a35565b60006040518083038186803b158015610c7357600080fd5b505afa925050508015610ca857506040513d6000823e601f3d908101601f19168201604052610ca59190810190611860565b60015b610ce2573d808015610cd6576040519150601f19603f3d011682016040523d82523d6000602084013e610cdb565b606091505b5050610d2e565b81600081518110610cf557610cf5611c4c565b60200260200101519450600182511115610d275781600181518110610d1c57610d1c611c4c565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b03163314610d60576040516354348f0360e01b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d541592219060200161051e565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff16918391506001908110610dd957610dd9611c4c565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd90610e1f908590600401611a35565b60006040518083038186803b158015610e3757600080fd5b505afa158015610e4b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e739190810190611860565b509050600081600181518110610e8b57610e8b611c4c565b602002602001015182600081518110610ea657610ea6611c4c565b6020026020010151610eb89190611b4b565b600a54909150610913908690600160a01b900460ff16610ee057610edb83611c06565b610ee2565b825b60065463ffffffff166109f2565b60095460405163a39744b560e01b81526000916001600160a01b03169063a39744b590610f439085907f000000000000000000000000000000000000000000000000000000000000000090600401611a00565b60206040518083038186803b158015610f5b57600080fd5b505afa158015610f6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190611991565b610fbd817f0000000000000000000000000000000000000000000000000000000000000000611543565b8051600a80546020909301511515600160a01b9081026001600160a81b03199094166001600160a01b039384161793909317908190556040517f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf41089361051e938316920460ff1690611a1a565b600081831061103857816107c6565b5090919050565b60008060008360020b12611056578260020b611063565b8260020b61106390611be9565b9050611072620d89e719611bc6565b60020b8111156110ac5760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b6000600182166110c057600160801b6110d2565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b031690506002821615611107576080611102826ffff97272373d413259a46990580e213a611b2c565b901c90505b600482161561113157608061112c826ffff2e50f5f656932ef12357cf3c7fdcc611b2c565b901c90505b600882161561115b576080611156826fffe5caca7e10e4e61c3624eaa0941cd0611b2c565b901c90505b6010821615611185576080611180826fffcb9843d60f6159c9db58835c926644611b2c565b901c90505b60208216156111af5760806111aa826fff973b41fa98c081472e6896dfb254c0611b2c565b901c90505b60408216156111d95760806111d4826fff2ea16466c96a3843ec78b326b52861611b2c565b901c90505b60808216156112035760806111fe826ffe5dee046a99a2a811c461f1969c3053611b2c565b901c90505b61010082161561122e576080611229826ffcbe86c7900a88aedcffc83b479aa3a4611b2c565b901c90505b610200821615611259576080611254826ff987a7253ac413176f2b074cf7815e54611b2c565b901c90505b61040082161561128457608061127f826ff3392b0822b70005940c7a398e4b70f3611b2c565b901c90505b6108008216156112af5760806112aa826fe7159475a2c29b7443b29c7fa6e889d9611b2c565b901c90505b6110008216156112da5760806112d5826fd097f3bdfd2022b8845ad8f792aa5825611b2c565b901c90505b612000821615611305576080611300826fa9f746462d870fdf8a65dc1f90e061e5611b2c565b901c90505b61400082161561133057608061132b826f70d869a156d2a1b890bb3df62baf32f7611b2c565b901c90505b61800082161561135b576080611356826f31be135f97d08fd981231505542fcfa6611b2c565b901c90505b62010000821615611387576080611382826f09aa508b5b7a84e1c677de54f3e99bc9611b2c565b901c90505b620200008216156113b25760806113ad826e5d6af8dedb81196699c329225ee604611b2c565b901c90505b620400008216156113dc5760806113d7826d2216e584f5fa1ea926041bedfe98611b2c565b901c90505b620800008216156114045760806113ff826b048a170391f7dc42444e8fa2611b2c565b901c90505b60008460020b131561141f5761141c81600019611b18565b90505b61142d600160201b82611bb2565b1561143957600161143c565b60005b6105b29060ff16602083901c611ad2565b600080806000198587098587029250828110838203039150508060001415611487576000841161147c57600080fd5b5082900490506107c6565b80841161149357600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de9060200161051e565b60408051808201909152600080825260208201526000826001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561159c57600080fd5b505afa1580156115b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d49190611764565b6001600160a01b031614905080158161166f5750826001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561162b57600080fd5b505afa15801561163f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116639190611764565b6001600160a01b031614155b1561168d5760405163db60809d60e01b815260040160405180910390fd5b604080518082019091526001600160a01b03851681529015156020820152905092915050565b600082601f8301126116c457600080fd5b815160206116d96116d483611aaf565b611a7f565b80838252828201915082860187848660051b89010111156116f957600080fd5b60005b8581101561172157815161170f81611c78565b845292840192908401906001016116fc565b5090979650505050505050565b803563ffffffff8116811461174257600080fd5b919050565b60006020828403121561175957600080fd5b81356107c681611c78565b60006020828403121561177657600080fd5b81516107c681611c78565b6000806040838503121561179457600080fd5b823561179f81611c78565b91506020838101356001600160401b038111156117bb57600080fd5b8401601f810186136117cc57600080fd5b80356117da6116d482611aaf565b80828252848201915084840189868560051b87010111156117fa57600080fd5b600094505b83851015611824576118108161172e565b8352600194909401939185019185016117ff565b5080955050505050509250929050565b6000806040838503121561184757600080fd5b823561185281611c78565b946020939093013593505050565b6000806040838503121561187357600080fd5b82516001600160401b038082111561188a57600080fd5b818501915085601f83011261189e57600080fd5b815160206118ae6116d483611aaf565b8083825282820191508286018a848660051b89010111156118ce57600080fd5b600096505b848710156118fa5780516118e681611c8d565b8352600196909601959183019183016118d3565b509188015191965090935050508082111561191457600080fd5b50611921858286016116b3565b9150509250929050565b60008060006060848603121561194057600080fd5b83356001600160801b038116811461195757600080fd5b9250602084013561196781611c8d565b929592945050506040919091013590565b60006020828403121561198a57600080fd5b5035919050565b6000602082840312156119a357600080fd5b5051919050565b6000806000606084860312156119bf57600080fd5b83359250602084013561196781611c8d565b6000602082840312156119e357600080fd5b6107c68261172e565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015611a7357835163ffffffff1683529284019291840191600101611a51565b50909695505050505050565b604051601f8201601f191681016001600160401b0381118282101715611aa757611aa7611c62565b604052919050565b60006001600160401b03821115611ac857611ac8611c62565b5060051b60200190565b60008219821115611ae557611ae5611c20565b500190565b600082611af957611af9611c36565b600160ff1b821460001984141615611b1357611b13611c20565b500590565b600082611b2757611b27611c36565b500490565b6000816000190483118215151615611b4657611b46611c20565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615611b7657611b76611c20565b81667fffffffffffff018313811615611b9157611b91611c20565b5090039392505050565b600082821015611bad57611bad611c20565b500390565b600082611bc157611bc1611c36565b500690565b60008160020b627fffff19811415611be057611be0611c20565b60000392915050565b6000600160ff1b821415611bff57611bff611c20565b5060000390565b60008160060b667fffffffffffff19811415611be057611be05b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461058457600080fd5b8060060b811461058457600080fdfea26469706673582212206e7e541d05de3a39e3b8273e581d49a50f28c8d6663aa5f7a97550d7d9ba5a1364736f6c63430008070033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101b15760003560e01c80637b40c913116100f55780637b40c9131461032b5780638561579c146103585780638a9b1b09146103615780639aaad6791461036a578063a0d271071461038f578063a62611a2146103a2578063ab033ea9146103ab578063ab5dce00146103be578063ab8cedc5146103d1578063b2e0df96146103e4578063b93f5af0146103f7578063c84993af1461040a578063ca4f28031461041d578063dc686d911461043e578063e244208b14610476578063ed1bd76c14610489578063f39c38a01461049c578063fe10d774146104af57600080fd5b806305e0b9a0146101b65780630c525835146101f3578063117cfc1b14610208578063160e1e311461021b5780632248e82d1461022e578063238efcbc1461024f57806325f09e61146102575780632742b9e714610260578063289adb441461026957806337090c2f1461027c5780633cc7ab30146102855780633facf24214610298578063435b21c1146102a1578063516c3323146102cf5780635aa6e675146102e2578063607e48d4146102f5578063696a437b14610308575b600080fd5b6101dd7f000000000000000000000000000000000000000000000000000000000000000081565b6040516101ea91906119ec565b60405180910390f35b610206610201366004611978565b6104c2565b005b6009546101dd906001600160a01b031681565b610206610229366004611747565b610529565b61024161023c366004611834565b610587565b6040519081526020016101ea565b6102066105ba565b61024161271081565b61024160045481565b610206610277366004611978565b610646565b61024160035481565b610206610293366004611747565b6106a6565b61024160055481565b6102b46102af366004611978565b610744565b604080519384526020840192909252908201526060016101ea565b6102416102dd366004611978565b610772565b6000546101dd906001600160a01b031681565b610206610303366004611978565b6107cd565b61031b610316366004611747565b61082d565b60405190151581526020016101ea565b600a5461034a906001600160a01b03811690600160a01b900460ff1682565b6040516101ea929190611a1a565b61024160025481565b61024160085481565b60065461037a9063ffffffff1681565b60405163ffffffff90911681526020016101ea565b61024161039d3660046119aa565b6108e0565b61024160075481565b6102066103b9366004611747565b61091c565b6102066103cc366004611978565b610992565b6102416103df36600461192b565b6109f2565b6102066103f2366004611978565b610a96565b6102066104053660046119d1565b610af6565b610241610418366004611978565b610b2a565b61043061042b366004611747565b610b3c565b6040516101ea929190611a00565b61045161044c366004611781565b610c2a565b60408051600694850b81529290930b60208301521515918101919091526060016101ea565b610206610484366004611978565b610d35565b610241610497366004611978565b610d95565b6001546101dd906001600160a01b031681565b6102416104bd366004611747565b610ef0565b6000546001600160a01b031633146104ed576040516354348f0360e01b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b03163314610554576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661057b5760405163d92e233d60e01b815260040160405180910390fd5b61058481610f93565b50565b6000806105966102dd85610ef0565b90506105b26127106105a88386611b2c565b6104979190611b18565b949350505050565b6001546001600160a01b031633146105e557604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161063c916119ec565b60405180910390a1565b6000546001600160a01b03163314610671576040516354348f0360e01b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b9060200161051e565b6000546001600160a01b031633146106d1576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166106f85760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a9161051e916119ec565b600080600061075a670de0b6b3a7640000610d95565b915061076584610772565b6005549095929450925050565b600061078082600454611029565b91506000600454836002546003546107989190611b9b565b6107a29190611b2c565b6107ac9190611b18565b6002546107b99190611ad2565b90506107c6600182611b2c565b9392505050565b6000546001600160a01b031633146107f8576040516354348f0360e01b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b9060200161051e565b600080600061083b84610b3c565b80925081935050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610887575060019392505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316146108d957604051637d7c8f2760e11b815260040160405180910390fd5b5050919050565b6000806108f96108f484600687900b611aea565b61103f565b9050610913600160601b86836001600160a01b031661144d565b95945050505050565b6000546001600160a01b03163314610947576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f9061051e9083906119ec565b6000546001600160a01b031633146109bd576040516354348f0360e01b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e9060200161051e565b600080610a066108f484600687900b611aea565b90506001600160801b036001600160a01b03821611610a56576000610a346001600160a01b03831680611b2c565b9050610a4e600160c01b876001600160801b03168361144d565b925050610a8e565b6000610a706001600160a01b03831680600160401b61144d565b9050610a8a600160801b876001600160801b03168361144d565b9250505b509392505050565b6000546001600160a01b03163314610ac1576040516354348f0360e01b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa9060200161051e565b6000546001600160a01b03163314610b21576040516354348f0360e01b815260040160405180910390fd5b610584816114fb565b6000610b363283610587565b92915050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610b7857600080fd5b505afa158015610b8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb09190611764565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610be957600080fd5b505afa158015610bfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c219190611764565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b8152600401610c5b9190611a35565b60006040518083038186803b158015610c7357600080fd5b505afa925050508015610ca857506040513d6000823e601f3d908101601f19168201604052610ca59190810190611860565b60015b610ce2573d808015610cd6576040519150601f19603f3d011682016040523d82523d6000602084013e610cdb565b606091505b5050610d2e565b81600081518110610cf557610cf5611c4c565b60200260200101519450600182511115610d275781600181518110610d1c57610d1c611c4c565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b03163314610d60576040516354348f0360e01b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d541592219060200161051e565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff16918391506001908110610dd957610dd9611c4c565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd90610e1f908590600401611a35565b60006040518083038186803b158015610e3757600080fd5b505afa158015610e4b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e739190810190611860565b509050600081600181518110610e8b57610e8b611c4c565b602002602001015182600081518110610ea657610ea6611c4c565b6020026020010151610eb89190611b4b565b600a54909150610913908690600160a01b900460ff16610ee057610edb83611c06565b610ee2565b825b60065463ffffffff166109f2565b60095460405163a39744b560e01b81526000916001600160a01b03169063a39744b590610f439085907f000000000000000000000000000000000000000000000000000000000000000090600401611a00565b60206040518083038186803b158015610f5b57600080fd5b505afa158015610f6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190611991565b610fbd817f0000000000000000000000000000000000000000000000000000000000000000611543565b8051600a80546020909301511515600160a01b9081026001600160a81b03199094166001600160a01b039384161793909317908190556040517f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf41089361051e938316920460ff1690611a1a565b600081831061103857816107c6565b5090919050565b60008060008360020b12611056578260020b611063565b8260020b61106390611be9565b9050611072620d89e719611bc6565b60020b8111156110ac5760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b6000600182166110c057600160801b6110d2565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b031690506002821615611107576080611102826ffff97272373d413259a46990580e213a611b2c565b901c90505b600482161561113157608061112c826ffff2e50f5f656932ef12357cf3c7fdcc611b2c565b901c90505b600882161561115b576080611156826fffe5caca7e10e4e61c3624eaa0941cd0611b2c565b901c90505b6010821615611185576080611180826fffcb9843d60f6159c9db58835c926644611b2c565b901c90505b60208216156111af5760806111aa826fff973b41fa98c081472e6896dfb254c0611b2c565b901c90505b60408216156111d95760806111d4826fff2ea16466c96a3843ec78b326b52861611b2c565b901c90505b60808216156112035760806111fe826ffe5dee046a99a2a811c461f1969c3053611b2c565b901c90505b61010082161561122e576080611229826ffcbe86c7900a88aedcffc83b479aa3a4611b2c565b901c90505b610200821615611259576080611254826ff987a7253ac413176f2b074cf7815e54611b2c565b901c90505b61040082161561128457608061127f826ff3392b0822b70005940c7a398e4b70f3611b2c565b901c90505b6108008216156112af5760806112aa826fe7159475a2c29b7443b29c7fa6e889d9611b2c565b901c90505b6110008216156112da5760806112d5826fd097f3bdfd2022b8845ad8f792aa5825611b2c565b901c90505b612000821615611305576080611300826fa9f746462d870fdf8a65dc1f90e061e5611b2c565b901c90505b61400082161561133057608061132b826f70d869a156d2a1b890bb3df62baf32f7611b2c565b901c90505b61800082161561135b576080611356826f31be135f97d08fd981231505542fcfa6611b2c565b901c90505b62010000821615611387576080611382826f09aa508b5b7a84e1c677de54f3e99bc9611b2c565b901c90505b620200008216156113b25760806113ad826e5d6af8dedb81196699c329225ee604611b2c565b901c90505b620400008216156113dc5760806113d7826d2216e584f5fa1ea926041bedfe98611b2c565b901c90505b620800008216156114045760806113ff826b048a170391f7dc42444e8fa2611b2c565b901c90505b60008460020b131561141f5761141c81600019611b18565b90505b61142d600160201b82611bb2565b1561143957600161143c565b60005b6105b29060ff16602083901c611ad2565b600080806000198587098587029250828110838203039150508060001415611487576000841161147c57600080fd5b5082900490506107c6565b80841161149357600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de9060200161051e565b60408051808201909152600080825260208201526000826001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561159c57600080fd5b505afa1580156115b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d49190611764565b6001600160a01b031614905080158161166f5750826001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561162b57600080fd5b505afa15801561163f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116639190611764565b6001600160a01b031614155b1561168d5760405163db60809d60e01b815260040160405180910390fd5b604080518082019091526001600160a01b03851681529015156020820152905092915050565b600082601f8301126116c457600080fd5b815160206116d96116d483611aaf565b611a7f565b80838252828201915082860187848660051b89010111156116f957600080fd5b60005b8581101561172157815161170f81611c78565b845292840192908401906001016116fc565b5090979650505050505050565b803563ffffffff8116811461174257600080fd5b919050565b60006020828403121561175957600080fd5b81356107c681611c78565b60006020828403121561177657600080fd5b81516107c681611c78565b6000806040838503121561179457600080fd5b823561179f81611c78565b91506020838101356001600160401b038111156117bb57600080fd5b8401601f810186136117cc57600080fd5b80356117da6116d482611aaf565b80828252848201915084840189868560051b87010111156117fa57600080fd5b600094505b83851015611824576118108161172e565b8352600194909401939185019185016117ff565b5080955050505050509250929050565b6000806040838503121561184757600080fd5b823561185281611c78565b946020939093013593505050565b6000806040838503121561187357600080fd5b82516001600160401b038082111561188a57600080fd5b818501915085601f83011261189e57600080fd5b815160206118ae6116d483611aaf565b8083825282820191508286018a848660051b89010111156118ce57600080fd5b600096505b848710156118fa5780516118e681611c8d565b8352600196909601959183019183016118d3565b509188015191965090935050508082111561191457600080fd5b50611921858286016116b3565b9150509250929050565b60008060006060848603121561194057600080fd5b83356001600160801b038116811461195757600080fd5b9250602084013561196781611c8d565b929592945050506040919091013590565b60006020828403121561198a57600080fd5b5035919050565b6000602082840312156119a357600080fd5b5051919050565b6000806000606084860312156119bf57600080fd5b83359250602084013561196781611c8d565b6000602082840312156119e357600080fd5b6107c68261172e565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015611a7357835163ffffffff1683529284019291840191600101611a51565b50909695505050505050565b604051601f8201601f191681016001600160401b0381118282101715611aa757611aa7611c62565b604052919050565b60006001600160401b03821115611ac857611ac8611c62565b5060051b60200190565b60008219821115611ae557611ae5611c20565b500190565b600082611af957611af9611c36565b600160ff1b821460001984141615611b1357611b13611c20565b500590565b600082611b2757611b27611c36565b500490565b6000816000190483118215151615611b4657611b46611c20565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615611b7657611b76611c20565b81667fffffffffffff018313811615611b9157611b91611c20565b5090039392505050565b600082821015611bad57611bad611c20565b500390565b600082611bc157611bc1611c36565b500690565b60008160020b627fffff19811415611be057611be0611c20565b60000392915050565b6000600160ff1b821415611bff57611bff611c20565b5060000390565b60008160060b667fffffffffffff19811415611be057611be05b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461058457600080fd5b8060060b811461058457600080fdfea26469706673582212206e7e541d05de3a39e3b8273e581d49a50f28c8d6663aa5f7a97550d7d9ba5a1364736f6c63430008070033", "devdoc": { "kind": "dev", "methods": { @@ -899,7 +899,12 @@ } }, "isKP3RToken0(address)": { - "details": "Overrides token comparison with KP3R address" + "params": { + "_pool": "Address of the correspondant pool" + }, + "returns": { + "_isKP3RToken0": "Boolean indicating the order of the tokens in the pair" + } }, "observe(address,uint32[])": { "params": { @@ -1080,6 +1085,9 @@ "governance()": { "notice": "Stores the governance address" }, + "isKP3RToken0(address)": { + "notice": "Defines the order of the tokens in the pair for twap calculations" + }, "keep3rV2()": { "notice": "Address of Keep3r V2" }, @@ -1152,7 +1160,7 @@ "storageLayout": { "storage": [ { - "astId": 5374, + "astId": 5362, "contract": "solidity/for-test/testnet/Keep3rHelperForTestnet.sol:Keep3rHelperForTestnet", "label": "governance", "offset": 0, @@ -1160,7 +1168,7 @@ "type": "t_address" }, { - "astId": 5378, + "astId": 5366, "contract": "solidity/for-test/testnet/Keep3rHelperForTestnet.sol:Keep3rHelperForTestnet", "label": "pendingGovernance", "offset": 0, @@ -1237,7 +1245,7 @@ "label": "kp3rWethPool", "offset": 0, "slot": "10", - "type": "t_struct(TokenOraclePool)12958_storage" + "type": "t_struct(TokenOraclePool)12811_storage" } ], "types": { @@ -1251,12 +1259,12 @@ "label": "bool", "numberOfBytes": "1" }, - "t_struct(TokenOraclePool)12958_storage": { + "t_struct(TokenOraclePool)12811_storage": { "encoding": "inplace", "label": "struct IKeep3rHelperParameters.TokenOraclePool", "members": [ { - "astId": 12955, + "astId": 12808, "contract": "solidity/for-test/testnet/Keep3rHelperForTestnet.sol:Keep3rHelperForTestnet", "label": "poolAddress", "offset": 0, @@ -1264,7 +1272,7 @@ "type": "t_address" }, { - "astId": 12957, + "astId": 12810, "contract": "solidity/for-test/testnet/Keep3rHelperForTestnet.sol:Keep3rHelperForTestnet", "label": "isTKNToken0", "offset": 20, diff --git a/deployments/goerli/UniV3Factory.json b/deployments/goerli/UniV3Factory.json index d7887a8..6f35160 100644 --- a/deployments/goerli/UniV3Factory.json +++ b/deployments/goerli/UniV3Factory.json @@ -198,5 +198,5 @@ "type": "function" } ], - "numDeployments": 2 + "numDeployments": 3 } \ No newline at end of file diff --git a/deployments/goerli/UniV3Pool.json b/deployments/goerli/UniV3Pool.json index 69207dc..f513052 100644 --- a/deployments/goerli/UniV3Pool.json +++ b/deployments/goerli/UniV3Pool.json @@ -983,5 +983,5 @@ "type": "function" } ], - "numDeployments": 2 + "numDeployments": 3 } \ No newline at end of file diff --git a/deployments/goerli/WETH.json b/deployments/goerli/WETH.json index c2c600c..ad60f60 100644 --- a/deployments/goerli/WETH.json +++ b/deployments/goerli/WETH.json @@ -413,5 +413,5 @@ "type": "function" } ], - "numDeployments": 2 + "numDeployments": 3 } \ No newline at end of file diff --git a/deployments/goerli/solcInputs/0100086ed88435cb002327f6c69d11e5.json b/deployments/goerli/solcInputs/0100086ed88435cb002327f6c69d11e5.json new file mode 100644 index 0000000..1f9c5fc --- /dev/null +++ b/deployments/goerli/solcInputs/0100086ed88435cb002327f6c69d11e5.json @@ -0,0 +1,334 @@ +{ + "language": "Solidity", + "sources": { + "solidity/contracts/Keep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport './peripherals/jobs/Keep3rJobs.sol';\nimport './peripherals/keepers/Keep3rKeepers.sol';\nimport './peripherals/DustCollector.sol';\n\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\n}\n" + }, + "solidity/interfaces/IKeep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobManager.sol';\nimport './Keep3rJobWorkable.sol';\nimport './Keep3rJobDisputable.sol';\n\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\nimport './Keep3rKeeperDisputable.sol';\n\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\n" + }, + "solidity/contracts/peripherals/DustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '../../contracts/peripherals/Governable.sol';\nimport '../../interfaces/peripherals/IDustCollector.sol';\n\nabstract contract DustCollector is IDustCollector, Governable {\n using SafeERC20 for IERC20;\n\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external override onlyGovernance {\n if (_to == address(0)) revert ZeroAddress();\n if (_token == _ETH_ADDRESS) {\n payable(_to).transfer(_amount);\n } else {\n IERC20(_token).safeTransfer(_to, _amount);\n }\n emit DustSent(_token, _amount, _to);\n }\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" + }, + "solidity/interfaces/peripherals/IBaseErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" + }, + "solidity/interfaces/peripherals/IGovernable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" + }, + "solidity/interfaces/peripherals/IDustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @inheritdoc IKeep3rJobManager\n function addJob(address _job) external override {\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\n if (hasBonded[_job]) revert AlreadyAKeeper();\n _jobs.add(_job);\n jobOwner[_job] = msg.sender;\n emit JobAddition(_job, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobMigration.sol';\nimport '../../../interfaces/IKeep3rHelper.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 internal _initialGas;\n\n /// @inheritdoc IKeep3rJobWorkable\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\n _initialGas = _getGasLeft();\n if (_keepers.contains(_keeper)) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external override returns (bool _isBondedKeeper) {\n _initialGas = _getGasLeft();\n if (\n _keepers.contains(_keeper) &&\n bonds[_keeper][_bond] >= _minBond &&\n workCompleted[_keeper] >= _earned &&\n block.timestamp - firstSeen[_keeper] >= _age\n ) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function worked(address _keeper) external virtual override {\n if (_initialGas == 0) revert GasNotInitialized();\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _gasLeft = _getGasLeft();\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n _gasLeft = _getGasLeft();\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function bondedPayment(address _keeper, uint256 _payment) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (disputes[_keeper]) revert Disputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_keeper, _amount);\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\n }\n\n function _bondedPayment(\n address _job,\n address _keeper,\n uint256 _payment\n ) internal {\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\n\n workedAt[_job] = block.timestamp;\n _jobLiquidityCredits[_job] -= _payment;\n bonds[_keeper][keep3rV1] += _payment;\n workCompleted[_keeper] += _payment;\n totalBonds += _payment;\n }\n\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\n /// @param _gasLeft Amount of gas left after working the job\n /// @param _extraGas Amount of expected unaccounted gas\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\n /// @return _payment Amount to be payed in KP3R tokens\n function _calculatePayment(\n uint256 _gasLeft,\n uint256 _extraGas,\n uint256 _oneEthQuote,\n uint256 _boost\n ) internal view returns (uint256 _payment) {\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\n }\n\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\n _gasLeft = (gasleft() * 64) / 63;\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\nimport '../Keep3rDisputable.sol';\n\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\n\n try IERC20(_token).transfer(governance, _amount) {} catch {}\n jobTokenCredits[_job][_token] -= _amount;\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit JobSlashToken(_job, _token, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobPendingOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\n jobPendingOwner[_job] = _newOwner;\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\n }\n\n /// @inheritdoc IKeep3rJobOwnership\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\n address _previousOwner = jobOwner[_job];\n\n jobOwner[_job] = jobPendingOwner[_job];\n delete jobPendingOwner[_job];\n\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\n }\n\n modifier onlyJobOwner(address _job) {\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\n _;\n }\n\n modifier onlyPendingJobOwner(address _job) {\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\nimport './Keep3rRoles.sol';\n\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @notice List of all enabled keepers\n EnumerableSet.AddressSet internal _keepers;\n\n /// @inheritdoc IKeep3rAccountance\n uint256 public override totalBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override workCompleted;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override firstSeen;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override disputes;\n\n /// @inheritdoc IKeep3rAccountance\n /// @notice Mapping (job => bonding => amount)\n mapping(address => mapping(address => uint256)) public override bonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\n\n /// @notice The current liquidity credits available for a job\n mapping(address => uint256) internal _jobLiquidityCredits;\n\n /// @notice Map the address of a job to its correspondent periodCredits\n mapping(address => uint256) internal _jobPeriodCredits;\n\n /// @notice Enumerable array of Job Tokens for Credits\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\n\n /// @notice List of liquidities that a job has (job => liquidities)\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\n\n /// @notice Liquidity pool to observe\n mapping(address => address) internal _liquidityPool;\n\n /// @notice Tracks if a pool has KP3R as token0\n mapping(address => bool) internal _isKP3RToken0;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override hasBonded;\n\n /// @notice List of all enabled jobs\n EnumerableSet.AddressSet internal _jobs;\n\n /// @inheritdoc IKeep3rAccountance\n function jobs() external view override returns (address[] memory _list) {\n _list = _jobs.values();\n }\n\n /// @inheritdoc IKeep3rAccountance\n function keepers() external view override returns (address[] memory _list) {\n _list = _keepers.values();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport './DustCollector.sol';\nimport './Governable.sol';\n\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override slashers;\n\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override disputers;\n\n constructor(address _governance) Governable(_governance) DustCollector() {}\n\n /// @inheritdoc IKeep3rRoles\n function addSlasher(address _slasher) external override onlyGovernance {\n if (_slasher == address(0)) revert ZeroAddress();\n if (slashers[_slasher]) revert SlasherExistent();\n slashers[_slasher] = true;\n emit SlasherAdded(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeSlasher(address _slasher) external override onlyGovernance {\n if (!slashers[_slasher]) revert SlasherUnexistent();\n delete slashers[_slasher];\n emit SlasherRemoved(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function addDisputer(address _disputer) external override onlyGovernance {\n if (_disputer == address(0)) revert ZeroAddress();\n if (disputers[_disputer]) revert DisputerExistent();\n disputers[_disputer] = true;\n emit DisputerAdded(_disputer);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeDisputer(address _disputer) external override onlyGovernance {\n if (!disputers[_disputer]) revert DisputerUnexistent();\n delete disputers[_disputer];\n emit DisputerRemoved(_disputer);\n }\n\n /// @notice Functions with this modifier can only be called by either a slasher or governance\n modifier onlySlasher {\n if (!slashers[msg.sender]) revert OnlySlasher();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by either a disputer or governance\n modifier onlyDisputer {\n if (!disputers[msg.sender]) revert OnlyDisputer();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Governable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public override governance;\n\n /// @inheritdoc IGovernable\n address public override pendingGovernance;\n\n constructor(address _governance) {\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\n governance = _governance;\n }\n\n /// @inheritdoc IGovernable\n function setGovernance(address _governance) external override onlyGovernance {\n pendingGovernance = _governance;\n emit GovernanceProposal(_governance);\n }\n\n /// @inheritdoc IGovernable\n function acceptGovernance() external override onlyPendingGovernance {\n governance = pendingGovernance;\n delete pendingGovernance;\n emit GovernanceSet(governance);\n }\n\n /// @notice Functions with this modifier can only be called by governance\n modifier onlyGovernance {\n if (msg.sender != governance) revert OnlyGovernance();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernance\n modifier onlyPendingGovernance {\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\n _;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\n\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobMigration\n mapping(address => address) public override pendingJobMigrations;\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\n\n /// @inheritdoc IKeep3rJobMigration\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\n if (_fromJob == _toJob) revert JobMigrationImpossible();\n\n pendingJobMigrations[_fromJob] = _toJob;\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\n\n emit JobMigrationRequested(_fromJob, _toJob);\n }\n\n /// @inheritdoc IKeep3rJobMigration\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\n\n // force job credits update for both jobs\n _settleJobAccountance(_fromJob);\n _settleJobAccountance(_toJob);\n\n // migrate tokens\n while (_jobTokens[_fromJob].length() > 0) {\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\n _jobTokens[_fromJob].remove(_tokenToMigrate);\n _jobTokens[_toJob].add(_tokenToMigrate);\n }\n\n // migrate liquidities\n while (_jobLiquidities[_fromJob].length() > 0) {\n address _liquidity = _jobLiquidities[_fromJob].at(0);\n\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\n delete liquidityAmount[_fromJob][_liquidity];\n\n _jobLiquidities[_toJob].add(_liquidity);\n _jobLiquidities[_fromJob].remove(_liquidity);\n }\n\n // migrate job balances\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\n delete _jobPeriodCredits[_fromJob];\n\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\n delete _jobLiquidityCredits[_fromJob];\n\n // stop _fromJob from being a job\n delete rewardedAt[_fromJob];\n _jobs.remove(_fromJob);\n\n // delete unused data slots\n delete jobOwner[_fromJob];\n delete jobPendingOwner[_fromJob];\n delete _migrationCreatedAt[_fromJob][_toJob];\n delete pendingJobMigrations[_fromJob];\n\n emit JobMigrationSuccessful(_fromJob, _toJob);\n }\n}\n" + }, + "solidity/interfaces/IKeep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rHelperParameters.sol';\n\n/// @title Keep3rHelper contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelper is IKeep3rHelperParameters {\n // Errors\n\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\n error LiquidityPairInvalid();\n\n // Methods\n // solhint-enable func-name-mixedcase\n\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\n /// @param _eth The amount of ETH\n /// @return _amountOut The amount of KP3R\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\n\n /// @notice Returns the amount of KP3R the keeper has bonded\n /// @param _keeper The address of the keeper to check\n /// @return _amountBonded The amount of KP3R the keeper has bonded\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\n /// @param _keeper The address of the keeper to check\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\n\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\n /// @return _rewardBoost The reward boost that corresponds to the keeper\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\n\n /// @notice Given a pool address, returns the underlying tokens of the pair\n /// @param _pool Address of the correspondant pool\n /// @return _token0 Address of the first token of the pair\n /// @return _token1 Address of the second token of the pair\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\n\n /// @notice Defines the order of the tokens in the pair for twap calculations\n /// @param _pool Address of the correspondant pool\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\n\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\n /// @param _pool Address of the pool to observe\n /// @param _secondsAgo Array with time references to observe\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\n /// @return _success Boolean indicating if the observe call was succesfull\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n );\n\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\n /// @param _bonds Amount of bonded KP3R owned by the keeper\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\n /// @return _extra Amount of extra gas that should be added to the gas spent\n function getPaymentParams(uint256 _bonds)\n external\n view\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n );\n\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\n /// @param _liquidityAmount Amount of liquidity to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _kp3rAmount);\n\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\n /// @param _baseAmount Amount of token to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _quoteAmount);\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice Cooldown between withdrawals\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override nonReentrant {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n // KP3R shouldn't be used for direct token payments\n if (_token == keep3rV1) revert TokenUnallowed();\n uint256 _before = IERC20(_token).balanceOf(address(this));\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\n uint256 _tokenFee = (_received * fee) / _BASE;\n jobTokenCredits[_job][_token] += _received - _tokenFee;\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\n IERC20(_token).safeTransfer(governance, _tokenFee);\n _jobTokens[_job].add(_token);\n\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\n }\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external override nonReentrant onlyJobOwner(_job) {\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\n if (disputes[_job]) revert JobDisputed();\n\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_receiver, _amount);\n\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/IPairManager.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '../../libraries/FullMath.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice List of liquidities that are accepted in the system\n EnumerableSet.AddressSet internal _approvedLiquidities;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override rewardedAt;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override workedAt;\n\n /// @notice Tracks an address and returns its TickCache\n mapping(address => TickCache) internal _tick;\n\n // Views\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approvedLiquidities() external view override returns (address[] memory _list) {\n _list = _approvedLiquidities.values();\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n _periodCredits += _getReward(\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\n );\n }\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n\n // If the job was rewarded in the past 1 period time\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\n // If the job has period credits, update minted job credits to new twap\n _liquidityCredits = _periodCredits > 0\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\n } else {\n // Else return a full period worth of credits if current credits have expired\n _liquidityCredits = _periodCredits;\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n uint256 _cooldown = block.timestamp;\n\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\n // Will calculate cooldown if it outdated\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will calculate cooldown from last reward reference in this period\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\n } else {\n // Will calculate cooldown from last reward timestamp\n _cooldown -= rewardedAt[_job];\n }\n } else {\n // Will calculate cooldown from period start if expired\n _cooldown -= _period(block.timestamp);\n }\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\n\n if (_tick[_liquidity].period == lastPeriod) {\n // Will only ask for current period accumulator if liquidity is outdated\n uint32[] memory _secondsAgo = new uint32[](1);\n int56 previousTick = _tick[_liquidity].current;\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - previousTick;\n } else if (_tick[_liquidity].period < lastPeriod) {\n // Will ask for 2 accumulators if liquidity is expired\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n }\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Methods\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n _settleJobAccountance(_job);\n _jobLiquidityCredits[_job] += _amount;\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\n delete _liquidityPool[_liquidity];\n delete _isKP3RToken0[_liquidity];\n delete _tick[_liquidity];\n\n emit LiquidityRevocation(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override nonReentrant {\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\n if (!_jobs.contains(_job)) revert JobUnavailable();\n\n _jobLiquidities[_job].add(_liquidity);\n\n _settleJobAccountance(_job);\n\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\n liquidityAmount[_job][_liquidity] += _amount;\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlyJobOwner(_job) {\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\n pendingUnbonds[_job][_liquidity] += _amount;\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit Unbonding(_job, _liquidity, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external override onlyJobOwner(_job) {\n if (_receiver == address(0)) revert ZeroAddress();\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\n if (disputes[_job]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[_job][_liquidity];\n\n delete pendingUnbonds[_job][_liquidity];\n delete canWithdrawAfter[_job][_liquidity];\n\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\n }\n\n // Internal functions\n\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\n if (rewardedAt[_job] < _period(block.timestamp)) {\n // Will exit function if job has been rewarded in current period\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\n // Will reset job to period syncronicity if a full period passed without rewards\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] = _period(block.timestamp);\n _rewarded = true;\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will reset job's syncronicity if last reward was more than epoch ago\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] += rewardPeriodTime;\n _rewarded = true;\n } else if (workedAt[_job] < _period(block.timestamp)) {\n // First keeper on period has to update job accountance to current twaps\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\n // Updating job accountance does not reward job\n }\n }\n }\n\n /// @notice Only called if _jobLiquidityCredits < payment\n function _rewardJobCredits(address _job) internal {\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\n rewardedAt[_job] = block.timestamp;\n }\n\n /// @notice Updates accountance for _jobPeriodCredits\n function _updateJobPeriod(address _job) internal {\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\n }\n\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n if (_tick[_liquidity].period != _period(block.timestamp)) {\n // Updates liquidity cache only if needed\n _tick[_liquidity] = observeLiquidity(_liquidity);\n }\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\n }\n }\n }\n\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\n function _unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) internal nonReentrant {\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\n\n // Ensures current twaps in job liquidities\n _updateJobPeriod(_job);\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\n\n // A liquidity can be revoked causing a job to have 0 periodCredits\n if (_jobPeriodCredits[_job] > 0) {\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\n }\n\n liquidityAmount[_job][_liquidity] -= _amount;\n if (liquidityAmount[_job][_liquidity] == 0) {\n _jobLiquidities[_job].remove(_liquidity);\n }\n }\n\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\n if (_timePassed < rewardPeriodTime) {\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\n } else _result = _multiplier;\n }\n\n /// @notice Returns the start of the period of the provided timestamp\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\n return _timestamp - (_timestamp % rewardPeriodTime);\n }\n\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\n }\n\n /// @notice Returns underlying KP3R amount for a given liquidity amount\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\n if (_tick[_liquidity].period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\n }\n }\n\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\n /// @dev Ensures a maximum of 1 period of credits\n function _settleJobAccountance(address _job) internal virtual {\n _updateJobCreditsIfNeeded(_job);\n _rewardJobCredits(_job);\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/IKeep3rHelper.sol';\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\nimport './Keep3rAccountance.sol';\n\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1Proxy;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rHelper;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override bondTime = 3 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override unbondTime = 14 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override liquidityMinimum = 3 ether;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override rewardPeriodTime = 5 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override inflationPeriod = 34 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override fee = 30;\n\n /// @notice The base that will be used to calculate the fee\n uint256 internal constant _BASE = 10_000;\n\n /// @notice The minimum reward period\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) {\n keep3rHelper = _keep3rHelper;\n keep3rV1 = _keep3rV1;\n keep3rV1Proxy = _keep3rV1Proxy;\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\n if (_keep3rHelper == address(0)) revert ZeroAddress();\n keep3rHelper = _keep3rHelper;\n emit Keep3rHelperChange(_keep3rHelper);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\n if (_keep3rV1 == address(0)) revert ZeroAddress();\n _mint(totalBonds);\n\n keep3rV1 = _keep3rV1;\n emit Keep3rV1Change(_keep3rV1);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\n keep3rV1Proxy = _keep3rV1Proxy;\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\n bondTime = _bondTime;\n emit BondTimeChange(_bondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\n unbondTime = _unbondTime;\n emit UnbondTimeChange(_unbondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\n liquidityMinimum = _liquidityMinimum;\n emit LiquidityMinimumChange(_liquidityMinimum);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\n rewardPeriodTime = _rewardPeriodTime;\n emit RewardPeriodTimeChange(_rewardPeriodTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\n inflationPeriod = _inflationPeriod;\n emit InflationPeriodChange(_inflationPeriod);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setFee(uint256 _fee) external override onlyGovernance {\n fee = _fee;\n emit FeeChange(_fee);\n }\n\n function _mint(uint256 _amount) internal {\n totalBonds -= _amount;\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IGovernable.sol';\n\ninterface IKeep3rV1Proxy is IGovernable {\n // Structs\n struct Recipient {\n address recipient;\n uint256 caps;\n }\n\n // Variables\n function keep3rV1() external view returns (address);\n\n function minter() external view returns (address);\n\n function next(address) external view returns (uint256);\n\n function caps(address) external view returns (uint256);\n\n function recipients() external view returns (address[] memory);\n\n function recipientsCaps() external view returns (Recipient[] memory);\n\n // Errors\n error Cooldown();\n error NoDrawableAmount();\n error ZeroAddress();\n error OnlyMinter();\n\n // Methods\n function addRecipient(address recipient, uint256 amount) external;\n\n function removeRecipient(address recipient) external;\n\n function draw() external returns (uint256 _amount);\n\n function setKeep3rV1(address _keep3rV1) external;\n\n function setMinter(address _minter) external;\n\n function mint(uint256 _amount) external;\n\n function mint(address _account, uint256 _amount) external;\n\n function setKeep3rV1Governance(address _governance) external;\n\n function acceptKeep3rV1Governance() external;\n\n function dispute(address _keeper) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function addJob(address _job) external;\n\n function removeJob(address _job) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n}\n" + }, + "solidity/interfaces/IKeep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rHelperParameters contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelperParameters {\n // Structs\n\n /// @dev KP3R-WETH Pool address and isKP3RToken0\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\n struct TokenOraclePool {\n address poolAddress;\n bool isTKNToken0;\n }\n\n // Errors\n\n /// @notice Throws when pool does not have KP3R as token0 nor token1\n error InvalidOraclePool();\n\n // Events\n\n /// @notice Emitted when the kp3r weth pool is changed\n /// @param _address Address of the new kp3r weth pool\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\n\n /// @notice Emitted when the minimum boost multiplier is changed\n /// @param _minBoost The minimum boost multiplier\n event MinBoostChange(uint256 _minBoost);\n\n /// @notice Emitted when the maximum boost multiplier is changed\n /// @param _maxBoost The maximum boost multiplier\n event MaxBoostChange(uint256 _maxBoost);\n\n /// @notice Emitted when the target bond amount is changed\n /// @param _targetBond The target bond amount\n event TargetBondChange(uint256 _targetBond);\n\n /// @notice Emitted when the Keep3r V2 address is changed\n /// @param _keep3rV2 The address of Keep3r V2\n event Keep3rV2Change(address _keep3rV2);\n\n /// @notice Emitted when the work extra gas amount is changed\n /// @param _workExtraGas The work extra gas\n event WorkExtraGasChange(uint256 _workExtraGas);\n\n /// @notice Emitted when the quote twap time is changed\n /// @param _quoteTwapTime The twap time for quoting\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\n\n /// @notice Emitted when minimum rewarded gas fee is changed\n /// @param _minBaseFee The minimum rewarded gas fee\n event MinBaseFeeChange(uint256 _minBaseFee);\n\n /// @notice Emitted when minimum rewarded priority fee is changed\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\n event MinPriorityFeeChange(uint256 _minPriorityFee);\n\n // Variables\n\n /// @notice Address of KP3R token\n /// @return _kp3r Address of KP3R token\n // solhint-disable func-name-mixedcase\n function KP3R() external view returns (address _kp3r);\n\n /// @notice The boost base used to calculate the boost rewards for the keeper\n /// @return _base The boost base number\n function BOOST_BASE() external view returns (uint256 _base);\n\n /// @notice KP3R-WETH pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\n /// @return _multiplier The minimum boost multiplier\n function minBoost() external view returns (uint256 _multiplier);\n\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\n /// @return _multiplier The maximum boost multiplier\n function maxBoost() external view returns (uint256 _multiplier);\n\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\n /// @return _target The amount of KP3R that comforms the targetBond\n function targetBond() external view returns (uint256 _target);\n\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\n /// @return _workExtraGas The work unaccounted gas amount\n function workExtraGas() external view returns (uint256 _workExtraGas);\n\n /// @notice The twap time for quoting\n /// @return _quoteTwapTime The twap time\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\n\n /// @notice The minimum base fee that is used to calculate keeper rewards\n /// @return _minBaseFee The minimum rewarded gas fee\n function minBaseFee() external view returns (uint256 _minBaseFee);\n\n /// @notice The minimum priority fee that is also rewarded for keepers\n /// @return _minPriorityFee The minimum rewarded priority fee\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\n\n /// @notice Address of Keep3r V2\n /// @return _keep3rV2 Address of Keep3r V2\n function keep3rV2() external view returns (address _keep3rV2);\n\n // Methods\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function setKp3rWethPool(address _poolAddress) external;\n\n /// @notice Sets the minimum boost multiplier\n /// @param _minBoost The minimum boost multiplier\n function setMinBoost(uint256 _minBoost) external;\n\n /// @notice Sets the maximum boost multiplier\n /// @param _maxBoost The maximum boost multiplier\n function setMaxBoost(uint256 _maxBoost) external;\n\n /// @notice Sets the target bond amount\n /// @param _targetBond The target bond amount\n function setTargetBond(uint256 _targetBond) external;\n\n /// @notice Sets the Keep3r V2 address\n /// @param _keep3rV2 The address of Keep3r V2\n function setKeep3rV2(address _keep3rV2) external;\n\n /// @notice Sets the work extra gas amount\n /// @param _workExtraGas The work extra gas\n function setWorkExtraGas(uint256 _workExtraGas) external;\n\n /// @notice Sets the quote twap time\n /// @param _quoteTwapTime The twap time for quoting\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\n\n /// @notice Sets the minimum rewarded gas fee\n /// @param _minBaseFee The minimum rewarded gas fee\n function setMinBaseFee(uint256 _minBaseFee) external;\n\n /// @notice Sets the minimum rewarded gas priority fee\n /// @param _minPriorityFee The minimum rewarded priority fee\n function setMinPriorityFee(uint256 _minPriorityFee) external;\n}\n" + }, + "solidity/interfaces/IPairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n/// @title Pair Manager interface\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\ninterface IPairManager is IERC20Metadata {\n /// @notice Address of the factory from which the pair manager was created\n /// @return _factory The address of the PairManager Factory\n function factory() external view returns (address _factory);\n\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\n /// @return _pool The address of the pool\n function pool() external view returns (address _pool);\n\n /// @notice Token0 of the pool\n /// @return _token0 The address of token0\n function token0() external view returns (address _token0);\n\n /// @notice Token1 of the pool\n /// @return _token1 The address of token1\n function token1() external view returns (address _token1);\n}\n" + }, + "solidity/contracts/libraries/FullMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (~denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "solidity/contracts/peripherals/Keep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rParameters.sol';\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\n\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\n /// @inheritdoc IKeep3rDisputable\n function dispute(address _jobOrKeeper) external override onlyDisputer {\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\n disputes[_jobOrKeeper] = true;\n emit Dispute(_jobOrKeeper, msg.sender);\n }\n\n /// @inheritdoc IKeep3rDisputable\n function resolve(address _jobOrKeeper) external override onlyDisputer {\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\n disputes[_jobOrKeeper] = false;\n emit Resolve(_jobOrKeeper, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rKeeperFundable.sol';\nimport '../Keep3rDisputable.sol';\nimport '../../../interfaces/external/IKeep3rV1.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\n }\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function revoke(address _keeper) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _keepers.remove(_keeper);\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\n emit KeeperRevoke(_keeper, msg.sender);\n }\n\n function _slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) internal {\n if (_bonded != keep3rV1) {\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\n }\n bonds[_keeper][_bonded] -= _bondAmount;\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nimport '../../../interfaces/external/IKeep3rV1.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperFundable\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\n if (disputes[msg.sender]) revert Disputed();\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\n\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\n\n hasBonded[msg.sender] = true;\n pendingBonds[msg.sender][_bonding] += _amount;\n\n emit Bonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function activate(address _bonding) external override {\n address _keeper = msg.sender;\n if (disputes[_keeper]) revert Disputed();\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\n if (_canActivateAfter == 0) revert BondsUnexistent();\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\n\n if (firstSeen[_keeper] == 0) {\n firstSeen[_keeper] = block.timestamp;\n }\n _keepers.add(_keeper);\n\n uint256 _amount = pendingBonds[_keeper][_bonding];\n delete pendingBonds[_keeper][_bonding];\n\n // bond provided tokens\n bonds[_keeper][_bonding] += _amount;\n if (_bonding == keep3rV1) {\n totalBonds += _amount;\n _depositBonds(_amount);\n }\n\n emit Activation(_keeper, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function unbond(address _bonding, uint256 _amount) external override {\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\n bonds[msg.sender][_bonding] -= _amount;\n pendingUnbonds[msg.sender][_bonding] += _amount;\n\n emit Unbonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function withdraw(address _bonding) external override nonReentrant {\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\n if (disputes[msg.sender]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\n\n delete pendingUnbonds[msg.sender][_bonding];\n delete canWithdrawAfter[msg.sender][_bonding];\n\n if (_bonding == keep3rV1) _mint(_amount);\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(msg.sender, _bonding, _amount);\n }\n\n function _depositBonds(uint256 _amount) internal virtual {\n IKeep3rV1(keep3rV1).burn(_amount);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n// solhint-disable func-name-mixedcase\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\n // Structs\n struct Checkpoint {\n uint32 fromBlock;\n uint256 votes;\n }\n\n // Events\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event JobAdded(address indexed _job, uint256 _block, address _governance);\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\n event KeeperDispute(address indexed _keeper, uint256 _block);\n event KeeperResolved(address indexed _keeper, uint256 _block);\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\n\n // Variables\n function KPRH() external returns (address);\n\n function delegates(address _delegator) external view returns (address);\n\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\n\n function numCheckpoints(address _account) external view returns (uint32);\n\n function DOMAIN_TYPEHASH() external returns (bytes32);\n\n function DOMAINSEPARATOR() external returns (bytes32);\n\n function DELEGATION_TYPEHASH() external returns (bytes32);\n\n function PERMIT_TYPEHASH() external returns (bytes32);\n\n function nonces(address _user) external view returns (uint256);\n\n function BOND() external returns (uint256);\n\n function UNBOND() external returns (uint256);\n\n function LIQUIDITYBOND() external returns (uint256);\n\n function FEE() external returns (uint256);\n\n function BASE() external returns (uint256);\n\n function ETH() external returns (address);\n\n function bondings(address _user, address _bonding) external view returns (uint256);\n\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\n\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function bonds(address _keeper, address _bonding) external view returns (uint256);\n\n function votes(address _delegator) external view returns (uint256);\n\n function firstSeen(address _keeper) external view returns (uint256);\n\n function disputes(address _keeper) external view returns (bool);\n\n function lastJob(address _keeper) external view returns (uint256);\n\n function workCompleted(address _keeper) external view returns (uint256);\n\n function jobs(address _job) external view returns (bool);\n\n function credits(address _job, address _credit) external view returns (uint256);\n\n function liquidityProvided(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmountsUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function jobProposalDelay(address _job) external view returns (uint256);\n\n function liquidityApplied(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmount(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function keepers(address _keeper) external view returns (bool);\n\n function blacklist(address _keeper) external view returns (bool);\n\n function keeperList(uint256 _index) external view returns (address);\n\n function jobList(uint256 _index) external view returns (address);\n\n function governance() external returns (address);\n\n function pendingGovernance() external returns (address);\n\n function liquidityAccepted(address _liquidity) external view returns (bool);\n\n function liquidityPairs(uint256 _index) external view returns (address);\n\n // Methods\n function getCurrentVotes(address _account) external view returns (uint256);\n\n function addCreditETH(address _job) external payable;\n\n function addCredit(\n address _credit,\n address _job,\n uint256 _amount\n ) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function pairs() external view returns (address[] memory);\n\n function addLiquidityToJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function applyCreditToJob(\n address _provider,\n address _liquidity,\n address _job\n ) external;\n\n function unbondLiquidityFromJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function removeLiquidityFromJob(address _liquidity, address _job) external;\n\n function mint(uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n\n function worked(address _keeper) external;\n\n function receipt(\n address _credit,\n address _keeper,\n uint256 _amount\n ) external;\n\n function receiptETH(address _keeper, uint256 _amount) external;\n\n function addJob(address _job) external;\n\n function getJobs() external view returns (address[] memory);\n\n function removeJob(address _job) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function isKeeper(address _keeper) external returns (bool);\n\n function isMinKeeper(\n address _keeper,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function bond(address _bonding, uint256 _amount) external;\n\n function getKeepers() external view returns (address[] memory);\n\n function activate(address _bonding) external;\n\n function unbond(address _bonding, uint256 _amount) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function withdraw(address _bonding) external;\n\n function dispute(address _keeper) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function permit(\n address _owner,\n address _spender,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3r.sol';\n\ncontract Keep3rForTestnet is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3r.sol';\n\ncontract Keep3rForTest is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3r.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\n\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @param _governance Address of governance\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\n constructor(\n address _governance, // governance\n address _keep3rHelperSidechain, // helper\n address _wrappedKP3R, // keep3rV1\n address _keep3rEscrow // keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\n\n // Keep3rSidechainAccountance\n\n /// @inheritdoc IKeep3rSidechainAccountance\n function virtualReserves() external view override returns (int256 _virtualReserves) {\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\n }\n\n // Keep3rJobFundableLiquidity\n\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\n /// @param _liquidity Address of the liquidity token being approved\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\n /// @param _liquidity Address of the liquidity token being observed\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n\n // Will always ask for 2 accumulators in sidechain\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Keep3rJobsWorkable\n\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\n function worked(address) external pure override {\n revert Deprecated();\n }\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Uses a USD per gas unit payment mechanism\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\n if (_initialGas == 0) revert GasNotInitialized();\n // Gas used for quote calculations & payment is not rewarded\n uint256 _gasLeft = _getGasLeft();\n\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\n\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _kp3rPayment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\n }\n\n // Keep3rKeeperFundable\n\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\n function _depositBonds(uint256 _amount) internal virtual override {\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\n }\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// solhint-disable-next-line no-empty-blocks\n\nimport '../peripherals/IMintable.sol';\n\n/// @title Keep3rEscrow contract\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\ninterface IKeep3rEscrow is IMintable {\n /// @notice Emitted when Keep3rEscrow#deposit function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _sender The address that called the function\n /// @param _amount The amount of wKP3R the user deposited\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#mint function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _recipient The address that will received the newly minted wKP3R\n /// @param _amount The amount of wKP3R minted to the recipient\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\n /// @param _newWKP3R The address of the wKP3R contract\n event wKP3RSet(address _newWKP3R);\n\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\n error InsufficientBalance();\n\n /// @notice Lists the address of the wKP3R contract\n /// @return _wKP3RAddress The address of wKP3R\n function wKP3R() external view returns (address _wKP3RAddress);\n\n /// @notice Deposits wKP3R into the contract\n /// @param _amount The amount of wKP3R to deposit\n function deposit(uint256 _amount) external;\n\n /// @notice mints wKP3R to the recipient\n /// @param _amount The amount of wKP3R to mint\n function mint(uint256 _amount) external;\n\n /// @notice sets the wKP3R address\n /// @param _wKP3R the wKP3R address\n function setWKP3R(address _wKP3R) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../IKeep3rHelper.sol';\n\n/// @title Keep3rHelperSidechain contract\n/// @notice Contains all the helper functions for sidechain keep3r implementations\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\n // Events\n\n /// @notice The oracle for a liquidity has been saved\n /// @param _liquidity The address of the given liquidity\n /// @param _oraclePool The address of the oracle pool\n event OracleSet(address _liquidity, address _oraclePool);\n\n /// @notice Emitted when the WETH USD pool is changed\n /// @param _address Address of the new WETH USD pool\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\n\n /// Variables\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n /// @return _weth Address of WETH token\n // solhint-disable func-name-mixedcase\n function WETH() external view returns (address _weth);\n\n /// @return _oracle The address of the observable pool for given liquidity\n function oracle(address _liquidity) external view returns (address _oracle);\n\n /// @notice WETH-USD pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice Quotes USD to ETH\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\n /// @param _usd The amount of USD to quote to ETH\n /// @return _eth The resulting amount of ETH after quoting the USD\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\n\n /// Methods\n\n /// @notice Sets an oracle for a given liquidity\n /// @param _liquidity The address of the liquidity\n /// @param _oracle The address of the pool used to quote the liquidity from\n /// @dev The oracle must contain KP3R as either token0 or token1\n function setOracle(address _liquidity, address _oracle) external;\n\n /// @notice Sets an oracle for querying WETH/USD quote\n /// @param _poolAddress The address of the pool used as oracle\n /// @dev The oracle must contain WETH as either token0 or token1\n function setWethUsdPool(address _poolAddress) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IKeep3rJobs.sol';\n\n/// @title Keep3rJobWorkableRated contract\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\n /// @notice Throws when job contract calls deprecated worked(address) function\n error Deprecated();\n\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title IKeep3rSidechainAccountance interface\n/// @notice Implements a view to get the amount of credits that can be withdrawn\ninterface IKeep3rSidechainAccountance {\n /// @notice The surplus amount of wKP3Rs in escrow contract\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\n function virtualReserves() external view returns (int256 _virtualReserves);\n}\n" + }, + "solidity/interfaces/peripherals/IMintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IGovernable.sol';\nimport './IBaseErrors.sol';\n\n/// @title Mintable contract\n/// @notice Manages the minter role\ninterface IMintable is IBaseErrors, IGovernable {\n // Events\n\n /// @notice Emitted when governance sets a new minter\n /// @param _minter Address of the new minter\n event MinterSet(address _minter);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not the minter\n error OnlyMinter();\n\n // Variables\n\n /// @notice Stores the minter address\n /// @return _minter The minter addresss\n function minter() external view returns (address _minter);\n\n // Methods\n\n /// @notice Sets a new address to be the minter\n /// @param _minter The address set as the minter\n function setMinter(address _minter) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rSidechainForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTest is Keep3rSidechain {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _governance,\n address _keep3rHelper,\n address _wrappedKP3R,\n address _keep3rEscrow\n ) Keep3rSidechain(_governance, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n}\n" + }, + "solidity/for-test/JobRatedForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\n\ncontract JobRatedForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n uint256 public usdPerGasUnit = 1_000e9;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n}\n" + }, + "solidity/for-test/JobForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract JobForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/for-test/BasicJob.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract BasicJob {\n error KeeperNotValid();\n\n address public keep3r;\n uint256 public nonce;\n uint256[] public array;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external upkeep {}\n\n function workHard(uint256 _howHard) external upkeep {\n for (uint256 i = nonce; i < _howHard; i++) {\n nonce++;\n }\n }\n\n function workRefund(uint256 _howHard) external upkeep {\n for (uint256 i; i < _howHard; i++) {\n array.push(i);\n }\n\n while (array.length > 0) {\n array.pop();\n }\n }\n\n modifier upkeep() {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\n _;\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/peripherals/IBaseErrors.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/external/IKeep3rV1.sol';\nimport '../interfaces/IKeep3rHelperParameters.sol';\nimport './peripherals/Governable.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\n /// @inheritdoc IKeep3rHelperParameters\n address public immutable override KP3R;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public constant override BOOST_BASE = 10_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBoost = 11_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override maxBoost = 12_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override targetBond = 200 ether;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override workExtraGas = 34_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint32 public override quoteTwapTime = 10 minutes;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBaseFee = 15e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minPriorityFee = 2e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n address public override keep3rV2;\n\n /// @inheritdoc IKeep3rHelperParameters\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Governable(_governance) {\n KP3R = _kp3r;\n keep3rV2 = _keep3rV2;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setKp3rWethPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\n minBoost = _minBoost;\n emit MinBoostChange(minBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\n maxBoost = _maxBoost;\n emit MaxBoostChange(maxBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\n targetBond = _targetBond;\n emit TargetBondChange(targetBond);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\n if (_keep3rV2 == address(0)) revert ZeroAddress();\n keep3rV2 = _keep3rV2;\n emit Keep3rV2Change(keep3rV2);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\n workExtraGas = _workExtraGas;\n emit WorkExtraGasChange(workExtraGas);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\n _setQuoteTwapTime(_quoteTwapTime);\n }\n\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\n quoteTwapTime = _quoteTwapTime;\n emit QuoteTwapTimeChange(quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\n minBaseFee = _minBaseFee;\n emit MinBaseFeeChange(minBaseFee);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\n minPriorityFee = _minPriorityFee;\n emit MinPriorityFeeChange(minPriorityFee);\n }\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function _setKp3rWethPool(address _poolAddress) internal {\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\n\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\n\n return TokenOraclePool(_poolAddress, _isTKNToken0);\n }\n}\n" + }, + "solidity/contracts/libraries/TickMath.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n// solhint-disable\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n // Second inequality must be < because the price can never reach the price at the max tick\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport './pool/IUniswapV3PoolImmutables.sol';\nimport './pool/IUniswapV3PoolState.sol';\nimport './pool/IUniswapV3PoolDerivedState.sol';\nimport './pool/IUniswapV3PoolActions.sol';\nimport './pool/IUniswapV3PoolOwnerActions.sol';\nimport './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolEvents\n{\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// observationIndex The index of the last oracle observation that was written,\n /// observationCardinality The current maximum number of observations stored in the pool,\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper,\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return _liquidity The amount of liquidity in the position,\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 _liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// Returns initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" + }, + "solidity/for-test/UniV3PairManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport '../contracts/libraries/LiquidityAmounts.sol';\nimport '../contracts/libraries/FixedPoint96.sol';\nimport '../contracts/libraries/FullMath.sol';\nimport '../contracts/libraries/TickMath.sol';\nimport '../contracts/UniV3PairManager.sol';\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManagerForTest is UniV3PairManager {\n constructor(address _pool, address _governance) UniV3PairManager(_pool, _governance) {}\n\n function internalAddLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n external\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n return _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n }\n\n function internalPay(\n address token,\n address payer,\n address recipient,\n uint256 value\n ) external {\n return _pay(token, payer, recipient, value);\n }\n\n function internalMint(address dst, uint256 amount) external {\n return _mint(dst, amount);\n }\n\n function internalBurn(address dst, uint256 amount) external {\n return _burn(dst, amount);\n }\n\n function internalTransferTokens(\n address src,\n address dst,\n uint256 amount\n ) external {\n _transferTokens(src, dst, amount);\n }\n\n function internalSafeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) external {\n _safeTransferFrom(token, from, to, value);\n }\n\n receive() external payable {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "solidity/contracts/libraries/LiquidityAmounts.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport './FullMath.sol';\nimport './FixedPoint96.sol';\n\n// solhint-disable\nlibrary LiquidityAmounts {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/contracts/libraries/FixedPoint96.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nlibrary FixedPoint96 {\n // solhint-disable\n uint8 internal constant RESOLUTION = 96;\n uint256 internal constant Q96 = 0x1000000000000000000000000;\n}\n" + }, + "solidity/contracts/UniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport './libraries/LiquidityAmounts.sol';\nimport './libraries/FixedPoint96.sol';\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\n\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\nimport './peripherals/Governable.sol';\n\ncontract UniV3PairManager is IUniV3PairManager, Governable {\n /// @inheritdoc IERC20Metadata\n string public override name;\n\n /// @inheritdoc IERC20Metadata\n string public override symbol;\n\n /// @inheritdoc IERC20\n uint256 public override totalSupply;\n\n /// @inheritdoc IPairManager\n address public immutable override factory;\n\n /// @inheritdoc IPairManager\n address public immutable override token0;\n\n /// @inheritdoc IPairManager\n address public immutable override token1;\n\n /// @inheritdoc IPairManager\n address public immutable override pool;\n\n /// @inheritdoc IUniV3PairManager\n uint24 public immutable override fee;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioAX96;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioBX96;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickLower;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickUpper;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickSpacing;\n\n /// @notice Uniswap's maximum tick\n /// @dev Due to tick spacing, pools with different fees may have differences between _MAX_TICK and tickUpper. Use tickUpper to find the max tick of the pool.\n int24 private constant _MAX_TICK = 887272;\n\n /// @inheritdoc IERC20Metadata\n //solhint-disable-next-line const-name-snakecase\n uint8 public constant override decimals = 18;\n\n /// @inheritdoc IERC20\n mapping(address => mapping(address => uint256)) public override allowance;\n\n /// @inheritdoc IERC20\n mapping(address => uint256) public override balanceOf;\n\n /// @notice Struct that contains token0, token1, and fee of the Uniswap pool\n PoolKey private _poolKey;\n\n constructor(address _pool, address _governance) Governable(_governance) {\n uint24 _fee = IUniswapV3Pool(_pool).fee();\n address _token0 = IUniswapV3Pool(_pool).token0();\n address _token1 = IUniswapV3Pool(_pool).token1();\n int24 _tickSpacing = IUniswapV3Pool(_pool).tickSpacing();\n int24 _tickUpper = _MAX_TICK - (_MAX_TICK % _tickSpacing);\n int24 _tickLower = -_tickUpper;\n\n factory = msg.sender;\n pool = _pool;\n fee = _fee;\n tickSpacing = _tickSpacing;\n tickUpper = _tickUpper;\n tickLower = _tickLower;\n token0 = _token0;\n token1 = _token1;\n name = string(abi.encodePacked('Keep3rLP - ', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n symbol = string(abi.encodePacked('kLP-', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n\n sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(_tickLower);\n sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(_tickUpper);\n _poolKey = PoolKey({token0: _token0, token1: _token1, fee: _fee});\n }\n\n // This low-level function should be called from a contract which performs important safety checks\n /// @inheritdoc IUniV3PairManager\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint128 liquidity) {\n (liquidity, , ) = _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n _mint(to, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external override {\n MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));\n if (msg.sender != pool) revert OnlyPool();\n if (amount0Owed > 0) _pay(decoded._poolKey.token0, decoded.payer, pool, amount0Owed);\n if (amount1Owed > 0) _pay(decoded._poolKey.token1, decoded.payer, pool, amount1Owed);\n }\n\n /// @inheritdoc IUniV3PairManager\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint256 amount0, uint256 amount1) {\n (amount0, amount1) = IUniswapV3Pool(pool).burn(tickLower, tickUpper, liquidity);\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n\n IUniswapV3Pool(pool).collect(to, tickLower, tickUpper, uint128(amount0), uint128(amount1));\n _burn(msg.sender, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function collect() external override onlyGovernance returns (uint256 amount0, uint256 amount1) {\n (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n (amount0, amount1) = IUniswapV3Pool(pool).collect(governance, tickLower, tickUpper, tokensOwed0, tokensOwed1);\n }\n\n /// @inheritdoc IUniV3PairManager\n function position()\n external\n view\n override\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n )\n {\n (liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128, tokensOwed0, tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n }\n\n /// @inheritdoc IERC20\n function approve(address spender, uint256 amount) external override returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transfer(address to, uint256 amount) external override returns (bool) {\n _transferTokens(msg.sender, to, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool) {\n address spender = msg.sender;\n uint256 spenderAllowance = allowance[from][spender];\n\n if (spender != from && spenderAllowance != type(uint256).max) {\n uint256 newAllowance = spenderAllowance - amount;\n allowance[from][spender] = newAllowance;\n\n emit Approval(from, spender, newAllowance);\n }\n\n _transferTokens(from, to, amount);\n return true;\n }\n\n /// @notice Adds liquidity to an initialized pool\n /// @dev Reverts if the returned amount0 is less than amount0Min or if amount1 is less than amount1Min\n /// @dev This function calls the mint function of the corresponding Uniswap pool, which in turn calls UniswapV3Callback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @return liquidity The calculated liquidity we get for the token amounts we provided\n /// @return amount0 The amount of token0 we ended up providing\n /// @return amount1 The amount of token1 we ended up providing\n function _addLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n internal\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(pool).slot0();\n\n liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, amount0Desired, amount1Desired);\n\n (amount0, amount1) = IUniswapV3Pool(pool).mint(\n address(this),\n tickLower,\n tickUpper,\n liquidity,\n abi.encode(MintCallbackData({_poolKey: _poolKey, payer: msg.sender}))\n );\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n }\n\n /// @notice Transfers the passed-in token from the payer to the recipient for the corresponding value\n /// @param token The token to be transferred to the recipient\n /// @param from The address of the payer\n /// @param to The address of the passed-in tokens recipient\n /// @param value How much of that token to be transferred from payer to the recipient\n function _pay(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n _safeTransferFrom(token, from, to, value);\n }\n\n /// @notice Mints Keep3r credits to the passed-in address of recipient and increases total supply of Keep3r credits by the corresponding amount\n /// @param to The recipient of the Keep3r credits\n /// @param amount The amount Keep3r credits to be minted to the recipient\n function _mint(address to, uint256 amount) internal {\n totalSupply += amount;\n balanceOf[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @notice Burns Keep3r credits to the passed-in address of recipient and reduces total supply of Keep3r credits by the corresponding amount\n /// @param to The address that will get its Keep3r credits burned\n /// @param amount The amount Keep3r credits to be burned from the recipient/recipient\n function _burn(address to, uint256 amount) internal {\n totalSupply -= amount;\n balanceOf[to] -= amount;\n emit Transfer(to, address(0), amount);\n }\n\n /// @notice Transfers amount of Keep3r credits between two addresses\n /// @param from The user that transfers the Keep3r credits\n /// @param to The user that receives the Keep3r credits\n /// @param amount The amount of Keep3r credits to be transferred\n function _transferTokens(\n address from,\n address to,\n uint256 amount\n ) internal {\n balanceOf[from] -= amount;\n balanceOf[to] += amount;\n\n emit Transfer(from, to, amount);\n }\n\n /// @notice Transfers the passed-in token from the specified \"from\" to the specified \"to\" for the corresponding value\n /// @dev Reverts with IUniV3PairManager#UnsuccessfulTransfer if the transfer was not successful,\n /// or if the passed data length is different than 0 and the decoded data is not a boolean\n /// @param token The token to be transferred to the specified \"to\"\n /// @param from The address which is going to transfer the tokens\n /// @param value How much of that token to be transferred from \"from\" to \"to\"\n function _safeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert UnsuccessfulTransfer();\n }\n}\n" + }, + "solidity/interfaces/external/IWeth9.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IWeth9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256) external;\n}\n" + }, + "solidity/interfaces/IUniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IPairManager.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\nimport './peripherals/IGovernable.sol';\n\n/// @title Pair Manager contract\n/// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner\n/// so that the user can use it as liquidity for a Keep3rJob\ninterface IUniV3PairManager is IGovernable, IPairManager {\n // Structs\n struct PoolKey {\n address token0;\n address token1;\n uint24 fee;\n }\n\n /// @notice The data to be decoded by the UniswapV3MintCallback function\n struct MintCallbackData {\n PoolKey _poolKey; // Struct that contains token0, token1, and fee of the pool passed into the constructor\n address payer; // The address of the payer, which will be the msg.sender of the mint function\n }\n\n // Variables\n\n /// @notice The fee of the Uniswap pool passed into the constructor\n /// @return _fee The fee of the Uniswap pool passed into the constructor\n function fee() external view returns (uint24 _fee);\n\n /// @notice Highest tick in the Uniswap's curve\n /// @return _tickUpper The highest tick in the Uniswap's curve\n function tickUpper() external view returns (int24 _tickUpper);\n\n /// @notice Lowest tick in the Uniswap's curve\n /// @return _tickLower The lower tick in the Uniswap's curve\n function tickLower() external view returns (int24 _tickLower);\n\n /// @notice The pair tick spacing\n /// @return _tickSpacing The pair tick spacing\n function tickSpacing() external view returns (int24 _tickSpacing);\n\n /// @notice The sqrtRatioAX96 at the lowest tick (-887200) of the Uniswap pool\n /// @return _sqrtPriceA96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the lowest tick\n function sqrtRatioAX96() external view returns (uint160 _sqrtPriceA96);\n\n /// @notice The sqrtRatioBX96 at the highest tick (887200) of the Uniswap pool\n /// @return _sqrtPriceBX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the highest tick\n function sqrtRatioBX96() external view returns (uint160 _sqrtPriceBX96);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the pool\n error OnlyPool();\n\n /// @notice Throws when the slippage exceeds what the user is comfortable with\n error ExcessiveSlippage();\n\n /// @notice Throws when a transfer is unsuccessful\n error UnsuccessfulTransfer();\n\n // Methods\n\n /// @notice This function is called after a user calls IUniV3PairManager#mint function\n /// It ensures that any tokens owed to the pool are paid by the msg.sender of IUniV3PairManager#mint function\n /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity\n /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity\n /// @param data The encoded token0, token1, fee (_poolKey) and the payer (msg.sender) of the IUniV3PairManager#mint function\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external;\n\n /// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool\n /// @dev Triggers UniV3PairManager#uniswapV3MintCallback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @param to The address to which the kLP tokens are going to be minted to\n /// @return liquidity kLP tokens sent in exchange for the provision of tokens\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint128 liquidity);\n\n /// @notice Returns the pair manager's position in the corresponding UniswapV3 pool\n /// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager\n /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position\n /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position\n /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation\n /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation\n function position()\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees\n // owed to a specific position to the recipient, in this case, that recipient is the pair manager\n /// @dev The collected fees will be sent to governance\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect() external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity\n // in the entire range\n /// @param liquidity The amount of liquidity to be burned\n /// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)\n /// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)\n /// @param to The address that will receive the due fees\n /// @return amount0 The calculated amount of token0 that will be sent to the recipient\n /// @return amount1 The calculated amount of token1 that will be sent to the recipient\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint256 amount0, uint256 amount1);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "solidity/interfaces/IPairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IGovernable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ninterface IPairManagerFactory is IGovernable {\n // Variables\n\n /// @notice Maps the address of a Uniswap pool, to the address of the corresponding PairManager\n /// For example, the uniswap address of DAI-WETH, will return the Keep3r/DAI-WETH pair manager address\n /// @param _pool The address of the Uniswap pool\n /// @return _pairManager The address of the corresponding pair manager\n function pairManagers(address _pool) external view returns (address _pairManager);\n\n // Events\n\n /// @notice Emitted when a new pair manager is created\n /// @param _pool The address of the corresponding Uniswap pool\n /// @param _pairManager The address of the just-created pair manager\n event PairCreated(address _pool, address _pairManager);\n\n // Errors\n\n /// @notice Throws an error if the pair manager is already initialized\n error AlreadyInitialized();\n\n /// @notice Throws an error if the caller is not the owner\n error OnlyOwner();\n\n // Methods\n\n /// @notice Creates a new pair manager based on the address of a Uniswap pool\n /// For example, the uniswap address of DAI-WETH, will create the Keep3r/DAI-WETH pool\n /// @param _pool The address of the Uniswap pool the pair manager will be based of\n /// @return _pairManager The address of the just-created pair manager\n function createPairManager(address _pool) external returns (address _pairManager);\n}\n" + }, + "solidity/contracts/UniV3PairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IPairManagerFactory.sol';\nimport './UniV3PairManager.sol';\nimport './peripherals/Governable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ncontract UniV3PairManagerFactory is IPairManagerFactory, Governable {\n mapping(address => address) public override pairManagers;\n\n constructor(address _governance) Governable(_governance) {}\n\n ///@inheritdoc IPairManagerFactory\n function createPairManager(address _pool) external override returns (address _pairManager) {\n if (pairManagers[_pool] != address(0)) revert AlreadyInitialized();\n _pairManager = address(new UniV3PairManager(_pool, governance));\n pairManagers[_pool] = _pairManager;\n emit PairCreated(_pool, _pairManager);\n }\n}\n" + }, + "solidity/for-test/peripherals/GovernableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" + }, + "solidity/for-test/BridgeForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ncontract BridgeForTest is ERC20 {\n address public immutable kp3r;\n\n constructor(address _kp3r) ERC20('Wrapped KP3R', 'wKP3R') {\n kp3r = _kp3r;\n }\n\n function bridge(uint256 _amount) external {\n IERC20(kp3r).transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n }\n\n function bridgeBack(uint256 _amount) external {\n _burn(msg.sender, _amount);\n IERC20(kp3r).transfer(msg.sender, _amount);\n }\n}\n" + }, + "solidity/for-test/ERC20ForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(uint256 _amount) public {\n _mint(msg.sender, _amount);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(uint256 _amount) public {\n _burn(msg.sender, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n function deposit() external payable {\n // Function added for compatibility with WETH\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperFundableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperFundable.sol';\n\ncontract Keep3rKeeperFundableForTest is Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function isKeeper(address _keeper) external view returns (bool) {\n return _keepers.contains(_keeper);\n }\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/Mintable.sol';\nimport '../peripherals/DustCollector.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rEscrow\n address public override wKP3R;\n\n /// @param _governance Address of governance\n /// @param _wKP3R Address of wrapped KP3R implementation\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\n wKP3R = _wKP3R;\n }\n\n /// @inheritdoc IKeep3rEscrow\n function deposit(uint256 _amount) external override {\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function mint(uint256 _amount) external override onlyMinter {\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function setWKP3R(address _wKP3R) external override onlyGovernance {\n if (_wKP3R == address(0)) revert ZeroAddress();\n wKP3R = _wKP3R;\n emit wKP3RSet(wKP3R);\n }\n}\n" + }, + "solidity/contracts/peripherals/Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IMintable.sol';\nimport './Governable.sol';\n\nabstract contract Mintable is Governable, IMintable {\n /// @inheritdoc IMintable\n address public override minter;\n\n constructor(address _governance) Governable(_governance) {}\n\n /// @inheritdoc IMintable\n function setMinter(address _minter) external override onlyGovernance {\n if (_minter == address(0)) revert ZeroAddress();\n minter = _minter;\n emit MinterSet(_minter);\n }\n\n /// @notice Functions with this modifier can only be called by the minter;\n modifier onlyMinter() {\n if (msg.sender != minter) revert OnlyMinter();\n _;\n }\n}\n" + }, + "solidity/for-test/peripherals/DustCollectorForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/DustCollector.sol';\n\ncontract DustCollectorForTest is DustCollector {\n constructor() DustCollector() Governable(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rAccountanceForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rAccountance.sol';\n\ncontract Keep3rAccountanceForTest is Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor() Keep3rRoles(msg.sender) {}\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n\n function setKeeper(address keeper) external {\n _keepers.add(keeper);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableLiquidityForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol';\n\ncontract Keep3rJobFundableLiquidityForTest is Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external returns (bool) {\n return _jobLiquidities[_job].add(_liquidity);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewTickOrder(address _liquidity) external view returns (bool) {\n return _isKP3RToken0[_liquidity];\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function internalSettleJobAccountance(address _job) external {\n _settleJobAccountance(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobDisputable.sol';\n\ncontract Keep3rJobDisputableForTest is Keep3rJobDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function internalJobLiquidityCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobLiquidityCredits[_job];\n }\n\n function internalJobPeriodCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobPeriodCredits[_job];\n }\n\n function internalJobTokens(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobTokens[_job].length());\n for (uint256 i; i < _jobTokens[_job].length(); i++) {\n _tokens[i] = _jobTokens[_job].at(i);\n }\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobLiquidities[_job].length());\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n _tokens[i] = _jobLiquidities[_job].at(i);\n }\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rDisputable.sol';\n\ncontract Keep3rDisputableForTest is Keep3rDisputable {\n constructor() Keep3rParameters(address(0), address(0), address(0)) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperDisputable.sol';\n\ncontract Keep3rKeeperDisputableForTest is Keep3rKeeperDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function internalSlash(\n address _bonded,\n address _keeper,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external {\n _slash(_bonded, _keeper, _bondAmount, _unbondAmount);\n }\n\n function isKeeper(address _address) external view returns (bool _isKeeper) {\n _isKeeper = _keepers.contains(_address);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableCreditsForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableCredits.sol';\n\ncontract Keep3rJobFundableCreditsForTest is Keep3rJobFundableCredits {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job, address _jobOwner) external {\n _jobs.add(_job);\n jobOwner[_job] = _jobOwner;\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function isJobToken(address _job, address _token) external view returns (bool _contains) {\n _contains = _jobTokens[_job].contains(_token);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/IKeep3rHelper.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n /// @inheritdoc IKeep3rHelper\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelper\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\n // solhint-disable-next-line avoid-tx-origin\n return getRewardAmountFor(tx.origin, _gasUsed);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\n _bonds = Math.min(_bonds, targetBond);\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\n _rewardBoost = _cap * _getBasefee();\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\n }\n\n /// @inheritdoc IKeep3rHelper\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\n address _token0;\n address _token1;\n (_token0, _token1) = getPoolTokens(_pool);\n if (_token0 == KP3R) {\n return true;\n } else if (_token1 != KP3R) {\n revert LiquidityPairInvalid();\n }\n }\n\n /// @inheritdoc IKeep3rHelper\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n override\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n )\n {\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\n _tickCumulative1 = _uniswapResponse[0];\n if (_uniswapResponse.length > 1) {\n _tickCumulative2 = _uniswapResponse[1];\n }\n _success = true;\n } catch (bytes memory) {}\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n )\n {\n _oneEthQuote = quote(1 ether);\n _boost = getRewardBoostFor(_bonds);\n _extra = workExtraGas;\n }\n\n /// @inheritdoc IKeep3rHelper\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure override returns (uint256 _kp3rAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) public pure override returns (uint256 _quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\n }\n }\n\n /// @notice Gets the gas basefee cost to calculate keeper rewards\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTestnet is Keep3rHelper {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal pure override returns (uint256) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/Keep3rHelperForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTest is Keep3rHelper {\n uint256 public basefee;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal view override returns (uint256) {\n return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee();\n }\n\n function setBaseFee(uint256 _baseFee) external {\n basefee = _baseFee;\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rHelper.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\n /// @inheritdoc IKeep3rHelperSidechain\n mapping(address => address) public override oracle;\n /// @inheritdoc IKeep3rHelperSidechain\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n address public immutable override WETH;\n\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\n /// @param _governance Address of governance\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\n /// @dev Oracle pools should use 18 decimals tokens\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\n WETH = _weth;\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\n _setQuoteTwapTime(1 days);\n workExtraGas = 0;\n }\n\n /// @inheritdoc IKeep3rHelper\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\n oracle[_liquidity] = _oracle;\n emit OracleSet(_liquidity, _oracle);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n /// @dev Oracle is compatible with IUniswapV3Pool\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setWethUsdPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override(Keep3rHelper, IKeep3rHelper)\n returns (\n uint256 _boost,\n uint256 _oneUsdQuote,\n uint256 _extraGas\n )\n {\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\n _boost = getRewardBoostFor(_bonds);\n _extraGas = workExtraGas;\n }\n\n function _setWethUsdPool(address _poolAddress) internal {\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\n }\n\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechainForTestnet is Keep3rHelperSidechain {\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelperSidechain(_keep3rV2, _governance, _kp3r, _weth, _kp3rWethOracle, _wethUsdOracle) {}\n\n /// @dev Overrides oracle validation that uses KP3R and WETH addresses\n function _validateOraclePool(address _poolAddress, address) internal view virtual override returns (TokenOraclePool memory _oraclePool) {\n return TokenOraclePool(_poolAddress, true);\n }\n\n /// @dev Overrides token comparison with KP3R address\n function isKP3RToken0(address) public view virtual override returns (bool) {\n return true;\n }\n\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256) {\n return _usd / 1000;\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rParametersForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rParameters.sol';\n\ncontract Keep3rParametersForTest is Keep3rParameters {\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobWorkableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobWorkable.sol';\n\ncontract Keep3rJobWorkableForTest is Keep3rJobWorkable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewGas() external view returns (uint256) {\n return _initialGas;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobMigrationForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobMigration.sol';\n\ncontract Keep3rJobMigrationForTest is Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(address => uint256) public settleJobAccountanceCallCount;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobTokenListLength(address _job) external view returns (uint256) {\n return _jobTokens[_job].length();\n }\n\n function viewJobLiquidityList(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewMigrationCreatedAt(address _fromJob, address _toJob) external view returns (uint256) {\n return _migrationCreatedAt[_fromJob][_toJob];\n }\n\n function isJob(address _job) external view returns (bool) {\n return _jobs.contains(_job);\n }\n\n function _settleJobAccountance(address _job) internal override {\n settleJobAccountanceCallCount[_job]++;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobManager.sol';\n\ncontract Keep3rJobManagerForTest is Keep3rJobManager {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rRoles(msg.sender) {}\n\n function isJob(address _job) external view returns (bool _isJob) {\n _isJob = _jobs.contains(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobOwnershipForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobOwnership.sol';\n\ncontract Keep3rJobOwnershipForTest is Keep3rJobOwnership {}\n" + }, + "solidity/for-test/libraries/LiquidityAmountsForTest.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/libraries/FullMath.sol';\nimport '../../contracts/libraries/FixedPoint96.sol';\n\n/// @dev Made this library into a contract to be able to calculate liquidity more precisely for tests\n\n// solhint-disable\ncontract LiquidityAmountsForTest {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) external pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) external pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/for-test/IUniswapV3PoolForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n// solhint-disable-next-line no-empty-blocks\ninterface IUniswapV3PoolForTest is IERC20Minimal, IUniswapV3Pool {\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Minimal ERC20 interface for Uniswap\n/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3\ninterface IERC20Minimal {\n /// @notice Returns the balance of a token\n /// @param account The account for which to look up the number of tokens it has, i.e. its balance\n /// @return The number of tokens held by the account\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Transfers the amount of token from the `msg.sender` to the recipient\n /// @param recipient The account that will receive the amount transferred\n /// @param amount The number of tokens to send from the sender to the recipient\n /// @return Returns true for a successful transfer, false for an unsuccessful transfer\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /// @notice Returns the current allowance given to a spender by an owner\n /// @param owner The account of the token owner\n /// @param spender The account of the token spender\n /// @return The current allowance granted by `owner` to `spender`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`\n /// @param spender The account which will be allowed to spend a given amount of the owners tokens\n /// @param amount The amount of tokens allowed to be used by `spender`\n /// @return Returns true for a successful approval, false for unsuccessful\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`\n /// @param sender The account from which the transfer will be initiated\n /// @param recipient The recipient of the transfer\n /// @param amount The amount of the transfer\n /// @return Returns true for a successful transfer, false for unsuccessful\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.\n /// @param from The account from which the tokens were sent, i.e. the balance decreased\n /// @param to The account to which the tokens were sent, i.e. the balance increased\n /// @param value The amount of tokens that were transferred\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.\n /// @param owner The account that approved spending of its tokens\n /// @param spender The account for which the spending allowance was modified\n /// @param value The new allowance from the owner to the spender\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 33 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" + } + } + } +} \ No newline at end of file diff --git a/deployments/goerli/solcInputs/0d224f905ebe4be6830f2d07ee9fcf58.json b/deployments/goerli/solcInputs/0d224f905ebe4be6830f2d07ee9fcf58.json new file mode 100644 index 0000000..78d4b61 --- /dev/null +++ b/deployments/goerli/solcInputs/0d224f905ebe4be6830f2d07ee9fcf58.json @@ -0,0 +1,331 @@ +{ + "language": "Solidity", + "sources": { + "solidity/contracts/Keep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport './peripherals/jobs/Keep3rJobs.sol';\nimport './peripherals/keepers/Keep3rKeepers.sol';\nimport './peripherals/DustCollector.sol';\n\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\n}\n" + }, + "solidity/interfaces/IKeep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobManager.sol';\nimport './Keep3rJobWorkable.sol';\nimport './Keep3rJobDisputable.sol';\n\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\nimport './Keep3rKeeperDisputable.sol';\n\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\n" + }, + "solidity/contracts/peripherals/DustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '../../contracts/peripherals/Governable.sol';\nimport '../../interfaces/peripherals/IDustCollector.sol';\n\nabstract contract DustCollector is IDustCollector, Governable {\n using SafeERC20 for IERC20;\n\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external override onlyGovernance {\n if (_to == address(0)) revert ZeroAddress();\n if (_token == _ETH_ADDRESS) {\n payable(_to).transfer(_amount);\n } else {\n IERC20(_token).safeTransfer(_to, _amount);\n }\n emit DustSent(_token, _amount, _to);\n }\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" + }, + "solidity/interfaces/peripherals/IBaseErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" + }, + "solidity/interfaces/peripherals/IGovernable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" + }, + "solidity/interfaces/peripherals/IDustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @inheritdoc IKeep3rJobManager\n function addJob(address _job) external override {\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\n if (hasBonded[_job]) revert AlreadyAKeeper();\n _jobs.add(_job);\n jobOwner[_job] = msg.sender;\n emit JobAddition(_job, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobMigration.sol';\nimport '../../../interfaces/IKeep3rHelper.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 internal _initialGas;\n\n /// @inheritdoc IKeep3rJobWorkable\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\n _initialGas = _getGasLeft();\n if (_keepers.contains(_keeper)) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external override returns (bool _isBondedKeeper) {\n _initialGas = _getGasLeft();\n if (\n _keepers.contains(_keeper) &&\n bonds[_keeper][_bond] >= _minBond &&\n workCompleted[_keeper] >= _earned &&\n block.timestamp - firstSeen[_keeper] >= _age\n ) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function worked(address _keeper) external virtual override {\n if (_initialGas == 0) revert GasNotInitialized();\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _gasLeft = _getGasLeft();\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n _gasLeft = _getGasLeft();\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function bondedPayment(address _keeper, uint256 _payment) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (disputes[_keeper]) revert Disputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_keeper, _amount);\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\n }\n\n function _bondedPayment(\n address _job,\n address _keeper,\n uint256 _payment\n ) internal {\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\n\n workedAt[_job] = block.timestamp;\n _jobLiquidityCredits[_job] -= _payment;\n bonds[_keeper][keep3rV1] += _payment;\n workCompleted[_keeper] += _payment;\n totalBonds += _payment;\n }\n\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\n /// @param _gasLeft Amount of gas left after working the job\n /// @param _extraGas Amount of expected unaccounted gas\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\n /// @return _payment Amount to be payed in KP3R tokens\n function _calculatePayment(\n uint256 _gasLeft,\n uint256 _extraGas,\n uint256 _oneEthQuote,\n uint256 _boost\n ) internal view returns (uint256 _payment) {\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\n }\n\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\n _gasLeft = (gasleft() * 64) / 63;\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\nimport '../Keep3rDisputable.sol';\n\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\n\n try IERC20(_token).transfer(governance, _amount) {} catch {}\n jobTokenCredits[_job][_token] -= _amount;\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit JobSlashToken(_job, _token, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobPendingOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\n jobPendingOwner[_job] = _newOwner;\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\n }\n\n /// @inheritdoc IKeep3rJobOwnership\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\n address _previousOwner = jobOwner[_job];\n\n jobOwner[_job] = jobPendingOwner[_job];\n delete jobPendingOwner[_job];\n\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\n }\n\n modifier onlyJobOwner(address _job) {\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\n _;\n }\n\n modifier onlyPendingJobOwner(address _job) {\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\nimport './Keep3rRoles.sol';\n\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @notice List of all enabled keepers\n EnumerableSet.AddressSet internal _keepers;\n\n /// @inheritdoc IKeep3rAccountance\n uint256 public override totalBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override workCompleted;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override firstSeen;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override disputes;\n\n /// @inheritdoc IKeep3rAccountance\n /// @notice Mapping (job => bonding => amount)\n mapping(address => mapping(address => uint256)) public override bonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\n\n /// @notice The current liquidity credits available for a job\n mapping(address => uint256) internal _jobLiquidityCredits;\n\n /// @notice Map the address of a job to its correspondent periodCredits\n mapping(address => uint256) internal _jobPeriodCredits;\n\n /// @notice Enumerable array of Job Tokens for Credits\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\n\n /// @notice List of liquidities that a job has (job => liquidities)\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\n\n /// @notice Liquidity pool to observe\n mapping(address => address) internal _liquidityPool;\n\n /// @notice Tracks if a pool has KP3R as token0\n mapping(address => bool) internal _isKP3RToken0;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override hasBonded;\n\n /// @notice List of all enabled jobs\n EnumerableSet.AddressSet internal _jobs;\n\n /// @inheritdoc IKeep3rAccountance\n function jobs() external view override returns (address[] memory _list) {\n _list = _jobs.values();\n }\n\n /// @inheritdoc IKeep3rAccountance\n function keepers() external view override returns (address[] memory _list) {\n _list = _keepers.values();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport './DustCollector.sol';\nimport './Governable.sol';\n\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override slashers;\n\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override disputers;\n\n constructor(address _governance) Governable(_governance) DustCollector() {}\n\n /// @inheritdoc IKeep3rRoles\n function addSlasher(address _slasher) external override onlyGovernance {\n if (_slasher == address(0)) revert ZeroAddress();\n if (slashers[_slasher]) revert SlasherExistent();\n slashers[_slasher] = true;\n emit SlasherAdded(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeSlasher(address _slasher) external override onlyGovernance {\n if (!slashers[_slasher]) revert SlasherUnexistent();\n delete slashers[_slasher];\n emit SlasherRemoved(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function addDisputer(address _disputer) external override onlyGovernance {\n if (_disputer == address(0)) revert ZeroAddress();\n if (disputers[_disputer]) revert DisputerExistent();\n disputers[_disputer] = true;\n emit DisputerAdded(_disputer);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeDisputer(address _disputer) external override onlyGovernance {\n if (!disputers[_disputer]) revert DisputerUnexistent();\n delete disputers[_disputer];\n emit DisputerRemoved(_disputer);\n }\n\n /// @notice Functions with this modifier can only be called by either a slasher or governance\n modifier onlySlasher {\n if (!slashers[msg.sender]) revert OnlySlasher();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by either a disputer or governance\n modifier onlyDisputer {\n if (!disputers[msg.sender]) revert OnlyDisputer();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Governable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public override governance;\n\n /// @inheritdoc IGovernable\n address public override pendingGovernance;\n\n constructor(address _governance) {\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\n governance = _governance;\n }\n\n /// @inheritdoc IGovernable\n function setGovernance(address _governance) external override onlyGovernance {\n pendingGovernance = _governance;\n emit GovernanceProposal(_governance);\n }\n\n /// @inheritdoc IGovernable\n function acceptGovernance() external override onlyPendingGovernance {\n governance = pendingGovernance;\n delete pendingGovernance;\n emit GovernanceSet(governance);\n }\n\n /// @notice Functions with this modifier can only be called by governance\n modifier onlyGovernance {\n if (msg.sender != governance) revert OnlyGovernance();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernance\n modifier onlyPendingGovernance {\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\n _;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\n\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobMigration\n mapping(address => address) public override pendingJobMigrations;\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\n\n /// @inheritdoc IKeep3rJobMigration\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\n if (_fromJob == _toJob) revert JobMigrationImpossible();\n\n pendingJobMigrations[_fromJob] = _toJob;\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\n\n emit JobMigrationRequested(_fromJob, _toJob);\n }\n\n /// @inheritdoc IKeep3rJobMigration\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\n\n // force job credits update for both jobs\n _settleJobAccountance(_fromJob);\n _settleJobAccountance(_toJob);\n\n // migrate tokens\n while (_jobTokens[_fromJob].length() > 0) {\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\n _jobTokens[_fromJob].remove(_tokenToMigrate);\n _jobTokens[_toJob].add(_tokenToMigrate);\n }\n\n // migrate liquidities\n while (_jobLiquidities[_fromJob].length() > 0) {\n address _liquidity = _jobLiquidities[_fromJob].at(0);\n\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\n delete liquidityAmount[_fromJob][_liquidity];\n\n _jobLiquidities[_toJob].add(_liquidity);\n _jobLiquidities[_fromJob].remove(_liquidity);\n }\n\n // migrate job balances\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\n delete _jobPeriodCredits[_fromJob];\n\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\n delete _jobLiquidityCredits[_fromJob];\n\n // stop _fromJob from being a job\n delete rewardedAt[_fromJob];\n _jobs.remove(_fromJob);\n\n // delete unused data slots\n delete jobOwner[_fromJob];\n delete jobPendingOwner[_fromJob];\n delete _migrationCreatedAt[_fromJob][_toJob];\n delete pendingJobMigrations[_fromJob];\n\n emit JobMigrationSuccessful(_fromJob, _toJob);\n }\n}\n" + }, + "solidity/interfaces/IKeep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rHelperParameters.sol';\n\n/// @title Keep3rHelper contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelper is IKeep3rHelperParameters {\n // Errors\n\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\n error LiquidityPairInvalid();\n\n // Methods\n // solhint-enable func-name-mixedcase\n\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\n /// @param _eth The amount of ETH\n /// @return _amountOut The amount of KP3R\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\n\n /// @notice Returns the amount of KP3R the keeper has bonded\n /// @param _keeper The address of the keeper to check\n /// @return _amountBonded The amount of KP3R the keeper has bonded\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\n /// @param _keeper The address of the keeper to check\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\n\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\n /// @return _rewardBoost The reward boost that corresponds to the keeper\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\n\n /// @notice Given a pool address, returns the underlying tokens of the pair\n /// @param _pool Address of the correspondant pool\n /// @return _token0 Address of the first token of the pair\n /// @return _token1 Address of the second token of the pair\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\n\n /// @notice Defines the order of the tokens in the pair for twap calculations\n /// @param _pool Address of the correspondant pool\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\n\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\n /// @param _pool Address of the pool to observe\n /// @param _secondsAgo Array with time references to observe\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\n /// @return _success Boolean indicating if the observe call was succesfull\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n );\n\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\n /// @param _bonds Amount of bonded KP3R owned by the keeper\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\n /// @return _extra Amount of extra gas that should be added to the gas spent\n function getPaymentParams(uint256 _bonds)\n external\n view\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n );\n\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\n /// @param _liquidityAmount Amount of liquidity to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _kp3rAmount);\n\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\n /// @param _baseAmount Amount of token to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _quoteAmount);\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice Cooldown between withdrawals\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override nonReentrant {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n // KP3R shouldn't be used for direct token payments\n if (_token == keep3rV1) revert TokenUnallowed();\n uint256 _before = IERC20(_token).balanceOf(address(this));\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\n uint256 _tokenFee = (_received * fee) / _BASE;\n jobTokenCredits[_job][_token] += _received - _tokenFee;\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\n IERC20(_token).safeTransfer(governance, _tokenFee);\n _jobTokens[_job].add(_token);\n\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\n }\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external override nonReentrant onlyJobOwner(_job) {\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\n if (disputes[_job]) revert JobDisputed();\n\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_receiver, _amount);\n\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/IPairManager.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '../../libraries/FullMath.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice List of liquidities that are accepted in the system\n EnumerableSet.AddressSet internal _approvedLiquidities;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override rewardedAt;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override workedAt;\n\n /// @notice Tracks an address and returns its TickCache\n mapping(address => TickCache) internal _tick;\n\n // Views\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approvedLiquidities() external view override returns (address[] memory _list) {\n _list = _approvedLiquidities.values();\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n _periodCredits += _getReward(\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\n );\n }\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n\n // If the job was rewarded in the past 1 period time\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\n // If the job has period credits, update minted job credits to new twap\n _liquidityCredits = _periodCredits > 0\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\n } else {\n // Else return a full period worth of credits if current credits have expired\n _liquidityCredits = _periodCredits;\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n uint256 _cooldown = block.timestamp;\n\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\n // Will calculate cooldown if it outdated\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will calculate cooldown from last reward reference in this period\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\n } else {\n // Will calculate cooldown from last reward timestamp\n _cooldown -= rewardedAt[_job];\n }\n } else {\n // Will calculate cooldown from period start if expired\n _cooldown -= _period(block.timestamp);\n }\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\n\n if (_tick[_liquidity].period == lastPeriod) {\n // Will only ask for current period accumulator if liquidity is outdated\n uint32[] memory _secondsAgo = new uint32[](1);\n int56 previousTick = _tick[_liquidity].current;\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - previousTick;\n } else if (_tick[_liquidity].period < lastPeriod) {\n // Will ask for 2 accumulators if liquidity is expired\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n }\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Methods\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n _settleJobAccountance(_job);\n _jobLiquidityCredits[_job] += _amount;\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\n delete _liquidityPool[_liquidity];\n delete _isKP3RToken0[_liquidity];\n delete _tick[_liquidity];\n\n emit LiquidityRevocation(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override nonReentrant {\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\n if (!_jobs.contains(_job)) revert JobUnavailable();\n\n _jobLiquidities[_job].add(_liquidity);\n\n _settleJobAccountance(_job);\n\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\n liquidityAmount[_job][_liquidity] += _amount;\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlyJobOwner(_job) {\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\n pendingUnbonds[_job][_liquidity] += _amount;\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit Unbonding(_job, _liquidity, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external override onlyJobOwner(_job) {\n if (_receiver == address(0)) revert ZeroAddress();\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\n if (disputes[_job]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[_job][_liquidity];\n\n delete pendingUnbonds[_job][_liquidity];\n delete canWithdrawAfter[_job][_liquidity];\n\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\n }\n\n // Internal functions\n\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\n if (rewardedAt[_job] < _period(block.timestamp)) {\n // Will exit function if job has been rewarded in current period\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\n // Will reset job to period syncronicity if a full period passed without rewards\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] = _period(block.timestamp);\n _rewarded = true;\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will reset job's syncronicity if last reward was more than epoch ago\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] += rewardPeriodTime;\n _rewarded = true;\n } else if (workedAt[_job] < _period(block.timestamp)) {\n // First keeper on period has to update job accountance to current twaps\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\n // Updating job accountance does not reward job\n }\n }\n }\n\n /// @notice Only called if _jobLiquidityCredits < payment\n function _rewardJobCredits(address _job) internal {\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\n rewardedAt[_job] = block.timestamp;\n }\n\n /// @notice Updates accountance for _jobPeriodCredits\n function _updateJobPeriod(address _job) internal {\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\n }\n\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n if (_tick[_liquidity].period != _period(block.timestamp)) {\n // Updates liquidity cache only if needed\n _tick[_liquidity] = observeLiquidity(_liquidity);\n }\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\n }\n }\n }\n\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\n function _unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) internal nonReentrant {\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\n\n // Ensures current twaps in job liquidities\n _updateJobPeriod(_job);\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\n\n // A liquidity can be revoked causing a job to have 0 periodCredits\n if (_jobPeriodCredits[_job] > 0) {\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\n }\n\n liquidityAmount[_job][_liquidity] -= _amount;\n if (liquidityAmount[_job][_liquidity] == 0) {\n _jobLiquidities[_job].remove(_liquidity);\n }\n }\n\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\n if (_timePassed < rewardPeriodTime) {\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\n } else _result = _multiplier;\n }\n\n /// @notice Returns the start of the period of the provided timestamp\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\n return _timestamp - (_timestamp % rewardPeriodTime);\n }\n\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\n }\n\n /// @notice Returns underlying KP3R amount for a given liquidity amount\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\n if (_tick[_liquidity].period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\n }\n }\n\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\n /// @dev Ensures a maximum of 1 period of credits\n function _settleJobAccountance(address _job) internal virtual {\n _updateJobCreditsIfNeeded(_job);\n _rewardJobCredits(_job);\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/IKeep3rHelper.sol';\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\nimport './Keep3rAccountance.sol';\n\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1Proxy;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rHelper;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override bondTime = 3 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override unbondTime = 14 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override liquidityMinimum = 3 ether;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override rewardPeriodTime = 5 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override inflationPeriod = 34 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override fee = 30;\n\n /// @notice The base that will be used to calculate the fee\n uint256 internal constant _BASE = 10_000;\n\n /// @notice The minimum reward period\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) {\n keep3rHelper = _keep3rHelper;\n keep3rV1 = _keep3rV1;\n keep3rV1Proxy = _keep3rV1Proxy;\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\n if (_keep3rHelper == address(0)) revert ZeroAddress();\n keep3rHelper = _keep3rHelper;\n emit Keep3rHelperChange(_keep3rHelper);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\n if (_keep3rV1 == address(0)) revert ZeroAddress();\n _mint(totalBonds);\n\n keep3rV1 = _keep3rV1;\n emit Keep3rV1Change(_keep3rV1);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\n keep3rV1Proxy = _keep3rV1Proxy;\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\n bondTime = _bondTime;\n emit BondTimeChange(_bondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\n unbondTime = _unbondTime;\n emit UnbondTimeChange(_unbondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\n liquidityMinimum = _liquidityMinimum;\n emit LiquidityMinimumChange(_liquidityMinimum);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\n rewardPeriodTime = _rewardPeriodTime;\n emit RewardPeriodTimeChange(_rewardPeriodTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\n inflationPeriod = _inflationPeriod;\n emit InflationPeriodChange(_inflationPeriod);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setFee(uint256 _fee) external override onlyGovernance {\n fee = _fee;\n emit FeeChange(_fee);\n }\n\n function _mint(uint256 _amount) internal {\n totalBonds -= _amount;\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IGovernable.sol';\n\ninterface IKeep3rV1Proxy is IGovernable {\n // Structs\n struct Recipient {\n address recipient;\n uint256 caps;\n }\n\n // Variables\n function keep3rV1() external view returns (address);\n\n function minter() external view returns (address);\n\n function next(address) external view returns (uint256);\n\n function caps(address) external view returns (uint256);\n\n function recipients() external view returns (address[] memory);\n\n function recipientsCaps() external view returns (Recipient[] memory);\n\n // Errors\n error Cooldown();\n error NoDrawableAmount();\n error ZeroAddress();\n error OnlyMinter();\n\n // Methods\n function addRecipient(address recipient, uint256 amount) external;\n\n function removeRecipient(address recipient) external;\n\n function draw() external returns (uint256 _amount);\n\n function setKeep3rV1(address _keep3rV1) external;\n\n function setMinter(address _minter) external;\n\n function mint(uint256 _amount) external;\n\n function mint(address _account, uint256 _amount) external;\n\n function setKeep3rV1Governance(address _governance) external;\n\n function acceptKeep3rV1Governance() external;\n\n function dispute(address _keeper) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function addJob(address _job) external;\n\n function removeJob(address _job) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n}\n" + }, + "solidity/interfaces/IKeep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rHelperParameters contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelperParameters {\n // Structs\n\n /// @dev KP3R-WETH Pool address and isKP3RToken0\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\n struct TokenOraclePool {\n address poolAddress;\n bool isTKNToken0;\n }\n\n // Errors\n\n /// @notice Throws when pool does not have KP3R as token0 nor token1\n error InvalidOraclePool();\n\n // Events\n\n /// @notice Emitted when the kp3r weth pool is changed\n /// @param _address Address of the new kp3r weth pool\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\n\n /// @notice Emitted when the minimum boost multiplier is changed\n /// @param _minBoost The minimum boost multiplier\n event MinBoostChange(uint256 _minBoost);\n\n /// @notice Emitted when the maximum boost multiplier is changed\n /// @param _maxBoost The maximum boost multiplier\n event MaxBoostChange(uint256 _maxBoost);\n\n /// @notice Emitted when the target bond amount is changed\n /// @param _targetBond The target bond amount\n event TargetBondChange(uint256 _targetBond);\n\n /// @notice Emitted when the Keep3r V2 address is changed\n /// @param _keep3rV2 The address of Keep3r V2\n event Keep3rV2Change(address _keep3rV2);\n\n /// @notice Emitted when the work extra gas amount is changed\n /// @param _workExtraGas The work extra gas\n event WorkExtraGasChange(uint256 _workExtraGas);\n\n /// @notice Emitted when the quote twap time is changed\n /// @param _quoteTwapTime The twap time for quoting\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\n\n /// @notice Emitted when minimum rewarded gas fee is changed\n /// @param _minBaseFee The minimum rewarded gas fee\n event MinBaseFeeChange(uint256 _minBaseFee);\n\n /// @notice Emitted when minimum rewarded priority fee is changed\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\n event MinPriorityFeeChange(uint256 _minPriorityFee);\n\n // Variables\n\n /// @notice Address of KP3R token\n /// @return _kp3r Address of KP3R token\n // solhint-disable func-name-mixedcase\n function KP3R() external view returns (address _kp3r);\n\n /// @notice The boost base used to calculate the boost rewards for the keeper\n /// @return _base The boost base number\n function BOOST_BASE() external view returns (uint256 _base);\n\n /// @notice KP3R-WETH pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\n /// @return _multiplier The minimum boost multiplier\n function minBoost() external view returns (uint256 _multiplier);\n\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\n /// @return _multiplier The maximum boost multiplier\n function maxBoost() external view returns (uint256 _multiplier);\n\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\n /// @return _target The amount of KP3R that comforms the targetBond\n function targetBond() external view returns (uint256 _target);\n\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\n /// @return _workExtraGas The work unaccounted gas amount\n function workExtraGas() external view returns (uint256 _workExtraGas);\n\n /// @notice The twap time for quoting\n /// @return _quoteTwapTime The twap time\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\n\n /// @notice The minimum base fee that is used to calculate keeper rewards\n /// @return _minBaseFee The minimum rewarded gas fee\n function minBaseFee() external view returns (uint256 _minBaseFee);\n\n /// @notice The minimum priority fee that is also rewarded for keepers\n /// @return _minPriorityFee The minimum rewarded priority fee\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\n\n /// @notice Address of Keep3r V2\n /// @return _keep3rV2 Address of Keep3r V2\n function keep3rV2() external view returns (address _keep3rV2);\n\n // Methods\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function setKp3rWethPool(address _poolAddress) external;\n\n /// @notice Sets the minimum boost multiplier\n /// @param _minBoost The minimum boost multiplier\n function setMinBoost(uint256 _minBoost) external;\n\n /// @notice Sets the maximum boost multiplier\n /// @param _maxBoost The maximum boost multiplier\n function setMaxBoost(uint256 _maxBoost) external;\n\n /// @notice Sets the target bond amount\n /// @param _targetBond The target bond amount\n function setTargetBond(uint256 _targetBond) external;\n\n /// @notice Sets the Keep3r V2 address\n /// @param _keep3rV2 The address of Keep3r V2\n function setKeep3rV2(address _keep3rV2) external;\n\n /// @notice Sets the work extra gas amount\n /// @param _workExtraGas The work extra gas\n function setWorkExtraGas(uint256 _workExtraGas) external;\n\n /// @notice Sets the quote twap time\n /// @param _quoteTwapTime The twap time for quoting\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\n\n /// @notice Sets the minimum rewarded gas fee\n /// @param _minBaseFee The minimum rewarded gas fee\n function setMinBaseFee(uint256 _minBaseFee) external;\n\n /// @notice Sets the minimum rewarded gas priority fee\n /// @param _minPriorityFee The minimum rewarded priority fee\n function setMinPriorityFee(uint256 _minPriorityFee) external;\n}\n" + }, + "solidity/interfaces/IPairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n/// @title Pair Manager interface\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\ninterface IPairManager is IERC20Metadata {\n /// @notice Address of the factory from which the pair manager was created\n /// @return _factory The address of the PairManager Factory\n function factory() external view returns (address _factory);\n\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\n /// @return _pool The address of the pool\n function pool() external view returns (address _pool);\n\n /// @notice Token0 of the pool\n /// @return _token0 The address of token0\n function token0() external view returns (address _token0);\n\n /// @notice Token1 of the pool\n /// @return _token1 The address of token1\n function token1() external view returns (address _token1);\n}\n" + }, + "solidity/contracts/libraries/FullMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (~denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "solidity/contracts/peripherals/Keep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rParameters.sol';\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\n\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\n /// @inheritdoc IKeep3rDisputable\n function dispute(address _jobOrKeeper) external override onlyDisputer {\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\n disputes[_jobOrKeeper] = true;\n emit Dispute(_jobOrKeeper, msg.sender);\n }\n\n /// @inheritdoc IKeep3rDisputable\n function resolve(address _jobOrKeeper) external override onlyDisputer {\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\n disputes[_jobOrKeeper] = false;\n emit Resolve(_jobOrKeeper, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rKeeperFundable.sol';\nimport '../Keep3rDisputable.sol';\nimport '../../../interfaces/external/IKeep3rV1.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\n }\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function revoke(address _keeper) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _keepers.remove(_keeper);\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\n emit KeeperRevoke(_keeper, msg.sender);\n }\n\n function _slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) internal {\n if (_bonded != keep3rV1) {\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\n }\n bonds[_keeper][_bonded] -= _bondAmount;\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nimport '../../../interfaces/external/IKeep3rV1.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperFundable\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\n if (disputes[msg.sender]) revert Disputed();\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\n\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\n\n hasBonded[msg.sender] = true;\n pendingBonds[msg.sender][_bonding] += _amount;\n\n emit Bonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function activate(address _bonding) external override {\n address _keeper = msg.sender;\n if (disputes[_keeper]) revert Disputed();\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\n if (_canActivateAfter == 0) revert BondsUnexistent();\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\n\n if (firstSeen[_keeper] == 0) {\n firstSeen[_keeper] = block.timestamp;\n }\n _keepers.add(_keeper);\n\n uint256 _amount = pendingBonds[_keeper][_bonding];\n delete pendingBonds[_keeper][_bonding];\n\n // bond provided tokens\n bonds[_keeper][_bonding] += _amount;\n if (_bonding == keep3rV1) {\n totalBonds += _amount;\n _depositBonds(_amount);\n }\n\n emit Activation(_keeper, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function unbond(address _bonding, uint256 _amount) external override {\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\n bonds[msg.sender][_bonding] -= _amount;\n pendingUnbonds[msg.sender][_bonding] += _amount;\n\n emit Unbonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function withdraw(address _bonding) external override nonReentrant {\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\n if (disputes[msg.sender]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\n\n delete pendingUnbonds[msg.sender][_bonding];\n delete canWithdrawAfter[msg.sender][_bonding];\n\n if (_bonding == keep3rV1) _mint(_amount);\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(msg.sender, _bonding, _amount);\n }\n\n function _depositBonds(uint256 _amount) internal virtual {\n IKeep3rV1(keep3rV1).burn(_amount);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n// solhint-disable func-name-mixedcase\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\n // Structs\n struct Checkpoint {\n uint32 fromBlock;\n uint256 votes;\n }\n\n // Events\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event JobAdded(address indexed _job, uint256 _block, address _governance);\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\n event KeeperDispute(address indexed _keeper, uint256 _block);\n event KeeperResolved(address indexed _keeper, uint256 _block);\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\n\n // Variables\n function KPRH() external returns (address);\n\n function delegates(address _delegator) external view returns (address);\n\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\n\n function numCheckpoints(address _account) external view returns (uint32);\n\n function DOMAIN_TYPEHASH() external returns (bytes32);\n\n function DOMAINSEPARATOR() external returns (bytes32);\n\n function DELEGATION_TYPEHASH() external returns (bytes32);\n\n function PERMIT_TYPEHASH() external returns (bytes32);\n\n function nonces(address _user) external view returns (uint256);\n\n function BOND() external returns (uint256);\n\n function UNBOND() external returns (uint256);\n\n function LIQUIDITYBOND() external returns (uint256);\n\n function FEE() external returns (uint256);\n\n function BASE() external returns (uint256);\n\n function ETH() external returns (address);\n\n function bondings(address _user, address _bonding) external view returns (uint256);\n\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\n\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function bonds(address _keeper, address _bonding) external view returns (uint256);\n\n function votes(address _delegator) external view returns (uint256);\n\n function firstSeen(address _keeper) external view returns (uint256);\n\n function disputes(address _keeper) external view returns (bool);\n\n function lastJob(address _keeper) external view returns (uint256);\n\n function workCompleted(address _keeper) external view returns (uint256);\n\n function jobs(address _job) external view returns (bool);\n\n function credits(address _job, address _credit) external view returns (uint256);\n\n function liquidityProvided(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmountsUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function jobProposalDelay(address _job) external view returns (uint256);\n\n function liquidityApplied(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmount(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function keepers(address _keeper) external view returns (bool);\n\n function blacklist(address _keeper) external view returns (bool);\n\n function keeperList(uint256 _index) external view returns (address);\n\n function jobList(uint256 _index) external view returns (address);\n\n function governance() external returns (address);\n\n function pendingGovernance() external returns (address);\n\n function liquidityAccepted(address _liquidity) external view returns (bool);\n\n function liquidityPairs(uint256 _index) external view returns (address);\n\n // Methods\n function getCurrentVotes(address _account) external view returns (uint256);\n\n function addCreditETH(address _job) external payable;\n\n function addCredit(\n address _credit,\n address _job,\n uint256 _amount\n ) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function pairs() external view returns (address[] memory);\n\n function addLiquidityToJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function applyCreditToJob(\n address _provider,\n address _liquidity,\n address _job\n ) external;\n\n function unbondLiquidityFromJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function removeLiquidityFromJob(address _liquidity, address _job) external;\n\n function mint(uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n\n function worked(address _keeper) external;\n\n function receipt(\n address _credit,\n address _keeper,\n uint256 _amount\n ) external;\n\n function receiptETH(address _keeper, uint256 _amount) external;\n\n function addJob(address _job) external;\n\n function getJobs() external view returns (address[] memory);\n\n function removeJob(address _job) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function isKeeper(address _keeper) external returns (bool);\n\n function isMinKeeper(\n address _keeper,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function bond(address _bonding, uint256 _amount) external;\n\n function getKeepers() external view returns (address[] memory);\n\n function activate(address _bonding) external;\n\n function unbond(address _bonding, uint256 _amount) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function withdraw(address _bonding) external;\n\n function dispute(address _keeper) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function permit(\n address _owner,\n address _spender,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3r.sol';\n\ncontract Keep3rForTestnet is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3r.sol';\n\ncontract Keep3rForTest is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3r.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\n\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @param _governance Address of governance\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\n constructor(\n address _governance, // governance\n address _keep3rHelperSidechain, // helper\n address _wrappedKP3R, // keep3rV1\n address _keep3rEscrow // keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\n\n // Keep3rSidechainAccountance\n\n /// @inheritdoc IKeep3rSidechainAccountance\n function virtualReserves() external view override returns (int256 _virtualReserves) {\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\n }\n\n // Keep3rJobFundableLiquidity\n\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\n /// @param _liquidity Address of the liquidity token being approved\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\n /// @param _liquidity Address of the liquidity token being observed\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n\n // Will always ask for 2 accumulators in sidechain\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Keep3rJobsWorkable\n\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\n function worked(address) external pure override {\n revert Deprecated();\n }\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Uses a USD per gas unit payment mechanism\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\n if (_initialGas == 0) revert GasNotInitialized();\n // Gas used for quote calculations & payment is not rewarded\n uint256 _gasLeft = _getGasLeft();\n\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\n\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _kp3rPayment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\n }\n\n // Keep3rKeeperFundable\n\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\n function _depositBonds(uint256 _amount) internal virtual override {\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\n }\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// solhint-disable-next-line no-empty-blocks\n\nimport '../peripherals/IMintable.sol';\n\n/// @title Keep3rEscrow contract\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\ninterface IKeep3rEscrow is IMintable {\n /// @notice Emitted when Keep3rEscrow#deposit function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _sender The address that called the function\n /// @param _amount The amount of wKP3R the user deposited\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#mint function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _recipient The address that will received the newly minted wKP3R\n /// @param _amount The amount of wKP3R minted to the recipient\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\n /// @param _newWKP3R The address of the wKP3R contract\n event wKP3RSet(address _newWKP3R);\n\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\n error InsufficientBalance();\n\n /// @notice Lists the address of the wKP3R contract\n /// @return _wKP3RAddress The address of wKP3R\n function wKP3R() external view returns (address _wKP3RAddress);\n\n /// @notice Deposits wKP3R into the contract\n /// @param _amount The amount of wKP3R to deposit\n function deposit(uint256 _amount) external;\n\n /// @notice mints wKP3R to the recipient\n /// @param _amount The amount of wKP3R to mint\n function mint(uint256 _amount) external;\n\n /// @notice sets the wKP3R address\n /// @param _wKP3R the wKP3R address\n function setWKP3R(address _wKP3R) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../IKeep3rHelper.sol';\n\n/// @title Keep3rHelperSidechain contract\n/// @notice Contains all the helper functions for sidechain keep3r implementations\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\n // Events\n\n /// @notice The oracle for a liquidity has been saved\n /// @param _liquidity The address of the given liquidity\n /// @param _oraclePool The address of the oracle pool\n event OracleSet(address _liquidity, address _oraclePool);\n\n /// @notice Emitted when the WETH USD pool is changed\n /// @param _address Address of the new WETH USD pool\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\n\n /// Variables\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n /// @return _weth Address of WETH token\n // solhint-disable func-name-mixedcase\n function WETH() external view returns (address _weth);\n\n /// @return _oracle The address of the observable pool for given liquidity\n function oracle(address _liquidity) external view returns (address _oracle);\n\n /// @notice WETH-USD pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice Quotes USD to ETH\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\n /// @param _usd The amount of USD to quote to ETH\n /// @return _eth The resulting amount of ETH after quoting the USD\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\n\n /// Methods\n\n /// @notice Sets an oracle for a given liquidity\n /// @param _liquidity The address of the liquidity\n /// @param _oracle The address of the pool used to quote the liquidity from\n /// @dev The oracle must contain KP3R as either token0 or token1\n function setOracle(address _liquidity, address _oracle) external;\n\n /// @notice Sets an oracle for querying WETH/USD quote\n /// @param _poolAddress The address of the pool used as oracle\n /// @dev The oracle must contain WETH as either token0 or token1\n function setWethUsdPool(address _poolAddress) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IKeep3rJobs.sol';\n\n/// @title Keep3rJobWorkableRated contract\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\n /// @notice Throws when job contract calls deprecated worked(address) function\n error Deprecated();\n\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title IKeep3rSidechainAccountance interface\n/// @notice Implements a view to get the amount of credits that can be withdrawn\ninterface IKeep3rSidechainAccountance {\n /// @notice The surplus amount of wKP3Rs in escrow contract\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\n function virtualReserves() external view returns (int256 _virtualReserves);\n}\n" + }, + "solidity/interfaces/peripherals/IMintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IGovernable.sol';\nimport './IBaseErrors.sol';\n\n/// @title Mintable contract\n/// @notice Manages the minter role\ninterface IMintable is IBaseErrors, IGovernable {\n // Events\n\n /// @notice Emitted when governance sets a new minter\n /// @param _minter Address of the new minter\n event MinterSet(address _minter);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not the minter\n error OnlyMinter();\n\n // Variables\n\n /// @notice Stores the minter address\n /// @return _minter The minter addresss\n function minter() external view returns (address _minter);\n\n // Methods\n\n /// @notice Sets a new address to be the minter\n /// @param _minter The address set as the minter\n function setMinter(address _minter) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rSidechainForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTest is Keep3rSidechain {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _governance,\n address _keep3rHelper,\n address _wrappedKP3R,\n address _keep3rEscrow\n ) Keep3rSidechain(_governance, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n}\n" + }, + "solidity/for-test/JobRatedForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\n\ncontract JobRatedForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n uint256 public usdPerGasUnit = 1;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n}\n" + }, + "solidity/for-test/JobForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract JobForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/for-test/BasicJob.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract BasicJob {\n error KeeperNotValid();\n\n address public keep3r;\n uint256 public nonce;\n uint256[] public array;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external upkeep {}\n\n function workHard(uint256 _howHard) external upkeep {\n for (uint256 i = nonce; i < _howHard; i++) {\n nonce++;\n }\n }\n\n function workRefund(uint256 _howHard) external upkeep {\n for (uint256 i; i < _howHard; i++) {\n array.push(i);\n }\n\n while (array.length > 0) {\n array.pop();\n }\n }\n\n modifier upkeep() {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\n _;\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/peripherals/IBaseErrors.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/external/IKeep3rV1.sol';\nimport '../interfaces/IKeep3rHelperParameters.sol';\nimport './peripherals/Governable.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\n /// @inheritdoc IKeep3rHelperParameters\n address public immutable override KP3R;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public constant override BOOST_BASE = 10_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBoost = 11_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override maxBoost = 12_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override targetBond = 200 ether;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override workExtraGas = 34_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint32 public override quoteTwapTime = 10 minutes;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBaseFee = 15e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minPriorityFee = 2e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n address public override keep3rV2;\n\n /// @inheritdoc IKeep3rHelperParameters\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Governable(_governance) {\n KP3R = _kp3r;\n keep3rV2 = _keep3rV2;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setKp3rWethPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\n minBoost = _minBoost;\n emit MinBoostChange(minBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\n maxBoost = _maxBoost;\n emit MaxBoostChange(maxBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\n targetBond = _targetBond;\n emit TargetBondChange(targetBond);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\n if (_keep3rV2 == address(0)) revert ZeroAddress();\n keep3rV2 = _keep3rV2;\n emit Keep3rV2Change(keep3rV2);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\n workExtraGas = _workExtraGas;\n emit WorkExtraGasChange(workExtraGas);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\n _setQuoteTwapTime(_quoteTwapTime);\n }\n\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\n quoteTwapTime = _quoteTwapTime;\n emit QuoteTwapTimeChange(quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\n minBaseFee = _minBaseFee;\n emit MinBaseFeeChange(minBaseFee);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\n minPriorityFee = _minPriorityFee;\n emit MinPriorityFeeChange(minPriorityFee);\n }\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function _setKp3rWethPool(address _poolAddress) internal {\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\n\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\n\n return TokenOraclePool(_poolAddress, _isTKNToken0);\n }\n}\n" + }, + "solidity/contracts/libraries/TickMath.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n// solhint-disable\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n // Second inequality must be < because the price can never reach the price at the max tick\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport './pool/IUniswapV3PoolImmutables.sol';\nimport './pool/IUniswapV3PoolState.sol';\nimport './pool/IUniswapV3PoolDerivedState.sol';\nimport './pool/IUniswapV3PoolActions.sol';\nimport './pool/IUniswapV3PoolOwnerActions.sol';\nimport './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolEvents\n{\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// observationIndex The index of the last oracle observation that was written,\n /// observationCardinality The current maximum number of observations stored in the pool,\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper,\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return _liquidity The amount of liquidity in the position,\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 _liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// Returns initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" + }, + "solidity/for-test/UniV3PairManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport '../contracts/libraries/LiquidityAmounts.sol';\nimport '../contracts/libraries/FixedPoint96.sol';\nimport '../contracts/libraries/FullMath.sol';\nimport '../contracts/libraries/TickMath.sol';\nimport '../contracts/UniV3PairManager.sol';\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManagerForTest is UniV3PairManager {\n constructor(address _pool, address _governance) UniV3PairManager(_pool, _governance) {}\n\n function internalAddLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n external\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n return _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n }\n\n function internalPay(\n address token,\n address payer,\n address recipient,\n uint256 value\n ) external {\n return _pay(token, payer, recipient, value);\n }\n\n function internalMint(address dst, uint256 amount) external {\n return _mint(dst, amount);\n }\n\n function internalBurn(address dst, uint256 amount) external {\n return _burn(dst, amount);\n }\n\n function internalTransferTokens(\n address src,\n address dst,\n uint256 amount\n ) external {\n _transferTokens(src, dst, amount);\n }\n\n function internalSafeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) external {\n _safeTransferFrom(token, from, to, value);\n }\n\n receive() external payable {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "solidity/contracts/libraries/LiquidityAmounts.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport './FullMath.sol';\nimport './FixedPoint96.sol';\n\n// solhint-disable\nlibrary LiquidityAmounts {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/contracts/libraries/FixedPoint96.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nlibrary FixedPoint96 {\n // solhint-disable\n uint8 internal constant RESOLUTION = 96;\n uint256 internal constant Q96 = 0x1000000000000000000000000;\n}\n" + }, + "solidity/contracts/UniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport './libraries/LiquidityAmounts.sol';\nimport './libraries/FixedPoint96.sol';\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\n\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\nimport './peripherals/Governable.sol';\n\ncontract UniV3PairManager is IUniV3PairManager, Governable {\n /// @inheritdoc IERC20Metadata\n string public override name;\n\n /// @inheritdoc IERC20Metadata\n string public override symbol;\n\n /// @inheritdoc IERC20\n uint256 public override totalSupply;\n\n /// @inheritdoc IPairManager\n address public immutable override factory;\n\n /// @inheritdoc IPairManager\n address public immutable override token0;\n\n /// @inheritdoc IPairManager\n address public immutable override token1;\n\n /// @inheritdoc IPairManager\n address public immutable override pool;\n\n /// @inheritdoc IUniV3PairManager\n uint24 public immutable override fee;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioAX96;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioBX96;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickLower;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickUpper;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickSpacing;\n\n /// @notice Uniswap's maximum tick\n /// @dev Due to tick spacing, pools with different fees may have differences between _MAX_TICK and tickUpper. Use tickUpper to find the max tick of the pool.\n int24 private constant _MAX_TICK = 887272;\n\n /// @inheritdoc IERC20Metadata\n //solhint-disable-next-line const-name-snakecase\n uint8 public constant override decimals = 18;\n\n /// @inheritdoc IERC20\n mapping(address => mapping(address => uint256)) public override allowance;\n\n /// @inheritdoc IERC20\n mapping(address => uint256) public override balanceOf;\n\n /// @notice Struct that contains token0, token1, and fee of the Uniswap pool\n PoolKey private _poolKey;\n\n constructor(address _pool, address _governance) Governable(_governance) {\n uint24 _fee = IUniswapV3Pool(_pool).fee();\n address _token0 = IUniswapV3Pool(_pool).token0();\n address _token1 = IUniswapV3Pool(_pool).token1();\n int24 _tickSpacing = IUniswapV3Pool(_pool).tickSpacing();\n int24 _tickUpper = _MAX_TICK - (_MAX_TICK % _tickSpacing);\n int24 _tickLower = -_tickUpper;\n\n factory = msg.sender;\n pool = _pool;\n fee = _fee;\n tickSpacing = _tickSpacing;\n tickUpper = _tickUpper;\n tickLower = _tickLower;\n token0 = _token0;\n token1 = _token1;\n name = string(abi.encodePacked('Keep3rLP - ', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n symbol = string(abi.encodePacked('kLP-', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n\n sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(_tickLower);\n sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(_tickUpper);\n _poolKey = PoolKey({token0: _token0, token1: _token1, fee: _fee});\n }\n\n // This low-level function should be called from a contract which performs important safety checks\n /// @inheritdoc IUniV3PairManager\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint128 liquidity) {\n (liquidity, , ) = _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n _mint(to, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external override {\n MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));\n if (msg.sender != pool) revert OnlyPool();\n if (amount0Owed > 0) _pay(decoded._poolKey.token0, decoded.payer, pool, amount0Owed);\n if (amount1Owed > 0) _pay(decoded._poolKey.token1, decoded.payer, pool, amount1Owed);\n }\n\n /// @inheritdoc IUniV3PairManager\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint256 amount0, uint256 amount1) {\n (amount0, amount1) = IUniswapV3Pool(pool).burn(tickLower, tickUpper, liquidity);\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n\n IUniswapV3Pool(pool).collect(to, tickLower, tickUpper, uint128(amount0), uint128(amount1));\n _burn(msg.sender, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function collect() external override onlyGovernance returns (uint256 amount0, uint256 amount1) {\n (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n (amount0, amount1) = IUniswapV3Pool(pool).collect(governance, tickLower, tickUpper, tokensOwed0, tokensOwed1);\n }\n\n /// @inheritdoc IUniV3PairManager\n function position()\n external\n view\n override\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n )\n {\n (liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128, tokensOwed0, tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n }\n\n /// @inheritdoc IERC20\n function approve(address spender, uint256 amount) external override returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transfer(address to, uint256 amount) external override returns (bool) {\n _transferTokens(msg.sender, to, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool) {\n address spender = msg.sender;\n uint256 spenderAllowance = allowance[from][spender];\n\n if (spender != from && spenderAllowance != type(uint256).max) {\n uint256 newAllowance = spenderAllowance - amount;\n allowance[from][spender] = newAllowance;\n\n emit Approval(from, spender, newAllowance);\n }\n\n _transferTokens(from, to, amount);\n return true;\n }\n\n /// @notice Adds liquidity to an initialized pool\n /// @dev Reverts if the returned amount0 is less than amount0Min or if amount1 is less than amount1Min\n /// @dev This function calls the mint function of the corresponding Uniswap pool, which in turn calls UniswapV3Callback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @return liquidity The calculated liquidity we get for the token amounts we provided\n /// @return amount0 The amount of token0 we ended up providing\n /// @return amount1 The amount of token1 we ended up providing\n function _addLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n internal\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(pool).slot0();\n\n liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, amount0Desired, amount1Desired);\n\n (amount0, amount1) = IUniswapV3Pool(pool).mint(\n address(this),\n tickLower,\n tickUpper,\n liquidity,\n abi.encode(MintCallbackData({_poolKey: _poolKey, payer: msg.sender}))\n );\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n }\n\n /// @notice Transfers the passed-in token from the payer to the recipient for the corresponding value\n /// @param token The token to be transferred to the recipient\n /// @param from The address of the payer\n /// @param to The address of the passed-in tokens recipient\n /// @param value How much of that token to be transferred from payer to the recipient\n function _pay(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n _safeTransferFrom(token, from, to, value);\n }\n\n /// @notice Mints Keep3r credits to the passed-in address of recipient and increases total supply of Keep3r credits by the corresponding amount\n /// @param to The recipient of the Keep3r credits\n /// @param amount The amount Keep3r credits to be minted to the recipient\n function _mint(address to, uint256 amount) internal {\n totalSupply += amount;\n balanceOf[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @notice Burns Keep3r credits to the passed-in address of recipient and reduces total supply of Keep3r credits by the corresponding amount\n /// @param to The address that will get its Keep3r credits burned\n /// @param amount The amount Keep3r credits to be burned from the recipient/recipient\n function _burn(address to, uint256 amount) internal {\n totalSupply -= amount;\n balanceOf[to] -= amount;\n emit Transfer(to, address(0), amount);\n }\n\n /// @notice Transfers amount of Keep3r credits between two addresses\n /// @param from The user that transfers the Keep3r credits\n /// @param to The user that receives the Keep3r credits\n /// @param amount The amount of Keep3r credits to be transferred\n function _transferTokens(\n address from,\n address to,\n uint256 amount\n ) internal {\n balanceOf[from] -= amount;\n balanceOf[to] += amount;\n\n emit Transfer(from, to, amount);\n }\n\n /// @notice Transfers the passed-in token from the specified \"from\" to the specified \"to\" for the corresponding value\n /// @dev Reverts with IUniV3PairManager#UnsuccessfulTransfer if the transfer was not successful,\n /// or if the passed data length is different than 0 and the decoded data is not a boolean\n /// @param token The token to be transferred to the specified \"to\"\n /// @param from The address which is going to transfer the tokens\n /// @param value How much of that token to be transferred from \"from\" to \"to\"\n function _safeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert UnsuccessfulTransfer();\n }\n}\n" + }, + "solidity/interfaces/external/IWeth9.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IWeth9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256) external;\n}\n" + }, + "solidity/interfaces/IUniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IPairManager.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\nimport './peripherals/IGovernable.sol';\n\n/// @title Pair Manager contract\n/// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner\n/// so that the user can use it as liquidity for a Keep3rJob\ninterface IUniV3PairManager is IGovernable, IPairManager {\n // Structs\n struct PoolKey {\n address token0;\n address token1;\n uint24 fee;\n }\n\n /// @notice The data to be decoded by the UniswapV3MintCallback function\n struct MintCallbackData {\n PoolKey _poolKey; // Struct that contains token0, token1, and fee of the pool passed into the constructor\n address payer; // The address of the payer, which will be the msg.sender of the mint function\n }\n\n // Variables\n\n /// @notice The fee of the Uniswap pool passed into the constructor\n /// @return _fee The fee of the Uniswap pool passed into the constructor\n function fee() external view returns (uint24 _fee);\n\n /// @notice Highest tick in the Uniswap's curve\n /// @return _tickUpper The highest tick in the Uniswap's curve\n function tickUpper() external view returns (int24 _tickUpper);\n\n /// @notice Lowest tick in the Uniswap's curve\n /// @return _tickLower The lower tick in the Uniswap's curve\n function tickLower() external view returns (int24 _tickLower);\n\n /// @notice The pair tick spacing\n /// @return _tickSpacing The pair tick spacing\n function tickSpacing() external view returns (int24 _tickSpacing);\n\n /// @notice The sqrtRatioAX96 at the lowest tick (-887200) of the Uniswap pool\n /// @return _sqrtPriceA96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the lowest tick\n function sqrtRatioAX96() external view returns (uint160 _sqrtPriceA96);\n\n /// @notice The sqrtRatioBX96 at the highest tick (887200) of the Uniswap pool\n /// @return _sqrtPriceBX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the highest tick\n function sqrtRatioBX96() external view returns (uint160 _sqrtPriceBX96);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the pool\n error OnlyPool();\n\n /// @notice Throws when the slippage exceeds what the user is comfortable with\n error ExcessiveSlippage();\n\n /// @notice Throws when a transfer is unsuccessful\n error UnsuccessfulTransfer();\n\n // Methods\n\n /// @notice This function is called after a user calls IUniV3PairManager#mint function\n /// It ensures that any tokens owed to the pool are paid by the msg.sender of IUniV3PairManager#mint function\n /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity\n /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity\n /// @param data The encoded token0, token1, fee (_poolKey) and the payer (msg.sender) of the IUniV3PairManager#mint function\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external;\n\n /// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool\n /// @dev Triggers UniV3PairManager#uniswapV3MintCallback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @param to The address to which the kLP tokens are going to be minted to\n /// @return liquidity kLP tokens sent in exchange for the provision of tokens\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint128 liquidity);\n\n /// @notice Returns the pair manager's position in the corresponding UniswapV3 pool\n /// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager\n /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position\n /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position\n /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation\n /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation\n function position()\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees\n // owed to a specific position to the recipient, in this case, that recipient is the pair manager\n /// @dev The collected fees will be sent to governance\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect() external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity\n // in the entire range\n /// @param liquidity The amount of liquidity to be burned\n /// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)\n /// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)\n /// @param to The address that will receive the due fees\n /// @return amount0 The calculated amount of token0 that will be sent to the recipient\n /// @return amount1 The calculated amount of token1 that will be sent to the recipient\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint256 amount0, uint256 amount1);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "solidity/interfaces/IPairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IGovernable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ninterface IPairManagerFactory is IGovernable {\n // Variables\n\n /// @notice Maps the address of a Uniswap pool, to the address of the corresponding PairManager\n /// For example, the uniswap address of DAI-WETH, will return the Keep3r/DAI-WETH pair manager address\n /// @param _pool The address of the Uniswap pool\n /// @return _pairManager The address of the corresponding pair manager\n function pairManagers(address _pool) external view returns (address _pairManager);\n\n // Events\n\n /// @notice Emitted when a new pair manager is created\n /// @param _pool The address of the corresponding Uniswap pool\n /// @param _pairManager The address of the just-created pair manager\n event PairCreated(address _pool, address _pairManager);\n\n // Errors\n\n /// @notice Throws an error if the pair manager is already initialized\n error AlreadyInitialized();\n\n /// @notice Throws an error if the caller is not the owner\n error OnlyOwner();\n\n // Methods\n\n /// @notice Creates a new pair manager based on the address of a Uniswap pool\n /// For example, the uniswap address of DAI-WETH, will create the Keep3r/DAI-WETH pool\n /// @param _pool The address of the Uniswap pool the pair manager will be based of\n /// @return _pairManager The address of the just-created pair manager\n function createPairManager(address _pool) external returns (address _pairManager);\n}\n" + }, + "solidity/contracts/UniV3PairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IPairManagerFactory.sol';\nimport './UniV3PairManager.sol';\nimport './peripherals/Governable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ncontract UniV3PairManagerFactory is IPairManagerFactory, Governable {\n mapping(address => address) public override pairManagers;\n\n constructor(address _governance) Governable(_governance) {}\n\n ///@inheritdoc IPairManagerFactory\n function createPairManager(address _pool) external override returns (address _pairManager) {\n if (pairManagers[_pool] != address(0)) revert AlreadyInitialized();\n _pairManager = address(new UniV3PairManager(_pool, governance));\n pairManagers[_pool] = _pairManager;\n emit PairCreated(_pool, _pairManager);\n }\n}\n" + }, + "solidity/for-test/peripherals/GovernableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" + }, + "solidity/for-test/BridgeForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ncontract BridgeForTest is ERC20 {\n address public immutable kp3r;\n\n constructor(address _kp3r) ERC20('Wrapped KP3R', 'wKP3R') {\n kp3r = _kp3r;\n }\n\n function bridge(uint256 _amount) external {\n IERC20(kp3r).transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n }\n\n function bridgeBack(uint256 _amount) external {\n _burn(msg.sender, _amount);\n IERC20(kp3r).transfer(msg.sender, _amount);\n }\n}\n" + }, + "solidity/for-test/ERC20ForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(uint256 _amount) public {\n _mint(msg.sender, _amount);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(uint256 _amount) public {\n _burn(msg.sender, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n function deposit() external payable {\n // Function added for compatibility with WETH\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperFundableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperFundable.sol';\n\ncontract Keep3rKeeperFundableForTest is Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function isKeeper(address _keeper) external view returns (bool) {\n return _keepers.contains(_keeper);\n }\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/Mintable.sol';\nimport '../peripherals/DustCollector.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rEscrow\n address public override wKP3R;\n\n /// @param _governance Address of governance\n /// @param _wKP3R Address of wrapped KP3R implementation\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\n wKP3R = _wKP3R;\n }\n\n /// @inheritdoc IKeep3rEscrow\n function deposit(uint256 _amount) external override {\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function mint(uint256 _amount) external override onlyMinter {\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function setWKP3R(address _wKP3R) external override onlyGovernance {\n if (_wKP3R == address(0)) revert ZeroAddress();\n wKP3R = _wKP3R;\n emit wKP3RSet(wKP3R);\n }\n}\n" + }, + "solidity/contracts/peripherals/Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IMintable.sol';\nimport './Governable.sol';\n\nabstract contract Mintable is Governable, IMintable {\n /// @inheritdoc IMintable\n address public override minter;\n\n constructor(address _governance) Governable(_governance) {}\n\n /// @inheritdoc IMintable\n function setMinter(address _minter) external override onlyGovernance {\n if (_minter == address(0)) revert ZeroAddress();\n minter = _minter;\n emit MinterSet(_minter);\n }\n\n /// @notice Functions with this modifier can only be called by the minter;\n modifier onlyMinter() {\n if (msg.sender != minter) revert OnlyMinter();\n _;\n }\n}\n" + }, + "solidity/for-test/peripherals/DustCollectorForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/DustCollector.sol';\n\ncontract DustCollectorForTest is DustCollector {\n constructor() DustCollector() Governable(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rAccountanceForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rAccountance.sol';\n\ncontract Keep3rAccountanceForTest is Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor() Keep3rRoles(msg.sender) {}\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n\n function setKeeper(address keeper) external {\n _keepers.add(keeper);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableLiquidityForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol';\n\ncontract Keep3rJobFundableLiquidityForTest is Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external returns (bool) {\n return _jobLiquidities[_job].add(_liquidity);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewTickOrder(address _liquidity) external view returns (bool) {\n return _isKP3RToken0[_liquidity];\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function internalSettleJobAccountance(address _job) external {\n _settleJobAccountance(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobDisputable.sol';\n\ncontract Keep3rJobDisputableForTest is Keep3rJobDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function internalJobLiquidityCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobLiquidityCredits[_job];\n }\n\n function internalJobPeriodCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobPeriodCredits[_job];\n }\n\n function internalJobTokens(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobTokens[_job].length());\n for (uint256 i; i < _jobTokens[_job].length(); i++) {\n _tokens[i] = _jobTokens[_job].at(i);\n }\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobLiquidities[_job].length());\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n _tokens[i] = _jobLiquidities[_job].at(i);\n }\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rDisputable.sol';\n\ncontract Keep3rDisputableForTest is Keep3rDisputable {\n constructor() Keep3rParameters(address(0), address(0), address(0)) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperDisputable.sol';\n\ncontract Keep3rKeeperDisputableForTest is Keep3rKeeperDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function internalSlash(\n address _bonded,\n address _keeper,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external {\n _slash(_bonded, _keeper, _bondAmount, _unbondAmount);\n }\n\n function isKeeper(address _address) external view returns (bool _isKeeper) {\n _isKeeper = _keepers.contains(_address);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableCreditsForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableCredits.sol';\n\ncontract Keep3rJobFundableCreditsForTest is Keep3rJobFundableCredits {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job, address _jobOwner) external {\n _jobs.add(_job);\n jobOwner[_job] = _jobOwner;\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function isJobToken(address _job, address _token) external view returns (bool _contains) {\n _contains = _jobTokens[_job].contains(_token);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/IKeep3rHelper.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n /// @inheritdoc IKeep3rHelper\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelper\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\n // solhint-disable-next-line avoid-tx-origin\n return getRewardAmountFor(tx.origin, _gasUsed);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\n _bonds = Math.min(_bonds, targetBond);\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\n _rewardBoost = _cap * _getBasefee();\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\n }\n\n /// @inheritdoc IKeep3rHelper\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\n address _token0;\n address _token1;\n (_token0, _token1) = getPoolTokens(_pool);\n if (_token0 == KP3R) {\n return true;\n } else if (_token1 != KP3R) {\n revert LiquidityPairInvalid();\n }\n }\n\n /// @inheritdoc IKeep3rHelper\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n override\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n )\n {\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\n _tickCumulative1 = _uniswapResponse[0];\n if (_uniswapResponse.length > 1) {\n _tickCumulative2 = _uniswapResponse[1];\n }\n _success = true;\n } catch (bytes memory) {}\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n )\n {\n _oneEthQuote = quote(1 ether);\n _boost = getRewardBoostFor(_bonds);\n _extra = workExtraGas;\n }\n\n /// @inheritdoc IKeep3rHelper\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure override returns (uint256 _kp3rAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) public pure override returns (uint256 _quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\n }\n }\n\n /// @notice Gets the gas basefee cost to calculate keeper rewards\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTestnet is Keep3rHelper {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal pure override returns (uint256) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/Keep3rHelperForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTest is Keep3rHelper {\n uint256 public basefee;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal view override returns (uint256) {\n return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee();\n }\n\n function setBaseFee(uint256 _baseFee) external {\n basefee = _baseFee;\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rHelper.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\n /// @inheritdoc IKeep3rHelperSidechain\n mapping(address => address) public override oracle;\n /// @inheritdoc IKeep3rHelperSidechain\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n address public immutable override WETH;\n\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\n /// @param _governance Address of governance\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\n /// @dev Oracle pools should use 18 decimals tokens\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\n WETH = _weth;\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\n _setQuoteTwapTime(1 days);\n workExtraGas = 0;\n }\n\n /// @inheritdoc IKeep3rHelper\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\n oracle[_liquidity] = _oracle;\n emit OracleSet(_liquidity, _oracle);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n /// @dev Oracle is compatible with IUniswapV3Pool\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setWethUsdPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override(Keep3rHelper, IKeep3rHelper)\n returns (\n uint256 _boost,\n uint256 _oneUsdQuote,\n uint256 _extraGas\n )\n {\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\n _boost = getRewardBoostFor(_bonds);\n _extraGas = workExtraGas;\n }\n\n function _setWethUsdPool(address _poolAddress) internal {\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\n }\n\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rParametersForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rParameters.sol';\n\ncontract Keep3rParametersForTest is Keep3rParameters {\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobWorkableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobWorkable.sol';\n\ncontract Keep3rJobWorkableForTest is Keep3rJobWorkable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewGas() external view returns (uint256) {\n return _initialGas;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobMigrationForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobMigration.sol';\n\ncontract Keep3rJobMigrationForTest is Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(address => uint256) public settleJobAccountanceCallCount;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobTokenListLength(address _job) external view returns (uint256) {\n return _jobTokens[_job].length();\n }\n\n function viewJobLiquidityList(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewMigrationCreatedAt(address _fromJob, address _toJob) external view returns (uint256) {\n return _migrationCreatedAt[_fromJob][_toJob];\n }\n\n function isJob(address _job) external view returns (bool) {\n return _jobs.contains(_job);\n }\n\n function _settleJobAccountance(address _job) internal override {\n settleJobAccountanceCallCount[_job]++;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobManager.sol';\n\ncontract Keep3rJobManagerForTest is Keep3rJobManager {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rRoles(msg.sender) {}\n\n function isJob(address _job) external view returns (bool _isJob) {\n _isJob = _jobs.contains(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobOwnershipForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobOwnership.sol';\n\ncontract Keep3rJobOwnershipForTest is Keep3rJobOwnership {}\n" + }, + "solidity/for-test/libraries/LiquidityAmountsForTest.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/libraries/FullMath.sol';\nimport '../../contracts/libraries/FixedPoint96.sol';\n\n/// @dev Made this library into a contract to be able to calculate liquidity more precisely for tests\n\n// solhint-disable\ncontract LiquidityAmountsForTest {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) external pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) external pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/for-test/IUniswapV3PoolForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n// solhint-disable-next-line no-empty-blocks\ninterface IUniswapV3PoolForTest is IERC20Minimal, IUniswapV3Pool {\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Minimal ERC20 interface for Uniswap\n/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3\ninterface IERC20Minimal {\n /// @notice Returns the balance of a token\n /// @param account The account for which to look up the number of tokens it has, i.e. its balance\n /// @return The number of tokens held by the account\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Transfers the amount of token from the `msg.sender` to the recipient\n /// @param recipient The account that will receive the amount transferred\n /// @param amount The number of tokens to send from the sender to the recipient\n /// @return Returns true for a successful transfer, false for an unsuccessful transfer\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /// @notice Returns the current allowance given to a spender by an owner\n /// @param owner The account of the token owner\n /// @param spender The account of the token spender\n /// @return The current allowance granted by `owner` to `spender`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`\n /// @param spender The account which will be allowed to spend a given amount of the owners tokens\n /// @param amount The amount of tokens allowed to be used by `spender`\n /// @return Returns true for a successful approval, false for unsuccessful\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`\n /// @param sender The account from which the transfer will be initiated\n /// @param recipient The recipient of the transfer\n /// @param amount The amount of the transfer\n /// @return Returns true for a successful transfer, false for unsuccessful\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.\n /// @param from The account from which the tokens were sent, i.e. the balance decreased\n /// @param to The account to which the tokens were sent, i.e. the balance increased\n /// @param value The amount of tokens that were transferred\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.\n /// @param owner The account that approved spending of its tokens\n /// @param spender The account for which the spending allowance was modified\n /// @param value The new allowance from the owner to the spender\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 33 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" + } + } + } +} \ No newline at end of file diff --git a/deployments/goerli/solcInputs/7120622b6fa82f1fde1bb178c8155d0d.json b/deployments/goerli/solcInputs/7120622b6fa82f1fde1bb178c8155d0d.json new file mode 100644 index 0000000..bbcdded --- /dev/null +++ b/deployments/goerli/solcInputs/7120622b6fa82f1fde1bb178c8155d0d.json @@ -0,0 +1,328 @@ +{ + "language": "Solidity", + "sources": { + "solidity/contracts/Keep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport './peripherals/jobs/Keep3rJobs.sol';\nimport './peripherals/keepers/Keep3rKeepers.sol';\nimport './peripherals/DustCollector.sol';\n\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\n}\n" + }, + "solidity/interfaces/IKeep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobManager.sol';\nimport './Keep3rJobWorkable.sol';\nimport './Keep3rJobDisputable.sol';\n\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\nimport './Keep3rKeeperDisputable.sol';\n\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\n" + }, + "solidity/contracts/peripherals/DustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '../../contracts/peripherals/Governable.sol';\nimport '../../interfaces/peripherals/IDustCollector.sol';\n\nabstract contract DustCollector is IDustCollector, Governable {\n using SafeERC20 for IERC20;\n\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external override onlyGovernance {\n if (_to == address(0)) revert ZeroAddress();\n if (_token == _ETH_ADDRESS) {\n payable(_to).transfer(_amount);\n } else {\n IERC20(_token).safeTransfer(_to, _amount);\n }\n emit DustSent(_token, _amount, _to);\n }\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" + }, + "solidity/interfaces/peripherals/IBaseErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" + }, + "solidity/interfaces/peripherals/IGovernable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" + }, + "solidity/interfaces/peripherals/IDustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @inheritdoc IKeep3rJobManager\n function addJob(address _job) external override {\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\n if (hasBonded[_job]) revert AlreadyAKeeper();\n _jobs.add(_job);\n jobOwner[_job] = msg.sender;\n emit JobAddition(_job, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobMigration.sol';\nimport '../../../interfaces/IKeep3rHelper.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 internal _initialGas;\n\n /// @inheritdoc IKeep3rJobWorkable\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\n _initialGas = _getGasLeft();\n if (_keepers.contains(_keeper)) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external override returns (bool _isBondedKeeper) {\n _initialGas = _getGasLeft();\n if (\n _keepers.contains(_keeper) &&\n bonds[_keeper][_bond] >= _minBond &&\n workCompleted[_keeper] >= _earned &&\n block.timestamp - firstSeen[_keeper] >= _age\n ) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function worked(address _keeper) external virtual override {\n if (_initialGas == 0) revert GasNotInitialized();\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _gasLeft = _getGasLeft();\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n _gasLeft = _getGasLeft();\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function bondedPayment(address _keeper, uint256 _payment) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (disputes[_keeper]) revert Disputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_keeper, _amount);\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\n }\n\n function _bondedPayment(\n address _job,\n address _keeper,\n uint256 _payment\n ) internal {\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\n\n workedAt[_job] = block.timestamp;\n _jobLiquidityCredits[_job] -= _payment;\n bonds[_keeper][keep3rV1] += _payment;\n workCompleted[_keeper] += _payment;\n totalBonds += _payment;\n }\n\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\n /// @param _gasLeft Amount of gas left after working the job\n /// @param _extraGas Amount of expected unaccounted gas\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\n /// @return _payment Amount to be payed in KP3R tokens\n function _calculatePayment(\n uint256 _gasLeft,\n uint256 _extraGas,\n uint256 _oneEthQuote,\n uint256 _boost\n ) internal view returns (uint256 _payment) {\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\n }\n\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\n _gasLeft = (gasleft() * 64) / 63;\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\nimport '../Keep3rDisputable.sol';\n\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\n\n try IERC20(_token).transfer(governance, _amount) {} catch {}\n jobTokenCredits[_job][_token] -= _amount;\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit JobSlashToken(_job, _token, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobPendingOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\n jobPendingOwner[_job] = _newOwner;\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\n }\n\n /// @inheritdoc IKeep3rJobOwnership\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\n address _previousOwner = jobOwner[_job];\n\n jobOwner[_job] = jobPendingOwner[_job];\n delete jobPendingOwner[_job];\n\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\n }\n\n modifier onlyJobOwner(address _job) {\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\n _;\n }\n\n modifier onlyPendingJobOwner(address _job) {\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\nimport './Keep3rRoles.sol';\n\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @notice List of all enabled keepers\n EnumerableSet.AddressSet internal _keepers;\n\n /// @inheritdoc IKeep3rAccountance\n uint256 public override totalBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override workCompleted;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override firstSeen;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override disputes;\n\n /// @inheritdoc IKeep3rAccountance\n /// @notice Mapping (job => bonding => amount)\n mapping(address => mapping(address => uint256)) public override bonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\n\n /// @notice The current liquidity credits available for a job\n mapping(address => uint256) internal _jobLiquidityCredits;\n\n /// @notice Map the address of a job to its correspondent periodCredits\n mapping(address => uint256) internal _jobPeriodCredits;\n\n /// @notice Enumerable array of Job Tokens for Credits\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\n\n /// @notice List of liquidities that a job has (job => liquidities)\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\n\n /// @notice Liquidity pool to observe\n mapping(address => address) internal _liquidityPool;\n\n /// @notice Tracks if a pool has KP3R as token0\n mapping(address => bool) internal _isKP3RToken0;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override hasBonded;\n\n /// @notice List of all enabled jobs\n EnumerableSet.AddressSet internal _jobs;\n\n /// @inheritdoc IKeep3rAccountance\n function jobs() external view override returns (address[] memory _list) {\n _list = _jobs.values();\n }\n\n /// @inheritdoc IKeep3rAccountance\n function keepers() external view override returns (address[] memory _list) {\n _list = _keepers.values();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport './DustCollector.sol';\nimport './Governable.sol';\n\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override slashers;\n\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override disputers;\n\n constructor(address _governance) Governable(_governance) DustCollector() {}\n\n /// @inheritdoc IKeep3rRoles\n function addSlasher(address _slasher) external override onlyGovernance {\n if (_slasher == address(0)) revert ZeroAddress();\n if (slashers[_slasher]) revert SlasherExistent();\n slashers[_slasher] = true;\n emit SlasherAdded(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeSlasher(address _slasher) external override onlyGovernance {\n if (!slashers[_slasher]) revert SlasherUnexistent();\n delete slashers[_slasher];\n emit SlasherRemoved(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function addDisputer(address _disputer) external override onlyGovernance {\n if (_disputer == address(0)) revert ZeroAddress();\n if (disputers[_disputer]) revert DisputerExistent();\n disputers[_disputer] = true;\n emit DisputerAdded(_disputer);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeDisputer(address _disputer) external override onlyGovernance {\n if (!disputers[_disputer]) revert DisputerUnexistent();\n delete disputers[_disputer];\n emit DisputerRemoved(_disputer);\n }\n\n /// @notice Functions with this modifier can only be called by either a slasher or governance\n modifier onlySlasher {\n if (!slashers[msg.sender]) revert OnlySlasher();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by either a disputer or governance\n modifier onlyDisputer {\n if (!disputers[msg.sender]) revert OnlyDisputer();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Governable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public override governance;\n\n /// @inheritdoc IGovernable\n address public override pendingGovernance;\n\n constructor(address _governance) {\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\n governance = _governance;\n }\n\n /// @inheritdoc IGovernable\n function setGovernance(address _governance) external override onlyGovernance {\n pendingGovernance = _governance;\n emit GovernanceProposal(_governance);\n }\n\n /// @inheritdoc IGovernable\n function acceptGovernance() external override onlyPendingGovernance {\n governance = pendingGovernance;\n delete pendingGovernance;\n emit GovernanceSet(governance);\n }\n\n /// @notice Functions with this modifier can only be called by governance\n modifier onlyGovernance {\n if (msg.sender != governance) revert OnlyGovernance();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernance\n modifier onlyPendingGovernance {\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\n _;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\n\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobMigration\n mapping(address => address) public override pendingJobMigrations;\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\n\n /// @inheritdoc IKeep3rJobMigration\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\n if (_fromJob == _toJob) revert JobMigrationImpossible();\n\n pendingJobMigrations[_fromJob] = _toJob;\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\n\n emit JobMigrationRequested(_fromJob, _toJob);\n }\n\n /// @inheritdoc IKeep3rJobMigration\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\n\n // force job credits update for both jobs\n _settleJobAccountance(_fromJob);\n _settleJobAccountance(_toJob);\n\n // migrate tokens\n while (_jobTokens[_fromJob].length() > 0) {\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\n _jobTokens[_fromJob].remove(_tokenToMigrate);\n _jobTokens[_toJob].add(_tokenToMigrate);\n }\n\n // migrate liquidities\n while (_jobLiquidities[_fromJob].length() > 0) {\n address _liquidity = _jobLiquidities[_fromJob].at(0);\n\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\n delete liquidityAmount[_fromJob][_liquidity];\n\n _jobLiquidities[_toJob].add(_liquidity);\n _jobLiquidities[_fromJob].remove(_liquidity);\n }\n\n // migrate job balances\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\n delete _jobPeriodCredits[_fromJob];\n\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\n delete _jobLiquidityCredits[_fromJob];\n\n // stop _fromJob from being a job\n delete rewardedAt[_fromJob];\n _jobs.remove(_fromJob);\n\n // delete unused data slots\n delete jobOwner[_fromJob];\n delete jobPendingOwner[_fromJob];\n delete _migrationCreatedAt[_fromJob][_toJob];\n delete pendingJobMigrations[_fromJob];\n\n emit JobMigrationSuccessful(_fromJob, _toJob);\n }\n}\n" + }, + "solidity/interfaces/IKeep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rHelperParameters.sol';\n\n/// @title Keep3rHelper contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelper is IKeep3rHelperParameters {\n // Errors\n\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\n error LiquidityPairInvalid();\n\n // Methods\n // solhint-enable func-name-mixedcase\n\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\n /// @param _eth The amount of ETH\n /// @return _amountOut The amount of KP3R\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\n\n /// @notice Returns the amount of KP3R the keeper has bonded\n /// @param _keeper The address of the keeper to check\n /// @return _amountBonded The amount of KP3R the keeper has bonded\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\n /// @param _keeper The address of the keeper to check\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\n\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\n /// @return _rewardBoost The reward boost that corresponds to the keeper\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\n\n /// @notice Given a pool address, returns the underlying tokens of the pair\n /// @param _pool Address of the correspondant pool\n /// @return _token0 Address of the first token of the pair\n /// @return _token1 Address of the second token of the pair\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\n\n /// @notice Defines the order of the tokens in the pair for twap calculations\n /// @param _pool Address of the correspondant pool\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\n\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\n /// @param _pool Address of the pool to observe\n /// @param _secondsAgo Array with time references to observe\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\n /// @return _success Boolean indicating if the observe call was succesfull\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n );\n\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\n /// @param _bonds Amount of bonded KP3R owned by the keeper\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\n /// @return _extra Amount of extra gas that should be added to the gas spent\n function getPaymentParams(uint256 _bonds)\n external\n view\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n );\n\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\n /// @param _liquidityAmount Amount of liquidity to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _kp3rAmount);\n\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\n /// @param _baseAmount Amount of token to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _quoteAmount);\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice Cooldown between withdrawals\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override nonReentrant {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n // KP3R shouldn't be used for direct token payments\n if (_token == keep3rV1) revert TokenUnallowed();\n uint256 _before = IERC20(_token).balanceOf(address(this));\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\n uint256 _tokenFee = (_received * fee) / _BASE;\n jobTokenCredits[_job][_token] += _received - _tokenFee;\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\n IERC20(_token).safeTransfer(governance, _tokenFee);\n _jobTokens[_job].add(_token);\n\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\n }\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external override nonReentrant onlyJobOwner(_job) {\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\n if (disputes[_job]) revert JobDisputed();\n\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_receiver, _amount);\n\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/IPairManager.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '../../libraries/FullMath.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice List of liquidities that are accepted in the system\n EnumerableSet.AddressSet internal _approvedLiquidities;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override rewardedAt;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override workedAt;\n\n /// @notice Tracks an address and returns its TickCache\n mapping(address => TickCache) internal _tick;\n\n // Views\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approvedLiquidities() external view override returns (address[] memory _list) {\n _list = _approvedLiquidities.values();\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n _periodCredits += _getReward(\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\n );\n }\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n\n // If the job was rewarded in the past 1 period time\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\n // If the job has period credits, update minted job credits to new twap\n _liquidityCredits = _periodCredits > 0\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\n } else {\n // Else return a full period worth of credits if current credits have expired\n _liquidityCredits = _periodCredits;\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n uint256 _cooldown = block.timestamp;\n\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\n // Will calculate cooldown if it outdated\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will calculate cooldown from last reward reference in this period\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\n } else {\n // Will calculate cooldown from last reward timestamp\n _cooldown -= rewardedAt[_job];\n }\n } else {\n // Will calculate cooldown from period start if expired\n _cooldown -= _period(block.timestamp);\n }\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\n\n if (_tick[_liquidity].period == lastPeriod) {\n // Will only ask for current period accumulator if liquidity is outdated\n uint32[] memory _secondsAgo = new uint32[](1);\n int56 previousTick = _tick[_liquidity].current;\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - previousTick;\n } else if (_tick[_liquidity].period < lastPeriod) {\n // Will ask for 2 accumulators if liquidity is expired\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n }\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Methods\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n _settleJobAccountance(_job);\n _jobLiquidityCredits[_job] += _amount;\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\n delete _liquidityPool[_liquidity];\n delete _isKP3RToken0[_liquidity];\n delete _tick[_liquidity];\n\n emit LiquidityRevocation(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override nonReentrant {\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\n if (!_jobs.contains(_job)) revert JobUnavailable();\n\n _jobLiquidities[_job].add(_liquidity);\n\n _settleJobAccountance(_job);\n\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\n liquidityAmount[_job][_liquidity] += _amount;\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlyJobOwner(_job) {\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\n pendingUnbonds[_job][_liquidity] += _amount;\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit Unbonding(_job, _liquidity, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external override onlyJobOwner(_job) {\n if (_receiver == address(0)) revert ZeroAddress();\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\n if (disputes[_job]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[_job][_liquidity];\n\n delete pendingUnbonds[_job][_liquidity];\n delete canWithdrawAfter[_job][_liquidity];\n\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\n }\n\n // Internal functions\n\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\n if (rewardedAt[_job] < _period(block.timestamp)) {\n // Will exit function if job has been rewarded in current period\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\n // Will reset job to period syncronicity if a full period passed without rewards\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] = _period(block.timestamp);\n _rewarded = true;\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will reset job's syncronicity if last reward was more than epoch ago\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] += rewardPeriodTime;\n _rewarded = true;\n } else if (workedAt[_job] < _period(block.timestamp)) {\n // First keeper on period has to update job accountance to current twaps\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\n // Updating job accountance does not reward job\n }\n }\n }\n\n /// @notice Only called if _jobLiquidityCredits < payment\n function _rewardJobCredits(address _job) internal {\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\n rewardedAt[_job] = block.timestamp;\n }\n\n /// @notice Updates accountance for _jobPeriodCredits\n function _updateJobPeriod(address _job) internal {\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\n }\n\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n if (_tick[_liquidity].period != _period(block.timestamp)) {\n // Updates liquidity cache only if needed\n _tick[_liquidity] = observeLiquidity(_liquidity);\n }\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\n }\n }\n }\n\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\n function _unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) internal nonReentrant {\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\n\n // Ensures current twaps in job liquidities\n _updateJobPeriod(_job);\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\n\n // A liquidity can be revoked causing a job to have 0 periodCredits\n if (_jobPeriodCredits[_job] > 0) {\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\n }\n\n liquidityAmount[_job][_liquidity] -= _amount;\n if (liquidityAmount[_job][_liquidity] == 0) {\n _jobLiquidities[_job].remove(_liquidity);\n }\n }\n\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\n if (_timePassed < rewardPeriodTime) {\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\n } else _result = _multiplier;\n }\n\n /// @notice Returns the start of the period of the provided timestamp\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\n return _timestamp - (_timestamp % rewardPeriodTime);\n }\n\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\n }\n\n /// @notice Returns underlying KP3R amount for a given liquidity amount\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\n if (_tick[_liquidity].period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\n }\n }\n\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\n /// @dev Ensures a maximum of 1 period of credits\n function _settleJobAccountance(address _job) internal virtual {\n _updateJobCreditsIfNeeded(_job);\n _rewardJobCredits(_job);\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/IKeep3rHelper.sol';\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\nimport './Keep3rAccountance.sol';\n\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1Proxy;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rHelper;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override bondTime = 3 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override unbondTime = 14 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override liquidityMinimum = 3 ether;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override rewardPeriodTime = 5 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override inflationPeriod = 34 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override fee = 30;\n\n /// @notice The base that will be used to calculate the fee\n uint256 internal constant _BASE = 10_000;\n\n /// @notice The minimum reward period\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) {\n keep3rHelper = _keep3rHelper;\n keep3rV1 = _keep3rV1;\n keep3rV1Proxy = _keep3rV1Proxy;\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\n if (_keep3rHelper == address(0)) revert ZeroAddress();\n keep3rHelper = _keep3rHelper;\n emit Keep3rHelperChange(_keep3rHelper);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\n if (_keep3rV1 == address(0)) revert ZeroAddress();\n _mint(totalBonds);\n\n keep3rV1 = _keep3rV1;\n emit Keep3rV1Change(_keep3rV1);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\n keep3rV1Proxy = _keep3rV1Proxy;\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\n bondTime = _bondTime;\n emit BondTimeChange(_bondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\n unbondTime = _unbondTime;\n emit UnbondTimeChange(_unbondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\n liquidityMinimum = _liquidityMinimum;\n emit LiquidityMinimumChange(_liquidityMinimum);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\n rewardPeriodTime = _rewardPeriodTime;\n emit RewardPeriodTimeChange(_rewardPeriodTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\n inflationPeriod = _inflationPeriod;\n emit InflationPeriodChange(_inflationPeriod);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setFee(uint256 _fee) external override onlyGovernance {\n fee = _fee;\n emit FeeChange(_fee);\n }\n\n function _mint(uint256 _amount) internal {\n totalBonds -= _amount;\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IGovernable.sol';\n\ninterface IKeep3rV1Proxy is IGovernable {\n // Structs\n struct Recipient {\n address recipient;\n uint256 caps;\n }\n\n // Variables\n function keep3rV1() external view returns (address);\n\n function minter() external view returns (address);\n\n function next(address) external view returns (uint256);\n\n function caps(address) external view returns (uint256);\n\n function recipients() external view returns (address[] memory);\n\n function recipientsCaps() external view returns (Recipient[] memory);\n\n // Errors\n error Cooldown();\n error NoDrawableAmount();\n error ZeroAddress();\n error OnlyMinter();\n\n // Methods\n function addRecipient(address recipient, uint256 amount) external;\n\n function removeRecipient(address recipient) external;\n\n function draw() external returns (uint256 _amount);\n\n function setKeep3rV1(address _keep3rV1) external;\n\n function setMinter(address _minter) external;\n\n function mint(uint256 _amount) external;\n\n function mint(address _account, uint256 _amount) external;\n\n function setKeep3rV1Governance(address _governance) external;\n\n function acceptKeep3rV1Governance() external;\n\n function dispute(address _keeper) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function addJob(address _job) external;\n\n function removeJob(address _job) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n}\n" + }, + "solidity/interfaces/IKeep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rHelperParameters contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelperParameters {\n // Structs\n\n /// @dev KP3R-WETH Pool address and isKP3RToken0\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\n struct TokenOraclePool {\n address poolAddress;\n bool isTKNToken0;\n }\n\n // Errors\n\n /// @notice Throws when pool does not have KP3R as token0 nor token1\n error InvalidOraclePool();\n\n // Events\n\n /// @notice Emitted when the kp3r weth pool is changed\n /// @param _address Address of the new kp3r weth pool\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\n\n /// @notice Emitted when the minimum boost multiplier is changed\n /// @param _minBoost The minimum boost multiplier\n event MinBoostChange(uint256 _minBoost);\n\n /// @notice Emitted when the maximum boost multiplier is changed\n /// @param _maxBoost The maximum boost multiplier\n event MaxBoostChange(uint256 _maxBoost);\n\n /// @notice Emitted when the target bond amount is changed\n /// @param _targetBond The target bond amount\n event TargetBondChange(uint256 _targetBond);\n\n /// @notice Emitted when the Keep3r V2 address is changed\n /// @param _keep3rV2 The address of Keep3r V2\n event Keep3rV2Change(address _keep3rV2);\n\n /// @notice Emitted when the work extra gas amount is changed\n /// @param _workExtraGas The work extra gas\n event WorkExtraGasChange(uint256 _workExtraGas);\n\n /// @notice Emitted when the quote twap time is changed\n /// @param _quoteTwapTime The twap time for quoting\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\n\n /// @notice Emitted when minimum rewarded gas fee is changed\n /// @param _minBaseFee The minimum rewarded gas fee\n event MinBaseFeeChange(uint256 _minBaseFee);\n\n /// @notice Emitted when minimum rewarded priority fee is changed\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\n event MinPriorityFeeChange(uint256 _minPriorityFee);\n\n // Variables\n\n /// @notice Address of KP3R token\n /// @return _kp3r Address of KP3R token\n // solhint-disable func-name-mixedcase\n function KP3R() external view returns (address _kp3r);\n\n /// @notice The boost base used to calculate the boost rewards for the keeper\n /// @return _base The boost base number\n function BOOST_BASE() external view returns (uint256 _base);\n\n /// @notice KP3R-WETH pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\n /// @return _multiplier The minimum boost multiplier\n function minBoost() external view returns (uint256 _multiplier);\n\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\n /// @return _multiplier The maximum boost multiplier\n function maxBoost() external view returns (uint256 _multiplier);\n\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\n /// @return _target The amount of KP3R that comforms the targetBond\n function targetBond() external view returns (uint256 _target);\n\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\n /// @return _workExtraGas The work unaccounted gas amount\n function workExtraGas() external view returns (uint256 _workExtraGas);\n\n /// @notice The twap time for quoting\n /// @return _quoteTwapTime The twap time\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\n\n /// @notice The minimum base fee that is used to calculate keeper rewards\n /// @return _minBaseFee The minimum rewarded gas fee\n function minBaseFee() external view returns (uint256 _minBaseFee);\n\n /// @notice The minimum priority fee that is also rewarded for keepers\n /// @return _minPriorityFee The minimum rewarded priority fee\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\n\n /// @notice Address of Keep3r V2\n /// @return _keep3rV2 Address of Keep3r V2\n function keep3rV2() external view returns (address _keep3rV2);\n\n // Methods\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function setKp3rWethPool(address _poolAddress) external;\n\n /// @notice Sets the minimum boost multiplier\n /// @param _minBoost The minimum boost multiplier\n function setMinBoost(uint256 _minBoost) external;\n\n /// @notice Sets the maximum boost multiplier\n /// @param _maxBoost The maximum boost multiplier\n function setMaxBoost(uint256 _maxBoost) external;\n\n /// @notice Sets the target bond amount\n /// @param _targetBond The target bond amount\n function setTargetBond(uint256 _targetBond) external;\n\n /// @notice Sets the Keep3r V2 address\n /// @param _keep3rV2 The address of Keep3r V2\n function setKeep3rV2(address _keep3rV2) external;\n\n /// @notice Sets the work extra gas amount\n /// @param _workExtraGas The work extra gas\n function setWorkExtraGas(uint256 _workExtraGas) external;\n\n /// @notice Sets the quote twap time\n /// @param _quoteTwapTime The twap time for quoting\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\n\n /// @notice Sets the minimum rewarded gas fee\n /// @param _minBaseFee The minimum rewarded gas fee\n function setMinBaseFee(uint256 _minBaseFee) external;\n\n /// @notice Sets the minimum rewarded gas priority fee\n /// @param _minPriorityFee The minimum rewarded priority fee\n function setMinPriorityFee(uint256 _minPriorityFee) external;\n}\n" + }, + "solidity/interfaces/IPairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n/// @title Pair Manager interface\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\ninterface IPairManager is IERC20Metadata {\n /// @notice Address of the factory from which the pair manager was created\n /// @return _factory The address of the PairManager Factory\n function factory() external view returns (address _factory);\n\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\n /// @return _pool The address of the pool\n function pool() external view returns (address _pool);\n\n /// @notice Token0 of the pool\n /// @return _token0 The address of token0\n function token0() external view returns (address _token0);\n\n /// @notice Token1 of the pool\n /// @return _token1 The address of token1\n function token1() external view returns (address _token1);\n}\n" + }, + "solidity/contracts/libraries/FullMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (~denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "solidity/contracts/peripherals/Keep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rParameters.sol';\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\n\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\n /// @inheritdoc IKeep3rDisputable\n function dispute(address _jobOrKeeper) external override onlyDisputer {\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\n disputes[_jobOrKeeper] = true;\n emit Dispute(_jobOrKeeper, msg.sender);\n }\n\n /// @inheritdoc IKeep3rDisputable\n function resolve(address _jobOrKeeper) external override onlyDisputer {\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\n disputes[_jobOrKeeper] = false;\n emit Resolve(_jobOrKeeper, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rKeeperFundable.sol';\nimport '../Keep3rDisputable.sol';\nimport '../../../interfaces/external/IKeep3rV1.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\n }\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function revoke(address _keeper) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _keepers.remove(_keeper);\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\n emit KeeperRevoke(_keeper, msg.sender);\n }\n\n function _slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) internal {\n if (_bonded != keep3rV1) {\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\n }\n bonds[_keeper][_bonded] -= _bondAmount;\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nimport '../../../interfaces/external/IKeep3rV1.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperFundable\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\n if (disputes[msg.sender]) revert Disputed();\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\n\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\n\n hasBonded[msg.sender] = true;\n pendingBonds[msg.sender][_bonding] += _amount;\n\n emit Bonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function activate(address _bonding) external override {\n address _keeper = msg.sender;\n if (disputes[_keeper]) revert Disputed();\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\n if (_canActivateAfter == 0) revert BondsUnexistent();\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\n\n if (firstSeen[_keeper] == 0) {\n firstSeen[_keeper] = block.timestamp;\n }\n _keepers.add(_keeper);\n\n uint256 _amount = pendingBonds[_keeper][_bonding];\n delete pendingBonds[_keeper][_bonding];\n\n // bond provided tokens\n bonds[_keeper][_bonding] += _amount;\n if (_bonding == keep3rV1) {\n totalBonds += _amount;\n _depositBonds(_amount);\n }\n\n emit Activation(_keeper, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function unbond(address _bonding, uint256 _amount) external override {\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\n bonds[msg.sender][_bonding] -= _amount;\n pendingUnbonds[msg.sender][_bonding] += _amount;\n\n emit Unbonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function withdraw(address _bonding) external override nonReentrant {\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\n if (disputes[msg.sender]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\n\n delete pendingUnbonds[msg.sender][_bonding];\n delete canWithdrawAfter[msg.sender][_bonding];\n\n if (_bonding == keep3rV1) _mint(_amount);\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(msg.sender, _bonding, _amount);\n }\n\n function _depositBonds(uint256 _amount) internal virtual {\n IKeep3rV1(keep3rV1).burn(_amount);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n// solhint-disable func-name-mixedcase\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\n // Structs\n struct Checkpoint {\n uint32 fromBlock;\n uint256 votes;\n }\n\n // Events\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event JobAdded(address indexed _job, uint256 _block, address _governance);\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\n event KeeperDispute(address indexed _keeper, uint256 _block);\n event KeeperResolved(address indexed _keeper, uint256 _block);\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\n\n // Variables\n function KPRH() external returns (address);\n\n function delegates(address _delegator) external view returns (address);\n\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\n\n function numCheckpoints(address _account) external view returns (uint32);\n\n function DOMAIN_TYPEHASH() external returns (bytes32);\n\n function DOMAINSEPARATOR() external returns (bytes32);\n\n function DELEGATION_TYPEHASH() external returns (bytes32);\n\n function PERMIT_TYPEHASH() external returns (bytes32);\n\n function nonces(address _user) external view returns (uint256);\n\n function BOND() external returns (uint256);\n\n function UNBOND() external returns (uint256);\n\n function LIQUIDITYBOND() external returns (uint256);\n\n function FEE() external returns (uint256);\n\n function BASE() external returns (uint256);\n\n function ETH() external returns (address);\n\n function bondings(address _user, address _bonding) external view returns (uint256);\n\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\n\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function bonds(address _keeper, address _bonding) external view returns (uint256);\n\n function votes(address _delegator) external view returns (uint256);\n\n function firstSeen(address _keeper) external view returns (uint256);\n\n function disputes(address _keeper) external view returns (bool);\n\n function lastJob(address _keeper) external view returns (uint256);\n\n function workCompleted(address _keeper) external view returns (uint256);\n\n function jobs(address _job) external view returns (bool);\n\n function credits(address _job, address _credit) external view returns (uint256);\n\n function liquidityProvided(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmountsUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function jobProposalDelay(address _job) external view returns (uint256);\n\n function liquidityApplied(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmount(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function keepers(address _keeper) external view returns (bool);\n\n function blacklist(address _keeper) external view returns (bool);\n\n function keeperList(uint256 _index) external view returns (address);\n\n function jobList(uint256 _index) external view returns (address);\n\n function governance() external returns (address);\n\n function pendingGovernance() external returns (address);\n\n function liquidityAccepted(address _liquidity) external view returns (bool);\n\n function liquidityPairs(uint256 _index) external view returns (address);\n\n // Methods\n function getCurrentVotes(address _account) external view returns (uint256);\n\n function addCreditETH(address _job) external payable;\n\n function addCredit(\n address _credit,\n address _job,\n uint256 _amount\n ) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function pairs() external view returns (address[] memory);\n\n function addLiquidityToJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function applyCreditToJob(\n address _provider,\n address _liquidity,\n address _job\n ) external;\n\n function unbondLiquidityFromJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function removeLiquidityFromJob(address _liquidity, address _job) external;\n\n function mint(uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n\n function worked(address _keeper) external;\n\n function receipt(\n address _credit,\n address _keeper,\n uint256 _amount\n ) external;\n\n function receiptETH(address _keeper, uint256 _amount) external;\n\n function addJob(address _job) external;\n\n function getJobs() external view returns (address[] memory);\n\n function removeJob(address _job) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function isKeeper(address _keeper) external returns (bool);\n\n function isMinKeeper(\n address _keeper,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function bond(address _bonding, uint256 _amount) external;\n\n function getKeepers() external view returns (address[] memory);\n\n function activate(address _bonding) external;\n\n function unbond(address _bonding, uint256 _amount) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function withdraw(address _bonding) external;\n\n function dispute(address _keeper) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function permit(\n address _owner,\n address _spender,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3r.sol';\n\ncontract Keep3rForTestnet is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3r.sol';\n\ncontract Keep3rForTest is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3r.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\n\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @param _governance Address of governance\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\n constructor(\n address _governance, // governance\n address _keep3rHelperSidechain, // helper\n address _wrappedKP3R, // keep3rV1\n address _keep3rEscrow // keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\n\n // Keep3rSidechainAccountance\n\n /// @inheritdoc IKeep3rSidechainAccountance\n function virtualReserves() external view override returns (int256 _virtualReserves) {\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\n }\n\n // Keep3rJobFundableLiquidity\n\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\n /// @param _liquidity Address of the liquidity token being approved\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\n /// @param _liquidity Address of the liquidity token being observed\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n\n // Will always ask for 2 accumulators in sidechain\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Keep3rJobsWorkable\n\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\n function worked(address) external pure override {\n revert Deprecated();\n }\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Uses a USD per gas unit payment mechanism\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\n if (_initialGas == 0) revert GasNotInitialized();\n // Gas used for quote calculations & payment is not rewarded\n uint256 _gasLeft = _getGasLeft();\n\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\n\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _kp3rPayment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\n }\n\n // Keep3rKeeperFundable\n\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\n function _depositBonds(uint256 _amount) internal virtual override {\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\n }\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// solhint-disable-next-line no-empty-blocks\n\nimport '../peripherals/IMintable.sol';\n\n/// @title Keep3rEscrow contract\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\ninterface IKeep3rEscrow is IMintable {\n /// @notice Emitted when Keep3rEscrow#deposit function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _sender The address that called the function\n /// @param _amount The amount of wKP3R the user deposited\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#mint function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _recipient The address that will received the newly minted wKP3R\n /// @param _amount The amount of wKP3R minted to the recipient\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\n /// @param _newWKP3R The address of the wKP3R contract\n event wKP3RSet(address _newWKP3R);\n\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\n error InsufficientBalance();\n\n /// @notice Lists the address of the wKP3R contract\n /// @return _wKP3RAddress The address of wKP3R\n function wKP3R() external view returns (address _wKP3RAddress);\n\n /// @notice Deposits wKP3R into the contract\n /// @param _amount The amount of wKP3R to deposit\n function deposit(uint256 _amount) external;\n\n /// @notice mints wKP3R to the recipient\n /// @param _amount The amount of wKP3R to mint\n function mint(uint256 _amount) external;\n\n /// @notice sets the wKP3R address\n /// @param _wKP3R the wKP3R address\n function setWKP3R(address _wKP3R) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../IKeep3rHelper.sol';\n\n/// @title Keep3rHelperSidechain contract\n/// @notice Contains all the helper functions for sidechain keep3r implementations\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\n // Events\n\n /// @notice The oracle for a liquidity has been saved\n /// @param _liquidity The address of the given liquidity\n /// @param _oraclePool The address of the oracle pool\n event OracleSet(address _liquidity, address _oraclePool);\n\n /// @notice Emitted when the WETH USD pool is changed\n /// @param _address Address of the new WETH USD pool\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\n\n /// Variables\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n /// @return _weth Address of WETH token\n // solhint-disable func-name-mixedcase\n function WETH() external view returns (address _weth);\n\n /// @return _oracle The address of the observable pool for given liquidity\n function oracle(address _liquidity) external view returns (address _oracle);\n\n /// @notice WETH-USD pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice Quotes USD to ETH\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\n /// @param _usd The amount of USD to quote to ETH\n /// @return _eth The resulting amount of ETH after quoting the USD\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\n\n /// Methods\n\n /// @notice Sets an oracle for a given liquidity\n /// @param _liquidity The address of the liquidity\n /// @param _oracle The address of the pool used to quote the liquidity from\n /// @dev The oracle must contain KP3R as either token0 or token1\n function setOracle(address _liquidity, address _oracle) external;\n\n /// @notice Sets an oracle for querying WETH/USD quote\n /// @param _poolAddress The address of the pool used as oracle\n /// @dev The oracle must contain WETH as either token0 or token1\n function setWethUsdPool(address _poolAddress) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IKeep3rJobs.sol';\n\n/// @title Keep3rJobWorkableRated contract\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\n /// @notice Throws when job contract calls deprecated worked(address) function\n error Deprecated();\n\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title IKeep3rSidechainAccountance interface\n/// @notice Implements a view to get the amount of credits that can be withdrawn\ninterface IKeep3rSidechainAccountance {\n /// @notice The surplus amount of wKP3Rs in escrow contract\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\n function virtualReserves() external view returns (int256 _virtualReserves);\n}\n" + }, + "solidity/interfaces/peripherals/IMintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IGovernable.sol';\nimport './IBaseErrors.sol';\n\n/// @title Mintable contract\n/// @notice Manages the minter role\ninterface IMintable is IBaseErrors, IGovernable {\n // Events\n\n /// @notice Emitted when governance sets a new minter\n /// @param _minter Address of the new minter\n event MinterSet(address _minter);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not the minter\n error OnlyMinter();\n\n // Variables\n\n /// @notice Stores the minter address\n /// @return _minter The minter addresss\n function minter() external view returns (address _minter);\n\n // Methods\n\n /// @notice Sets a new address to be the minter\n /// @param _minter The address set as the minter\n function setMinter(address _minter) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rSidechainForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTest is Keep3rSidechain {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _governance,\n address _keep3rHelper,\n address _wrappedKP3R,\n address _keep3rEscrow\n ) Keep3rSidechain(_governance, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n}\n" + }, + "solidity/for-test/JobRatedForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\n\ncontract JobRatedForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n uint256 public usdPerGasUnit = 1;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n}\n" + }, + "solidity/for-test/JobForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract JobForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/for-test/BasicJob.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract BasicJob {\n error KeeperNotValid();\n\n address public keep3r;\n uint256 public nonce;\n uint256[] public array;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external upkeep {}\n\n function workHard(uint256 _howHard) external upkeep {\n for (uint256 i = nonce; i < _howHard; i++) {\n nonce++;\n }\n }\n\n function workRefund(uint256 _howHard) external upkeep {\n for (uint256 i; i < _howHard; i++) {\n array.push(i);\n }\n\n while (array.length > 0) {\n array.pop();\n }\n }\n\n modifier upkeep() {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\n _;\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/peripherals/IBaseErrors.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/external/IKeep3rV1.sol';\nimport '../interfaces/IKeep3rHelperParameters.sol';\nimport './peripherals/Governable.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\n /// @inheritdoc IKeep3rHelperParameters\n address public immutable override KP3R;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public constant override BOOST_BASE = 10_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBoost = 11_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override maxBoost = 12_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override targetBond = 200 ether;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override workExtraGas = 34_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint32 public override quoteTwapTime = 10 minutes;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBaseFee = 15e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minPriorityFee = 2e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n address public override keep3rV2;\n\n /// @inheritdoc IKeep3rHelperParameters\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Governable(_governance) {\n KP3R = _kp3r;\n keep3rV2 = _keep3rV2;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setKp3rWethPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\n minBoost = _minBoost;\n emit MinBoostChange(minBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\n maxBoost = _maxBoost;\n emit MaxBoostChange(maxBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\n targetBond = _targetBond;\n emit TargetBondChange(targetBond);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\n if (_keep3rV2 == address(0)) revert ZeroAddress();\n keep3rV2 = _keep3rV2;\n emit Keep3rV2Change(keep3rV2);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\n workExtraGas = _workExtraGas;\n emit WorkExtraGasChange(workExtraGas);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\n _setQuoteTwapTime(_quoteTwapTime);\n }\n\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\n quoteTwapTime = _quoteTwapTime;\n emit QuoteTwapTimeChange(quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\n minBaseFee = _minBaseFee;\n emit MinBaseFeeChange(minBaseFee);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\n minPriorityFee = _minPriorityFee;\n emit MinPriorityFeeChange(minPriorityFee);\n }\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function _setKp3rWethPool(address _poolAddress) internal {\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\n\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\n\n return TokenOraclePool(_poolAddress, _isTKNToken0);\n }\n}\n" + }, + "solidity/contracts/libraries/TickMath.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n// solhint-disable\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n // Second inequality must be < because the price can never reach the price at the max tick\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport './pool/IUniswapV3PoolImmutables.sol';\nimport './pool/IUniswapV3PoolState.sol';\nimport './pool/IUniswapV3PoolDerivedState.sol';\nimport './pool/IUniswapV3PoolActions.sol';\nimport './pool/IUniswapV3PoolOwnerActions.sol';\nimport './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolEvents\n{\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// observationIndex The index of the last oracle observation that was written,\n /// observationCardinality The current maximum number of observations stored in the pool,\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper,\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return _liquidity The amount of liquidity in the position,\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 _liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// Returns initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" + }, + "solidity/for-test/UniV3PairManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport '../contracts/libraries/LiquidityAmounts.sol';\nimport '../contracts/libraries/FixedPoint96.sol';\nimport '../contracts/libraries/FullMath.sol';\nimport '../contracts/libraries/TickMath.sol';\nimport '../contracts/UniV3PairManager.sol';\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManagerForTest is UniV3PairManager {\n constructor(address _pool, address _governance) UniV3PairManager(_pool, _governance) {}\n\n function internalAddLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n external\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n return _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n }\n\n function internalPay(\n address token,\n address payer,\n address recipient,\n uint256 value\n ) external {\n return _pay(token, payer, recipient, value);\n }\n\n function internalMint(address dst, uint256 amount) external {\n return _mint(dst, amount);\n }\n\n function internalBurn(address dst, uint256 amount) external {\n return _burn(dst, amount);\n }\n\n function internalTransferTokens(\n address src,\n address dst,\n uint256 amount\n ) external {\n _transferTokens(src, dst, amount);\n }\n\n function internalSafeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) external {\n _safeTransferFrom(token, from, to, value);\n }\n\n receive() external payable {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "solidity/contracts/libraries/LiquidityAmounts.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport './FullMath.sol';\nimport './FixedPoint96.sol';\n\n// solhint-disable\nlibrary LiquidityAmounts {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/contracts/libraries/FixedPoint96.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nlibrary FixedPoint96 {\n // solhint-disable\n uint8 internal constant RESOLUTION = 96;\n uint256 internal constant Q96 = 0x1000000000000000000000000;\n}\n" + }, + "solidity/contracts/UniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport './libraries/LiquidityAmounts.sol';\nimport './libraries/FixedPoint96.sol';\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\n\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\nimport './peripherals/Governable.sol';\n\ncontract UniV3PairManager is IUniV3PairManager, Governable {\n /// @inheritdoc IERC20Metadata\n string public override name;\n\n /// @inheritdoc IERC20Metadata\n string public override symbol;\n\n /// @inheritdoc IERC20\n uint256 public override totalSupply;\n\n /// @inheritdoc IPairManager\n address public immutable override factory;\n\n /// @inheritdoc IPairManager\n address public immutable override token0;\n\n /// @inheritdoc IPairManager\n address public immutable override token1;\n\n /// @inheritdoc IPairManager\n address public immutable override pool;\n\n /// @inheritdoc IUniV3PairManager\n uint24 public immutable override fee;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioAX96;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioBX96;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickLower;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickUpper;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickSpacing;\n\n /// @notice Uniswap's maximum tick\n /// @dev Due to tick spacing, pools with different fees may have differences between _MAX_TICK and tickUpper. Use tickUpper to find the max tick of the pool.\n int24 private constant _MAX_TICK = 887272;\n\n /// @inheritdoc IERC20Metadata\n //solhint-disable-next-line const-name-snakecase\n uint8 public constant override decimals = 18;\n\n /// @inheritdoc IERC20\n mapping(address => mapping(address => uint256)) public override allowance;\n\n /// @inheritdoc IERC20\n mapping(address => uint256) public override balanceOf;\n\n /// @notice Struct that contains token0, token1, and fee of the Uniswap pool\n PoolKey private _poolKey;\n\n constructor(address _pool, address _governance) Governable(_governance) {\n uint24 _fee = IUniswapV3Pool(_pool).fee();\n address _token0 = IUniswapV3Pool(_pool).token0();\n address _token1 = IUniswapV3Pool(_pool).token1();\n int24 _tickSpacing = IUniswapV3Pool(_pool).tickSpacing();\n int24 _tickUpper = _MAX_TICK - (_MAX_TICK % _tickSpacing);\n int24 _tickLower = -_tickUpper;\n\n factory = msg.sender;\n pool = _pool;\n fee = _fee;\n tickSpacing = _tickSpacing;\n tickUpper = _tickUpper;\n tickLower = _tickLower;\n token0 = _token0;\n token1 = _token1;\n name = string(abi.encodePacked('Keep3rLP - ', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n symbol = string(abi.encodePacked('kLP-', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n\n sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(_tickLower);\n sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(_tickUpper);\n _poolKey = PoolKey({token0: _token0, token1: _token1, fee: _fee});\n }\n\n // This low-level function should be called from a contract which performs important safety checks\n /// @inheritdoc IUniV3PairManager\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint128 liquidity) {\n (liquidity, , ) = _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n _mint(to, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external override {\n MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));\n if (msg.sender != pool) revert OnlyPool();\n if (amount0Owed > 0) _pay(decoded._poolKey.token0, decoded.payer, pool, amount0Owed);\n if (amount1Owed > 0) _pay(decoded._poolKey.token1, decoded.payer, pool, amount1Owed);\n }\n\n /// @inheritdoc IUniV3PairManager\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint256 amount0, uint256 amount1) {\n (amount0, amount1) = IUniswapV3Pool(pool).burn(tickLower, tickUpper, liquidity);\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n\n IUniswapV3Pool(pool).collect(to, tickLower, tickUpper, uint128(amount0), uint128(amount1));\n _burn(msg.sender, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function collect() external override onlyGovernance returns (uint256 amount0, uint256 amount1) {\n (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n (amount0, amount1) = IUniswapV3Pool(pool).collect(governance, tickLower, tickUpper, tokensOwed0, tokensOwed1);\n }\n\n /// @inheritdoc IUniV3PairManager\n function position()\n external\n view\n override\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n )\n {\n (liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128, tokensOwed0, tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n }\n\n /// @inheritdoc IERC20\n function approve(address spender, uint256 amount) external override returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transfer(address to, uint256 amount) external override returns (bool) {\n _transferTokens(msg.sender, to, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool) {\n address spender = msg.sender;\n uint256 spenderAllowance = allowance[from][spender];\n\n if (spender != from && spenderAllowance != type(uint256).max) {\n uint256 newAllowance = spenderAllowance - amount;\n allowance[from][spender] = newAllowance;\n\n emit Approval(from, spender, newAllowance);\n }\n\n _transferTokens(from, to, amount);\n return true;\n }\n\n /// @notice Adds liquidity to an initialized pool\n /// @dev Reverts if the returned amount0 is less than amount0Min or if amount1 is less than amount1Min\n /// @dev This function calls the mint function of the corresponding Uniswap pool, which in turn calls UniswapV3Callback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @return liquidity The calculated liquidity we get for the token amounts we provided\n /// @return amount0 The amount of token0 we ended up providing\n /// @return amount1 The amount of token1 we ended up providing\n function _addLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n internal\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(pool).slot0();\n\n liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, amount0Desired, amount1Desired);\n\n (amount0, amount1) = IUniswapV3Pool(pool).mint(\n address(this),\n tickLower,\n tickUpper,\n liquidity,\n abi.encode(MintCallbackData({_poolKey: _poolKey, payer: msg.sender}))\n );\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n }\n\n /// @notice Transfers the passed-in token from the payer to the recipient for the corresponding value\n /// @param token The token to be transferred to the recipient\n /// @param from The address of the payer\n /// @param to The address of the passed-in tokens recipient\n /// @param value How much of that token to be transferred from payer to the recipient\n function _pay(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n _safeTransferFrom(token, from, to, value);\n }\n\n /// @notice Mints Keep3r credits to the passed-in address of recipient and increases total supply of Keep3r credits by the corresponding amount\n /// @param to The recipient of the Keep3r credits\n /// @param amount The amount Keep3r credits to be minted to the recipient\n function _mint(address to, uint256 amount) internal {\n totalSupply += amount;\n balanceOf[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @notice Burns Keep3r credits to the passed-in address of recipient and reduces total supply of Keep3r credits by the corresponding amount\n /// @param to The address that will get its Keep3r credits burned\n /// @param amount The amount Keep3r credits to be burned from the recipient/recipient\n function _burn(address to, uint256 amount) internal {\n totalSupply -= amount;\n balanceOf[to] -= amount;\n emit Transfer(to, address(0), amount);\n }\n\n /// @notice Transfers amount of Keep3r credits between two addresses\n /// @param from The user that transfers the Keep3r credits\n /// @param to The user that receives the Keep3r credits\n /// @param amount The amount of Keep3r credits to be transferred\n function _transferTokens(\n address from,\n address to,\n uint256 amount\n ) internal {\n balanceOf[from] -= amount;\n balanceOf[to] += amount;\n\n emit Transfer(from, to, amount);\n }\n\n /// @notice Transfers the passed-in token from the specified \"from\" to the specified \"to\" for the corresponding value\n /// @dev Reverts with IUniV3PairManager#UnsuccessfulTransfer if the transfer was not successful,\n /// or if the passed data length is different than 0 and the decoded data is not a boolean\n /// @param token The token to be transferred to the specified \"to\"\n /// @param from The address which is going to transfer the tokens\n /// @param value How much of that token to be transferred from \"from\" to \"to\"\n function _safeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert UnsuccessfulTransfer();\n }\n}\n" + }, + "solidity/interfaces/external/IWeth9.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IWeth9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256) external;\n}\n" + }, + "solidity/interfaces/IUniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IPairManager.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\nimport './peripherals/IGovernable.sol';\n\n/// @title Pair Manager contract\n/// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner\n/// so that the user can use it as liquidity for a Keep3rJob\ninterface IUniV3PairManager is IGovernable, IPairManager {\n // Structs\n struct PoolKey {\n address token0;\n address token1;\n uint24 fee;\n }\n\n /// @notice The data to be decoded by the UniswapV3MintCallback function\n struct MintCallbackData {\n PoolKey _poolKey; // Struct that contains token0, token1, and fee of the pool passed into the constructor\n address payer; // The address of the payer, which will be the msg.sender of the mint function\n }\n\n // Variables\n\n /// @notice The fee of the Uniswap pool passed into the constructor\n /// @return _fee The fee of the Uniswap pool passed into the constructor\n function fee() external view returns (uint24 _fee);\n\n /// @notice Highest tick in the Uniswap's curve\n /// @return _tickUpper The highest tick in the Uniswap's curve\n function tickUpper() external view returns (int24 _tickUpper);\n\n /// @notice Lowest tick in the Uniswap's curve\n /// @return _tickLower The lower tick in the Uniswap's curve\n function tickLower() external view returns (int24 _tickLower);\n\n /// @notice The pair tick spacing\n /// @return _tickSpacing The pair tick spacing\n function tickSpacing() external view returns (int24 _tickSpacing);\n\n /// @notice The sqrtRatioAX96 at the lowest tick (-887200) of the Uniswap pool\n /// @return _sqrtPriceA96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the lowest tick\n function sqrtRatioAX96() external view returns (uint160 _sqrtPriceA96);\n\n /// @notice The sqrtRatioBX96 at the highest tick (887200) of the Uniswap pool\n /// @return _sqrtPriceBX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the highest tick\n function sqrtRatioBX96() external view returns (uint160 _sqrtPriceBX96);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the pool\n error OnlyPool();\n\n /// @notice Throws when the slippage exceeds what the user is comfortable with\n error ExcessiveSlippage();\n\n /// @notice Throws when a transfer is unsuccessful\n error UnsuccessfulTransfer();\n\n // Methods\n\n /// @notice This function is called after a user calls IUniV3PairManager#mint function\n /// It ensures that any tokens owed to the pool are paid by the msg.sender of IUniV3PairManager#mint function\n /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity\n /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity\n /// @param data The encoded token0, token1, fee (_poolKey) and the payer (msg.sender) of the IUniV3PairManager#mint function\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external;\n\n /// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool\n /// @dev Triggers UniV3PairManager#uniswapV3MintCallback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @param to The address to which the kLP tokens are going to be minted to\n /// @return liquidity kLP tokens sent in exchange for the provision of tokens\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint128 liquidity);\n\n /// @notice Returns the pair manager's position in the corresponding UniswapV3 pool\n /// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager\n /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position\n /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position\n /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation\n /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation\n function position()\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees\n // owed to a specific position to the recipient, in this case, that recipient is the pair manager\n /// @dev The collected fees will be sent to governance\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect() external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity\n // in the entire range\n /// @param liquidity The amount of liquidity to be burned\n /// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)\n /// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)\n /// @param to The address that will receive the due fees\n /// @return amount0 The calculated amount of token0 that will be sent to the recipient\n /// @return amount1 The calculated amount of token1 that will be sent to the recipient\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint256 amount0, uint256 amount1);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "solidity/interfaces/IPairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IGovernable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ninterface IPairManagerFactory is IGovernable {\n // Variables\n\n /// @notice Maps the address of a Uniswap pool, to the address of the corresponding PairManager\n /// For example, the uniswap address of DAI-WETH, will return the Keep3r/DAI-WETH pair manager address\n /// @param _pool The address of the Uniswap pool\n /// @return _pairManager The address of the corresponding pair manager\n function pairManagers(address _pool) external view returns (address _pairManager);\n\n // Events\n\n /// @notice Emitted when a new pair manager is created\n /// @param _pool The address of the corresponding Uniswap pool\n /// @param _pairManager The address of the just-created pair manager\n event PairCreated(address _pool, address _pairManager);\n\n // Errors\n\n /// @notice Throws an error if the pair manager is already initialized\n error AlreadyInitialized();\n\n /// @notice Throws an error if the caller is not the owner\n error OnlyOwner();\n\n // Methods\n\n /// @notice Creates a new pair manager based on the address of a Uniswap pool\n /// For example, the uniswap address of DAI-WETH, will create the Keep3r/DAI-WETH pool\n /// @param _pool The address of the Uniswap pool the pair manager will be based of\n /// @return _pairManager The address of the just-created pair manager\n function createPairManager(address _pool) external returns (address _pairManager);\n}\n" + }, + "solidity/contracts/UniV3PairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IPairManagerFactory.sol';\nimport './UniV3PairManager.sol';\nimport './peripherals/Governable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ncontract UniV3PairManagerFactory is IPairManagerFactory, Governable {\n mapping(address => address) public override pairManagers;\n\n constructor(address _governance) Governable(_governance) {}\n\n ///@inheritdoc IPairManagerFactory\n function createPairManager(address _pool) external override returns (address _pairManager) {\n if (pairManagers[_pool] != address(0)) revert AlreadyInitialized();\n _pairManager = address(new UniV3PairManager(_pool, governance));\n pairManagers[_pool] = _pairManager;\n emit PairCreated(_pool, _pairManager);\n }\n}\n" + }, + "solidity/for-test/peripherals/GovernableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" + }, + "solidity/for-test/BridgeForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ncontract BridgeForTest is ERC20 {\n address public immutable kp3r;\n\n constructor(address _kp3r) ERC20('Wrapped KP3R', 'wKP3R') {\n kp3r = _kp3r;\n }\n\n function bridge(uint256 _amount) external {\n IERC20(kp3r).transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n }\n\n function bridgeBack(uint256 _amount) external {\n _burn(msg.sender, _amount);\n IERC20(kp3r).transfer(msg.sender, _amount);\n }\n}\n" + }, + "solidity/for-test/ERC20ForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(uint256 _amount) public {\n _mint(msg.sender, _amount);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(uint256 _amount) public {\n _burn(msg.sender, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n function deposit() external payable {\n // Function added for compatibility with WETH\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperFundableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperFundable.sol';\n\ncontract Keep3rKeeperFundableForTest is Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function isKeeper(address _keeper) external view returns (bool) {\n return _keepers.contains(_keeper);\n }\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/Mintable.sol';\nimport '../peripherals/DustCollector.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rEscrow\n address public override wKP3R;\n\n /// @param _governance Address of governance\n /// @param _wKP3R Address of wrapped KP3R implementation\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\n wKP3R = _wKP3R;\n }\n\n /// @inheritdoc IKeep3rEscrow\n function deposit(uint256 _amount) external override {\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function mint(uint256 _amount) external override onlyMinter {\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function setWKP3R(address _wKP3R) external override onlyGovernance {\n if (_wKP3R == address(0)) revert ZeroAddress();\n wKP3R = _wKP3R;\n emit wKP3RSet(wKP3R);\n }\n}\n" + }, + "solidity/contracts/peripherals/Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IMintable.sol';\nimport './Governable.sol';\n\nabstract contract Mintable is Governable, IMintable {\n /// @inheritdoc IMintable\n address public override minter;\n\n constructor(address _governance) Governable(_governance) {}\n\n /// @inheritdoc IMintable\n function setMinter(address _minter) external override onlyGovernance {\n if (_minter == address(0)) revert ZeroAddress();\n minter = _minter;\n emit MinterSet(_minter);\n }\n\n /// @notice Functions with this modifier can only be called by the minter;\n modifier onlyMinter() {\n if (msg.sender != minter) revert OnlyMinter();\n _;\n }\n}\n" + }, + "solidity/for-test/peripherals/DustCollectorForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/DustCollector.sol';\n\ncontract DustCollectorForTest is DustCollector {\n constructor() DustCollector() Governable(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rAccountanceForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rAccountance.sol';\n\ncontract Keep3rAccountanceForTest is Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor() Keep3rRoles(msg.sender) {}\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n\n function setKeeper(address keeper) external {\n _keepers.add(keeper);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableLiquidityForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol';\n\ncontract Keep3rJobFundableLiquidityForTest is Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external returns (bool) {\n return _jobLiquidities[_job].add(_liquidity);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewTickOrder(address _liquidity) external view returns (bool) {\n return _isKP3RToken0[_liquidity];\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function internalSettleJobAccountance(address _job) external {\n _settleJobAccountance(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobDisputable.sol';\n\ncontract Keep3rJobDisputableForTest is Keep3rJobDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function internalJobLiquidityCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobLiquidityCredits[_job];\n }\n\n function internalJobPeriodCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobPeriodCredits[_job];\n }\n\n function internalJobTokens(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobTokens[_job].length());\n for (uint256 i; i < _jobTokens[_job].length(); i++) {\n _tokens[i] = _jobTokens[_job].at(i);\n }\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobLiquidities[_job].length());\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n _tokens[i] = _jobLiquidities[_job].at(i);\n }\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rDisputable.sol';\n\ncontract Keep3rDisputableForTest is Keep3rDisputable {\n constructor() Keep3rParameters(address(0), address(0), address(0)) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperDisputable.sol';\n\ncontract Keep3rKeeperDisputableForTest is Keep3rKeeperDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function internalSlash(\n address _bonded,\n address _keeper,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external {\n _slash(_bonded, _keeper, _bondAmount, _unbondAmount);\n }\n\n function isKeeper(address _address) external view returns (bool _isKeeper) {\n _isKeeper = _keepers.contains(_address);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableCreditsForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableCredits.sol';\n\ncontract Keep3rJobFundableCreditsForTest is Keep3rJobFundableCredits {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job, address _jobOwner) external {\n _jobs.add(_job);\n jobOwner[_job] = _jobOwner;\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function isJobToken(address _job, address _token) external view returns (bool _contains) {\n _contains = _jobTokens[_job].contains(_token);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/IKeep3rHelper.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n /// @inheritdoc IKeep3rHelper\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelper\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\n // solhint-disable-next-line avoid-tx-origin\n return getRewardAmountFor(tx.origin, _gasUsed);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\n _bonds = Math.min(_bonds, targetBond);\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\n _rewardBoost = _cap * _getBasefee();\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\n }\n\n /// @inheritdoc IKeep3rHelper\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\n address _token0;\n address _token1;\n (_token0, _token1) = getPoolTokens(_pool);\n if (_token0 == KP3R) {\n return true;\n } else if (_token1 != KP3R) {\n revert LiquidityPairInvalid();\n }\n }\n\n /// @inheritdoc IKeep3rHelper\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n override\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n )\n {\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\n _tickCumulative1 = _uniswapResponse[0];\n if (_uniswapResponse.length > 1) {\n _tickCumulative2 = _uniswapResponse[1];\n }\n _success = true;\n } catch (bytes memory) {}\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n )\n {\n _oneEthQuote = quote(1 ether);\n _boost = getRewardBoostFor(_bonds);\n _extra = workExtraGas;\n }\n\n /// @inheritdoc IKeep3rHelper\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure override returns (uint256 _kp3rAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) public pure override returns (uint256 _quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\n }\n }\n\n /// @notice Gets the gas basefee cost to calculate keeper rewards\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\n }\n}\n" + }, + "solidity/for-test/Keep3rHelperForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTest is Keep3rHelper {\n uint256 public basefee;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal view override returns (uint256) {\n return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee();\n }\n\n function setBaseFee(uint256 _baseFee) external {\n basefee = _baseFee;\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rHelper.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\n /// @inheritdoc IKeep3rHelperSidechain\n mapping(address => address) public override oracle;\n /// @inheritdoc IKeep3rHelperSidechain\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n address public immutable override WETH;\n\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\n /// @param _governance Address of governance\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\n /// @dev Oracle pools should use 18 decimals tokens\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\n WETH = _weth;\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\n _setQuoteTwapTime(1 days);\n workExtraGas = 0;\n }\n\n /// @inheritdoc IKeep3rHelper\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\n oracle[_liquidity] = _oracle;\n emit OracleSet(_liquidity, _oracle);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n /// @dev Oracle is compatible with IUniswapV3Pool\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setWethUsdPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override(Keep3rHelper, IKeep3rHelper)\n returns (\n uint256 _boost,\n uint256 _oneUsdQuote,\n uint256 _extraGas\n )\n {\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\n _boost = getRewardBoostFor(_bonds);\n _extraGas = workExtraGas;\n }\n\n function _setWethUsdPool(address _poolAddress) internal {\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\n }\n\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rParametersForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rParameters.sol';\n\ncontract Keep3rParametersForTest is Keep3rParameters {\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobWorkableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobWorkable.sol';\n\ncontract Keep3rJobWorkableForTest is Keep3rJobWorkable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewGas() external view returns (uint256) {\n return _initialGas;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobMigrationForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobMigration.sol';\n\ncontract Keep3rJobMigrationForTest is Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(address => uint256) public settleJobAccountanceCallCount;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobTokenListLength(address _job) external view returns (uint256) {\n return _jobTokens[_job].length();\n }\n\n function viewJobLiquidityList(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewMigrationCreatedAt(address _fromJob, address _toJob) external view returns (uint256) {\n return _migrationCreatedAt[_fromJob][_toJob];\n }\n\n function isJob(address _job) external view returns (bool) {\n return _jobs.contains(_job);\n }\n\n function _settleJobAccountance(address _job) internal override {\n settleJobAccountanceCallCount[_job]++;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobManager.sol';\n\ncontract Keep3rJobManagerForTest is Keep3rJobManager {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rRoles(msg.sender) {}\n\n function isJob(address _job) external view returns (bool _isJob) {\n _isJob = _jobs.contains(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobOwnershipForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobOwnership.sol';\n\ncontract Keep3rJobOwnershipForTest is Keep3rJobOwnership {}\n" + }, + "solidity/for-test/libraries/LiquidityAmountsForTest.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/libraries/FullMath.sol';\nimport '../../contracts/libraries/FixedPoint96.sol';\n\n/// @dev Made this library into a contract to be able to calculate liquidity more precisely for tests\n\n// solhint-disable\ncontract LiquidityAmountsForTest {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) external pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) external pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/for-test/IUniswapV3PoolForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n// solhint-disable-next-line no-empty-blocks\ninterface IUniswapV3PoolForTest is IERC20Minimal, IUniswapV3Pool {\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Minimal ERC20 interface for Uniswap\n/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3\ninterface IERC20Minimal {\n /// @notice Returns the balance of a token\n /// @param account The account for which to look up the number of tokens it has, i.e. its balance\n /// @return The number of tokens held by the account\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Transfers the amount of token from the `msg.sender` to the recipient\n /// @param recipient The account that will receive the amount transferred\n /// @param amount The number of tokens to send from the sender to the recipient\n /// @return Returns true for a successful transfer, false for an unsuccessful transfer\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /// @notice Returns the current allowance given to a spender by an owner\n /// @param owner The account of the token owner\n /// @param spender The account of the token spender\n /// @return The current allowance granted by `owner` to `spender`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`\n /// @param spender The account which will be allowed to spend a given amount of the owners tokens\n /// @param amount The amount of tokens allowed to be used by `spender`\n /// @return Returns true for a successful approval, false for unsuccessful\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`\n /// @param sender The account from which the transfer will be initiated\n /// @param recipient The recipient of the transfer\n /// @param amount The amount of the transfer\n /// @return Returns true for a successful transfer, false for unsuccessful\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.\n /// @param from The account from which the tokens were sent, i.e. the balance decreased\n /// @param to The account to which the tokens were sent, i.e. the balance increased\n /// @param value The amount of tokens that were transferred\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.\n /// @param owner The account that approved spending of its tokens\n /// @param spender The account for which the spending allowance was modified\n /// @param value The new allowance from the owner to the spender\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 33 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" + } + } + } +} \ No newline at end of file diff --git a/deployments/goerli/solcInputs/8c968687fa7312972c014a5aac38beba.json b/deployments/goerli/solcInputs/8c968687fa7312972c014a5aac38beba.json new file mode 100644 index 0000000..a83b63d --- /dev/null +++ b/deployments/goerli/solcInputs/8c968687fa7312972c014a5aac38beba.json @@ -0,0 +1,334 @@ +{ + "language": "Solidity", + "sources": { + "solidity/contracts/Keep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport './peripherals/jobs/Keep3rJobs.sol';\nimport './peripherals/keepers/Keep3rKeepers.sol';\nimport './peripherals/DustCollector.sol';\n\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\n}\n" + }, + "solidity/interfaces/IKeep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobManager.sol';\nimport './Keep3rJobWorkable.sol';\nimport './Keep3rJobDisputable.sol';\n\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\nimport './Keep3rKeeperDisputable.sol';\n\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\n" + }, + "solidity/contracts/peripherals/DustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '../../contracts/peripherals/Governable.sol';\nimport '../../interfaces/peripherals/IDustCollector.sol';\n\nabstract contract DustCollector is IDustCollector, Governable {\n using SafeERC20 for IERC20;\n\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external override onlyGovernance {\n if (_to == address(0)) revert ZeroAddress();\n if (_token == _ETH_ADDRESS) {\n payable(_to).transfer(_amount);\n } else {\n IERC20(_token).safeTransfer(_to, _amount);\n }\n emit DustSent(_token, _amount, _to);\n }\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" + }, + "solidity/interfaces/peripherals/IBaseErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" + }, + "solidity/interfaces/peripherals/IGovernable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" + }, + "solidity/interfaces/peripherals/IDustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @inheritdoc IKeep3rJobManager\n function addJob(address _job) external override {\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\n if (hasBonded[_job]) revert AlreadyAKeeper();\n _jobs.add(_job);\n jobOwner[_job] = msg.sender;\n emit JobAddition(_job, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobMigration.sol';\nimport '../../../interfaces/IKeep3rHelper.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 internal _initialGas;\n\n /// @inheritdoc IKeep3rJobWorkable\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\n _initialGas = _getGasLeft();\n if (_keepers.contains(_keeper)) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external override returns (bool _isBondedKeeper) {\n _initialGas = _getGasLeft();\n if (\n _keepers.contains(_keeper) &&\n bonds[_keeper][_bond] >= _minBond &&\n workCompleted[_keeper] >= _earned &&\n block.timestamp - firstSeen[_keeper] >= _age\n ) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function worked(address _keeper) external virtual override {\n if (_initialGas == 0) revert GasNotInitialized();\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _gasLeft = _getGasLeft();\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n _gasLeft = _getGasLeft();\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function bondedPayment(address _keeper, uint256 _payment) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (disputes[_keeper]) revert Disputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_keeper, _amount);\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\n }\n\n function _bondedPayment(\n address _job,\n address _keeper,\n uint256 _payment\n ) internal {\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\n\n workedAt[_job] = block.timestamp;\n _jobLiquidityCredits[_job] -= _payment;\n bonds[_keeper][keep3rV1] += _payment;\n workCompleted[_keeper] += _payment;\n totalBonds += _payment;\n }\n\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\n /// @param _gasLeft Amount of gas left after working the job\n /// @param _extraGas Amount of expected unaccounted gas\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\n /// @return _payment Amount to be payed in KP3R tokens\n function _calculatePayment(\n uint256 _gasLeft,\n uint256 _extraGas,\n uint256 _oneEthQuote,\n uint256 _boost\n ) internal view returns (uint256 _payment) {\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\n }\n\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\n _gasLeft = (gasleft() * 64) / 63;\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\nimport '../Keep3rDisputable.sol';\n\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\n\n try IERC20(_token).transfer(governance, _amount) {} catch {}\n jobTokenCredits[_job][_token] -= _amount;\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit JobSlashToken(_job, _token, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobPendingOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\n jobPendingOwner[_job] = _newOwner;\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\n }\n\n /// @inheritdoc IKeep3rJobOwnership\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\n address _previousOwner = jobOwner[_job];\n\n jobOwner[_job] = jobPendingOwner[_job];\n delete jobPendingOwner[_job];\n\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\n }\n\n modifier onlyJobOwner(address _job) {\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\n _;\n }\n\n modifier onlyPendingJobOwner(address _job) {\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\nimport './Keep3rRoles.sol';\n\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @notice List of all enabled keepers\n EnumerableSet.AddressSet internal _keepers;\n\n /// @inheritdoc IKeep3rAccountance\n uint256 public override totalBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override workCompleted;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override firstSeen;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override disputes;\n\n /// @inheritdoc IKeep3rAccountance\n /// @notice Mapping (job => bonding => amount)\n mapping(address => mapping(address => uint256)) public override bonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\n\n /// @notice The current liquidity credits available for a job\n mapping(address => uint256) internal _jobLiquidityCredits;\n\n /// @notice Map the address of a job to its correspondent periodCredits\n mapping(address => uint256) internal _jobPeriodCredits;\n\n /// @notice Enumerable array of Job Tokens for Credits\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\n\n /// @notice List of liquidities that a job has (job => liquidities)\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\n\n /// @notice Liquidity pool to observe\n mapping(address => address) internal _liquidityPool;\n\n /// @notice Tracks if a pool has KP3R as token0\n mapping(address => bool) internal _isKP3RToken0;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override hasBonded;\n\n /// @notice List of all enabled jobs\n EnumerableSet.AddressSet internal _jobs;\n\n /// @inheritdoc IKeep3rAccountance\n function jobs() external view override returns (address[] memory _list) {\n _list = _jobs.values();\n }\n\n /// @inheritdoc IKeep3rAccountance\n function keepers() external view override returns (address[] memory _list) {\n _list = _keepers.values();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport './DustCollector.sol';\nimport './Governable.sol';\n\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override slashers;\n\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override disputers;\n\n constructor(address _governance) Governable(_governance) DustCollector() {}\n\n /// @inheritdoc IKeep3rRoles\n function addSlasher(address _slasher) external override onlyGovernance {\n if (_slasher == address(0)) revert ZeroAddress();\n if (slashers[_slasher]) revert SlasherExistent();\n slashers[_slasher] = true;\n emit SlasherAdded(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeSlasher(address _slasher) external override onlyGovernance {\n if (!slashers[_slasher]) revert SlasherUnexistent();\n delete slashers[_slasher];\n emit SlasherRemoved(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function addDisputer(address _disputer) external override onlyGovernance {\n if (_disputer == address(0)) revert ZeroAddress();\n if (disputers[_disputer]) revert DisputerExistent();\n disputers[_disputer] = true;\n emit DisputerAdded(_disputer);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeDisputer(address _disputer) external override onlyGovernance {\n if (!disputers[_disputer]) revert DisputerUnexistent();\n delete disputers[_disputer];\n emit DisputerRemoved(_disputer);\n }\n\n /// @notice Functions with this modifier can only be called by either a slasher or governance\n modifier onlySlasher {\n if (!slashers[msg.sender]) revert OnlySlasher();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by either a disputer or governance\n modifier onlyDisputer {\n if (!disputers[msg.sender]) revert OnlyDisputer();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Governable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public override governance;\n\n /// @inheritdoc IGovernable\n address public override pendingGovernance;\n\n constructor(address _governance) {\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\n governance = _governance;\n }\n\n /// @inheritdoc IGovernable\n function setGovernance(address _governance) external override onlyGovernance {\n pendingGovernance = _governance;\n emit GovernanceProposal(_governance);\n }\n\n /// @inheritdoc IGovernable\n function acceptGovernance() external override onlyPendingGovernance {\n governance = pendingGovernance;\n delete pendingGovernance;\n emit GovernanceSet(governance);\n }\n\n /// @notice Functions with this modifier can only be called by governance\n modifier onlyGovernance {\n if (msg.sender != governance) revert OnlyGovernance();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernance\n modifier onlyPendingGovernance {\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\n _;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\n\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobMigration\n mapping(address => address) public override pendingJobMigrations;\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\n\n /// @inheritdoc IKeep3rJobMigration\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\n if (_fromJob == _toJob) revert JobMigrationImpossible();\n\n pendingJobMigrations[_fromJob] = _toJob;\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\n\n emit JobMigrationRequested(_fromJob, _toJob);\n }\n\n /// @inheritdoc IKeep3rJobMigration\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\n\n // force job credits update for both jobs\n _settleJobAccountance(_fromJob);\n _settleJobAccountance(_toJob);\n\n // migrate tokens\n while (_jobTokens[_fromJob].length() > 0) {\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\n _jobTokens[_fromJob].remove(_tokenToMigrate);\n _jobTokens[_toJob].add(_tokenToMigrate);\n }\n\n // migrate liquidities\n while (_jobLiquidities[_fromJob].length() > 0) {\n address _liquidity = _jobLiquidities[_fromJob].at(0);\n\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\n delete liquidityAmount[_fromJob][_liquidity];\n\n _jobLiquidities[_toJob].add(_liquidity);\n _jobLiquidities[_fromJob].remove(_liquidity);\n }\n\n // migrate job balances\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\n delete _jobPeriodCredits[_fromJob];\n\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\n delete _jobLiquidityCredits[_fromJob];\n\n // stop _fromJob from being a job\n delete rewardedAt[_fromJob];\n _jobs.remove(_fromJob);\n\n // delete unused data slots\n delete jobOwner[_fromJob];\n delete jobPendingOwner[_fromJob];\n delete _migrationCreatedAt[_fromJob][_toJob];\n delete pendingJobMigrations[_fromJob];\n\n emit JobMigrationSuccessful(_fromJob, _toJob);\n }\n}\n" + }, + "solidity/interfaces/IKeep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rHelperParameters.sol';\n\n/// @title Keep3rHelper contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelper is IKeep3rHelperParameters {\n // Errors\n\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\n error LiquidityPairInvalid();\n\n // Methods\n // solhint-enable func-name-mixedcase\n\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\n /// @param _eth The amount of ETH\n /// @return _amountOut The amount of KP3R\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\n\n /// @notice Returns the amount of KP3R the keeper has bonded\n /// @param _keeper The address of the keeper to check\n /// @return _amountBonded The amount of KP3R the keeper has bonded\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\n /// @param _keeper The address of the keeper to check\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\n\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\n /// @return _rewardBoost The reward boost that corresponds to the keeper\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\n\n /// @notice Given a pool address, returns the underlying tokens of the pair\n /// @param _pool Address of the correspondant pool\n /// @return _token0 Address of the first token of the pair\n /// @return _token1 Address of the second token of the pair\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\n\n /// @notice Defines the order of the tokens in the pair for twap calculations\n /// @param _pool Address of the correspondant pool\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\n\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\n /// @param _pool Address of the pool to observe\n /// @param _secondsAgo Array with time references to observe\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\n /// @return _success Boolean indicating if the observe call was succesfull\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n );\n\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\n /// @param _bonds Amount of bonded KP3R owned by the keeper\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\n /// @return _extra Amount of extra gas that should be added to the gas spent\n function getPaymentParams(uint256 _bonds)\n external\n view\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n );\n\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\n /// @param _liquidityAmount Amount of liquidity to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _kp3rAmount);\n\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\n /// @param _baseAmount Amount of token to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _quoteAmount);\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice Cooldown between withdrawals\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override nonReentrant {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n // KP3R shouldn't be used for direct token payments\n if (_token == keep3rV1) revert TokenUnallowed();\n uint256 _before = IERC20(_token).balanceOf(address(this));\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\n uint256 _tokenFee = (_received * fee) / _BASE;\n jobTokenCredits[_job][_token] += _received - _tokenFee;\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\n IERC20(_token).safeTransfer(governance, _tokenFee);\n _jobTokens[_job].add(_token);\n\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\n }\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external override nonReentrant onlyJobOwner(_job) {\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\n if (disputes[_job]) revert JobDisputed();\n\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_receiver, _amount);\n\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/IPairManager.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '../../libraries/FullMath.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice List of liquidities that are accepted in the system\n EnumerableSet.AddressSet internal _approvedLiquidities;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override rewardedAt;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override workedAt;\n\n /// @notice Tracks an address and returns its TickCache\n mapping(address => TickCache) internal _tick;\n\n // Views\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approvedLiquidities() external view override returns (address[] memory _list) {\n _list = _approvedLiquidities.values();\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n _periodCredits += _getReward(\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\n );\n }\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n\n // If the job was rewarded in the past 1 period time\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\n // If the job has period credits, update minted job credits to new twap\n _liquidityCredits = _periodCredits > 0\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\n } else {\n // Else return a full period worth of credits if current credits have expired\n _liquidityCredits = _periodCredits;\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n uint256 _cooldown = block.timestamp;\n\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\n // Will calculate cooldown if it outdated\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will calculate cooldown from last reward reference in this period\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\n } else {\n // Will calculate cooldown from last reward timestamp\n _cooldown -= rewardedAt[_job];\n }\n } else {\n // Will calculate cooldown from period start if expired\n _cooldown -= _period(block.timestamp);\n }\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\n\n if (_tick[_liquidity].period == lastPeriod) {\n // Will only ask for current period accumulator if liquidity is outdated\n uint32[] memory _secondsAgo = new uint32[](1);\n int56 previousTick = _tick[_liquidity].current;\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - previousTick;\n } else if (_tick[_liquidity].period < lastPeriod) {\n // Will ask for 2 accumulators if liquidity is expired\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n }\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Methods\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n _settleJobAccountance(_job);\n _jobLiquidityCredits[_job] += _amount;\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\n delete _liquidityPool[_liquidity];\n delete _isKP3RToken0[_liquidity];\n delete _tick[_liquidity];\n\n emit LiquidityRevocation(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override nonReentrant {\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\n if (!_jobs.contains(_job)) revert JobUnavailable();\n\n _jobLiquidities[_job].add(_liquidity);\n\n _settleJobAccountance(_job);\n\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\n liquidityAmount[_job][_liquidity] += _amount;\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlyJobOwner(_job) {\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\n pendingUnbonds[_job][_liquidity] += _amount;\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit Unbonding(_job, _liquidity, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external override onlyJobOwner(_job) {\n if (_receiver == address(0)) revert ZeroAddress();\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\n if (disputes[_job]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[_job][_liquidity];\n\n delete pendingUnbonds[_job][_liquidity];\n delete canWithdrawAfter[_job][_liquidity];\n\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\n }\n\n // Internal functions\n\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\n if (rewardedAt[_job] < _period(block.timestamp)) {\n // Will exit function if job has been rewarded in current period\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\n // Will reset job to period syncronicity if a full period passed without rewards\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] = _period(block.timestamp);\n _rewarded = true;\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will reset job's syncronicity if last reward was more than epoch ago\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] += rewardPeriodTime;\n _rewarded = true;\n } else if (workedAt[_job] < _period(block.timestamp)) {\n // First keeper on period has to update job accountance to current twaps\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\n // Updating job accountance does not reward job\n }\n }\n }\n\n /// @notice Only called if _jobLiquidityCredits < payment\n function _rewardJobCredits(address _job) internal {\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\n rewardedAt[_job] = block.timestamp;\n }\n\n /// @notice Updates accountance for _jobPeriodCredits\n function _updateJobPeriod(address _job) internal {\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\n }\n\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n if (_tick[_liquidity].period != _period(block.timestamp)) {\n // Updates liquidity cache only if needed\n _tick[_liquidity] = observeLiquidity(_liquidity);\n }\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\n }\n }\n }\n\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\n function _unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) internal nonReentrant {\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\n\n // Ensures current twaps in job liquidities\n _updateJobPeriod(_job);\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\n\n // A liquidity can be revoked causing a job to have 0 periodCredits\n if (_jobPeriodCredits[_job] > 0) {\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\n }\n\n liquidityAmount[_job][_liquidity] -= _amount;\n if (liquidityAmount[_job][_liquidity] == 0) {\n _jobLiquidities[_job].remove(_liquidity);\n }\n }\n\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\n if (_timePassed < rewardPeriodTime) {\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\n } else _result = _multiplier;\n }\n\n /// @notice Returns the start of the period of the provided timestamp\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\n return _timestamp - (_timestamp % rewardPeriodTime);\n }\n\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\n }\n\n /// @notice Returns underlying KP3R amount for a given liquidity amount\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\n if (_tick[_liquidity].period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\n }\n }\n\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\n /// @dev Ensures a maximum of 1 period of credits\n function _settleJobAccountance(address _job) internal virtual {\n _updateJobCreditsIfNeeded(_job);\n _rewardJobCredits(_job);\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/IKeep3rHelper.sol';\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\nimport './Keep3rAccountance.sol';\n\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1Proxy;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rHelper;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override bondTime = 3 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override unbondTime = 14 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override liquidityMinimum = 3 ether;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override rewardPeriodTime = 5 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override inflationPeriod = 34 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override fee = 30;\n\n /// @notice The base that will be used to calculate the fee\n uint256 internal constant _BASE = 10_000;\n\n /// @notice The minimum reward period\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) {\n keep3rHelper = _keep3rHelper;\n keep3rV1 = _keep3rV1;\n keep3rV1Proxy = _keep3rV1Proxy;\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\n if (_keep3rHelper == address(0)) revert ZeroAddress();\n keep3rHelper = _keep3rHelper;\n emit Keep3rHelperChange(_keep3rHelper);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\n if (_keep3rV1 == address(0)) revert ZeroAddress();\n _mint(totalBonds);\n\n keep3rV1 = _keep3rV1;\n emit Keep3rV1Change(_keep3rV1);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\n keep3rV1Proxy = _keep3rV1Proxy;\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\n bondTime = _bondTime;\n emit BondTimeChange(_bondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\n unbondTime = _unbondTime;\n emit UnbondTimeChange(_unbondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\n liquidityMinimum = _liquidityMinimum;\n emit LiquidityMinimumChange(_liquidityMinimum);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\n rewardPeriodTime = _rewardPeriodTime;\n emit RewardPeriodTimeChange(_rewardPeriodTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\n inflationPeriod = _inflationPeriod;\n emit InflationPeriodChange(_inflationPeriod);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setFee(uint256 _fee) external override onlyGovernance {\n fee = _fee;\n emit FeeChange(_fee);\n }\n\n function _mint(uint256 _amount) internal {\n totalBonds -= _amount;\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IGovernable.sol';\n\ninterface IKeep3rV1Proxy is IGovernable {\n // Structs\n struct Recipient {\n address recipient;\n uint256 caps;\n }\n\n // Variables\n function keep3rV1() external view returns (address);\n\n function minter() external view returns (address);\n\n function next(address) external view returns (uint256);\n\n function caps(address) external view returns (uint256);\n\n function recipients() external view returns (address[] memory);\n\n function recipientsCaps() external view returns (Recipient[] memory);\n\n // Errors\n error Cooldown();\n error NoDrawableAmount();\n error ZeroAddress();\n error OnlyMinter();\n\n // Methods\n function addRecipient(address recipient, uint256 amount) external;\n\n function removeRecipient(address recipient) external;\n\n function draw() external returns (uint256 _amount);\n\n function setKeep3rV1(address _keep3rV1) external;\n\n function setMinter(address _minter) external;\n\n function mint(uint256 _amount) external;\n\n function mint(address _account, uint256 _amount) external;\n\n function setKeep3rV1Governance(address _governance) external;\n\n function acceptKeep3rV1Governance() external;\n\n function dispute(address _keeper) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function addJob(address _job) external;\n\n function removeJob(address _job) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n}\n" + }, + "solidity/interfaces/IKeep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rHelperParameters contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelperParameters {\n // Structs\n\n /// @dev KP3R-WETH Pool address and isKP3RToken0\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\n struct TokenOraclePool {\n address poolAddress;\n bool isTKNToken0;\n }\n\n // Errors\n\n /// @notice Throws when pool does not have KP3R as token0 nor token1\n error InvalidOraclePool();\n\n // Events\n\n /// @notice Emitted when the kp3r weth pool is changed\n /// @param _address Address of the new kp3r weth pool\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\n\n /// @notice Emitted when the minimum boost multiplier is changed\n /// @param _minBoost The minimum boost multiplier\n event MinBoostChange(uint256 _minBoost);\n\n /// @notice Emitted when the maximum boost multiplier is changed\n /// @param _maxBoost The maximum boost multiplier\n event MaxBoostChange(uint256 _maxBoost);\n\n /// @notice Emitted when the target bond amount is changed\n /// @param _targetBond The target bond amount\n event TargetBondChange(uint256 _targetBond);\n\n /// @notice Emitted when the Keep3r V2 address is changed\n /// @param _keep3rV2 The address of Keep3r V2\n event Keep3rV2Change(address _keep3rV2);\n\n /// @notice Emitted when the work extra gas amount is changed\n /// @param _workExtraGas The work extra gas\n event WorkExtraGasChange(uint256 _workExtraGas);\n\n /// @notice Emitted when the quote twap time is changed\n /// @param _quoteTwapTime The twap time for quoting\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\n\n /// @notice Emitted when minimum rewarded gas fee is changed\n /// @param _minBaseFee The minimum rewarded gas fee\n event MinBaseFeeChange(uint256 _minBaseFee);\n\n /// @notice Emitted when minimum rewarded priority fee is changed\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\n event MinPriorityFeeChange(uint256 _minPriorityFee);\n\n // Variables\n\n /// @notice Address of KP3R token\n /// @return _kp3r Address of KP3R token\n // solhint-disable func-name-mixedcase\n function KP3R() external view returns (address _kp3r);\n\n /// @notice The boost base used to calculate the boost rewards for the keeper\n /// @return _base The boost base number\n function BOOST_BASE() external view returns (uint256 _base);\n\n /// @notice KP3R-WETH pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\n /// @return _multiplier The minimum boost multiplier\n function minBoost() external view returns (uint256 _multiplier);\n\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\n /// @return _multiplier The maximum boost multiplier\n function maxBoost() external view returns (uint256 _multiplier);\n\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\n /// @return _target The amount of KP3R that comforms the targetBond\n function targetBond() external view returns (uint256 _target);\n\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\n /// @return _workExtraGas The work unaccounted gas amount\n function workExtraGas() external view returns (uint256 _workExtraGas);\n\n /// @notice The twap time for quoting\n /// @return _quoteTwapTime The twap time\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\n\n /// @notice The minimum base fee that is used to calculate keeper rewards\n /// @return _minBaseFee The minimum rewarded gas fee\n function minBaseFee() external view returns (uint256 _minBaseFee);\n\n /// @notice The minimum priority fee that is also rewarded for keepers\n /// @return _minPriorityFee The minimum rewarded priority fee\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\n\n /// @notice Address of Keep3r V2\n /// @return _keep3rV2 Address of Keep3r V2\n function keep3rV2() external view returns (address _keep3rV2);\n\n // Methods\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function setKp3rWethPool(address _poolAddress) external;\n\n /// @notice Sets the minimum boost multiplier\n /// @param _minBoost The minimum boost multiplier\n function setMinBoost(uint256 _minBoost) external;\n\n /// @notice Sets the maximum boost multiplier\n /// @param _maxBoost The maximum boost multiplier\n function setMaxBoost(uint256 _maxBoost) external;\n\n /// @notice Sets the target bond amount\n /// @param _targetBond The target bond amount\n function setTargetBond(uint256 _targetBond) external;\n\n /// @notice Sets the Keep3r V2 address\n /// @param _keep3rV2 The address of Keep3r V2\n function setKeep3rV2(address _keep3rV2) external;\n\n /// @notice Sets the work extra gas amount\n /// @param _workExtraGas The work extra gas\n function setWorkExtraGas(uint256 _workExtraGas) external;\n\n /// @notice Sets the quote twap time\n /// @param _quoteTwapTime The twap time for quoting\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\n\n /// @notice Sets the minimum rewarded gas fee\n /// @param _minBaseFee The minimum rewarded gas fee\n function setMinBaseFee(uint256 _minBaseFee) external;\n\n /// @notice Sets the minimum rewarded gas priority fee\n /// @param _minPriorityFee The minimum rewarded priority fee\n function setMinPriorityFee(uint256 _minPriorityFee) external;\n}\n" + }, + "solidity/interfaces/IPairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n/// @title Pair Manager interface\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\ninterface IPairManager is IERC20Metadata {\n /// @notice Address of the factory from which the pair manager was created\n /// @return _factory The address of the PairManager Factory\n function factory() external view returns (address _factory);\n\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\n /// @return _pool The address of the pool\n function pool() external view returns (address _pool);\n\n /// @notice Token0 of the pool\n /// @return _token0 The address of token0\n function token0() external view returns (address _token0);\n\n /// @notice Token1 of the pool\n /// @return _token1 The address of token1\n function token1() external view returns (address _token1);\n}\n" + }, + "solidity/contracts/libraries/FullMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (~denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "solidity/contracts/peripherals/Keep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rParameters.sol';\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\n\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\n /// @inheritdoc IKeep3rDisputable\n function dispute(address _jobOrKeeper) external override onlyDisputer {\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\n disputes[_jobOrKeeper] = true;\n emit Dispute(_jobOrKeeper, msg.sender);\n }\n\n /// @inheritdoc IKeep3rDisputable\n function resolve(address _jobOrKeeper) external override onlyDisputer {\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\n disputes[_jobOrKeeper] = false;\n emit Resolve(_jobOrKeeper, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rKeeperFundable.sol';\nimport '../Keep3rDisputable.sol';\nimport '../../../interfaces/external/IKeep3rV1.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\n }\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function revoke(address _keeper) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _keepers.remove(_keeper);\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\n emit KeeperRevoke(_keeper, msg.sender);\n }\n\n function _slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) internal {\n if (_bonded != keep3rV1) {\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\n }\n bonds[_keeper][_bonded] -= _bondAmount;\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nimport '../../../interfaces/external/IKeep3rV1.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperFundable\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\n if (disputes[msg.sender]) revert Disputed();\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\n\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\n\n hasBonded[msg.sender] = true;\n pendingBonds[msg.sender][_bonding] += _amount;\n\n emit Bonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function activate(address _bonding) external override {\n address _keeper = msg.sender;\n if (disputes[_keeper]) revert Disputed();\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\n if (_canActivateAfter == 0) revert BondsUnexistent();\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\n\n if (firstSeen[_keeper] == 0) {\n firstSeen[_keeper] = block.timestamp;\n }\n _keepers.add(_keeper);\n\n uint256 _amount = pendingBonds[_keeper][_bonding];\n delete pendingBonds[_keeper][_bonding];\n\n // bond provided tokens\n bonds[_keeper][_bonding] += _amount;\n if (_bonding == keep3rV1) {\n totalBonds += _amount;\n _depositBonds(_amount);\n }\n\n emit Activation(_keeper, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function unbond(address _bonding, uint256 _amount) external override {\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\n bonds[msg.sender][_bonding] -= _amount;\n pendingUnbonds[msg.sender][_bonding] += _amount;\n\n emit Unbonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function withdraw(address _bonding) external override nonReentrant {\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\n if (disputes[msg.sender]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\n\n delete pendingUnbonds[msg.sender][_bonding];\n delete canWithdrawAfter[msg.sender][_bonding];\n\n if (_bonding == keep3rV1) _mint(_amount);\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(msg.sender, _bonding, _amount);\n }\n\n function _depositBonds(uint256 _amount) internal virtual {\n IKeep3rV1(keep3rV1).burn(_amount);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n// solhint-disable func-name-mixedcase\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\n // Structs\n struct Checkpoint {\n uint32 fromBlock;\n uint256 votes;\n }\n\n // Events\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event JobAdded(address indexed _job, uint256 _block, address _governance);\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\n event KeeperDispute(address indexed _keeper, uint256 _block);\n event KeeperResolved(address indexed _keeper, uint256 _block);\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\n\n // Variables\n function KPRH() external returns (address);\n\n function delegates(address _delegator) external view returns (address);\n\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\n\n function numCheckpoints(address _account) external view returns (uint32);\n\n function DOMAIN_TYPEHASH() external returns (bytes32);\n\n function DOMAINSEPARATOR() external returns (bytes32);\n\n function DELEGATION_TYPEHASH() external returns (bytes32);\n\n function PERMIT_TYPEHASH() external returns (bytes32);\n\n function nonces(address _user) external view returns (uint256);\n\n function BOND() external returns (uint256);\n\n function UNBOND() external returns (uint256);\n\n function LIQUIDITYBOND() external returns (uint256);\n\n function FEE() external returns (uint256);\n\n function BASE() external returns (uint256);\n\n function ETH() external returns (address);\n\n function bondings(address _user, address _bonding) external view returns (uint256);\n\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\n\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function bonds(address _keeper, address _bonding) external view returns (uint256);\n\n function votes(address _delegator) external view returns (uint256);\n\n function firstSeen(address _keeper) external view returns (uint256);\n\n function disputes(address _keeper) external view returns (bool);\n\n function lastJob(address _keeper) external view returns (uint256);\n\n function workCompleted(address _keeper) external view returns (uint256);\n\n function jobs(address _job) external view returns (bool);\n\n function credits(address _job, address _credit) external view returns (uint256);\n\n function liquidityProvided(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmountsUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function jobProposalDelay(address _job) external view returns (uint256);\n\n function liquidityApplied(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmount(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function keepers(address _keeper) external view returns (bool);\n\n function blacklist(address _keeper) external view returns (bool);\n\n function keeperList(uint256 _index) external view returns (address);\n\n function jobList(uint256 _index) external view returns (address);\n\n function governance() external returns (address);\n\n function pendingGovernance() external returns (address);\n\n function liquidityAccepted(address _liquidity) external view returns (bool);\n\n function liquidityPairs(uint256 _index) external view returns (address);\n\n // Methods\n function getCurrentVotes(address _account) external view returns (uint256);\n\n function addCreditETH(address _job) external payable;\n\n function addCredit(\n address _credit,\n address _job,\n uint256 _amount\n ) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function pairs() external view returns (address[] memory);\n\n function addLiquidityToJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function applyCreditToJob(\n address _provider,\n address _liquidity,\n address _job\n ) external;\n\n function unbondLiquidityFromJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function removeLiquidityFromJob(address _liquidity, address _job) external;\n\n function mint(uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n\n function worked(address _keeper) external;\n\n function receipt(\n address _credit,\n address _keeper,\n uint256 _amount\n ) external;\n\n function receiptETH(address _keeper, uint256 _amount) external;\n\n function addJob(address _job) external;\n\n function getJobs() external view returns (address[] memory);\n\n function removeJob(address _job) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function isKeeper(address _keeper) external returns (bool);\n\n function isMinKeeper(\n address _keeper,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function bond(address _bonding, uint256 _amount) external;\n\n function getKeepers() external view returns (address[] memory);\n\n function activate(address _bonding) external;\n\n function unbond(address _bonding, uint256 _amount) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function withdraw(address _bonding) external;\n\n function dispute(address _keeper) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function permit(\n address _owner,\n address _spender,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3r.sol';\n\ncontract Keep3rForTestnet is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3r.sol';\n\ncontract Keep3rForTest is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3r.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\n\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @param _governance Address of governance\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\n constructor(\n address _governance, // governance\n address _keep3rHelperSidechain, // helper\n address _wrappedKP3R, // keep3rV1\n address _keep3rEscrow // keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\n\n // Keep3rSidechainAccountance\n\n /// @inheritdoc IKeep3rSidechainAccountance\n function virtualReserves() external view override returns (int256 _virtualReserves) {\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\n }\n\n // Keep3rJobFundableLiquidity\n\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\n /// @param _liquidity Address of the liquidity token being approved\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\n /// @param _liquidity Address of the liquidity token being observed\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n\n // Will always ask for 2 accumulators in sidechain\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Keep3rJobsWorkable\n\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\n function worked(address) external pure override {\n revert Deprecated();\n }\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Uses a USD per gas unit payment mechanism\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\n if (_initialGas == 0) revert GasNotInitialized();\n // Gas used for quote calculations & payment is not rewarded\n uint256 _gasLeft = _getGasLeft();\n\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\n\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _kp3rPayment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\n }\n\n // Keep3rKeeperFundable\n\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\n function _depositBonds(uint256 _amount) internal virtual override {\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\n }\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// solhint-disable-next-line no-empty-blocks\n\nimport '../peripherals/IMintable.sol';\n\n/// @title Keep3rEscrow contract\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\ninterface IKeep3rEscrow is IMintable {\n /// @notice Emitted when Keep3rEscrow#deposit function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _sender The address that called the function\n /// @param _amount The amount of wKP3R the user deposited\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#mint function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _recipient The address that will received the newly minted wKP3R\n /// @param _amount The amount of wKP3R minted to the recipient\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\n /// @param _newWKP3R The address of the wKP3R contract\n event wKP3RSet(address _newWKP3R);\n\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\n error InsufficientBalance();\n\n /// @notice Lists the address of the wKP3R contract\n /// @return _wKP3RAddress The address of wKP3R\n function wKP3R() external view returns (address _wKP3RAddress);\n\n /// @notice Deposits wKP3R into the contract\n /// @param _amount The amount of wKP3R to deposit\n function deposit(uint256 _amount) external;\n\n /// @notice mints wKP3R to the recipient\n /// @param _amount The amount of wKP3R to mint\n function mint(uint256 _amount) external;\n\n /// @notice sets the wKP3R address\n /// @param _wKP3R the wKP3R address\n function setWKP3R(address _wKP3R) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../IKeep3rHelper.sol';\n\n/// @title Keep3rHelperSidechain contract\n/// @notice Contains all the helper functions for sidechain keep3r implementations\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\n // Events\n\n /// @notice The oracle for a liquidity has been saved\n /// @param _liquidity The address of the given liquidity\n /// @param _oraclePool The address of the oracle pool\n event OracleSet(address _liquidity, address _oraclePool);\n\n /// @notice Emitted when the WETH USD pool is changed\n /// @param _address Address of the new WETH USD pool\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\n\n /// Variables\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n /// @return _weth Address of WETH token\n // solhint-disable func-name-mixedcase\n function WETH() external view returns (address _weth);\n\n /// @return _oracle The address of the observable pool for given liquidity\n function oracle(address _liquidity) external view returns (address _oracle);\n\n /// @notice WETH-USD pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice Quotes USD to ETH\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\n /// @param _usd The amount of USD to quote to ETH\n /// @return _eth The resulting amount of ETH after quoting the USD\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\n\n /// Methods\n\n /// @notice Sets an oracle for a given liquidity\n /// @param _liquidity The address of the liquidity\n /// @param _oracle The address of the pool used to quote the liquidity from\n /// @dev The oracle must contain KP3R as either token0 or token1\n function setOracle(address _liquidity, address _oracle) external;\n\n /// @notice Sets an oracle for querying WETH/USD quote\n /// @param _poolAddress The address of the pool used as oracle\n /// @dev The oracle must contain WETH as either token0 or token1\n function setWethUsdPool(address _poolAddress) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IKeep3rJobs.sol';\n\n/// @title Keep3rJobWorkableRated contract\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\n /// @notice Throws when job contract calls deprecated worked(address) function\n error Deprecated();\n\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title IKeep3rSidechainAccountance interface\n/// @notice Implements a view to get the amount of credits that can be withdrawn\ninterface IKeep3rSidechainAccountance {\n /// @notice The surplus amount of wKP3Rs in escrow contract\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\n function virtualReserves() external view returns (int256 _virtualReserves);\n}\n" + }, + "solidity/interfaces/peripherals/IMintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IGovernable.sol';\nimport './IBaseErrors.sol';\n\n/// @title Mintable contract\n/// @notice Manages the minter role\ninterface IMintable is IBaseErrors, IGovernable {\n // Events\n\n /// @notice Emitted when governance sets a new minter\n /// @param _minter Address of the new minter\n event MinterSet(address _minter);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not the minter\n error OnlyMinter();\n\n // Variables\n\n /// @notice Stores the minter address\n /// @return _minter The minter addresss\n function minter() external view returns (address _minter);\n\n // Methods\n\n /// @notice Sets a new address to be the minter\n /// @param _minter The address set as the minter\n function setMinter(address _minter) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rSidechainForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTest is Keep3rSidechain {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _governance,\n address _keep3rHelper,\n address _wrappedKP3R,\n address _keep3rEscrow\n ) Keep3rSidechain(_governance, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n}\n" + }, + "solidity/for-test/JobRatedForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\n\ncontract JobRatedForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n uint256 public usdPerGasUnit = 1_000e9;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n}\n" + }, + "solidity/for-test/JobForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract JobForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/for-test/BasicJob.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract BasicJob {\n error KeeperNotValid();\n\n address public keep3r;\n uint256 public nonce;\n uint256[] public array;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external upkeep {}\n\n function workHard(uint256 _howHard) external upkeep {\n for (uint256 i = nonce; i < _howHard; i++) {\n nonce++;\n }\n }\n\n function workRefund(uint256 _howHard) external upkeep {\n for (uint256 i; i < _howHard; i++) {\n array.push(i);\n }\n\n while (array.length > 0) {\n array.pop();\n }\n }\n\n modifier upkeep() {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\n _;\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/peripherals/IBaseErrors.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/external/IKeep3rV1.sol';\nimport '../interfaces/IKeep3rHelperParameters.sol';\nimport './peripherals/Governable.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\n /// @inheritdoc IKeep3rHelperParameters\n address public immutable override KP3R;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public constant override BOOST_BASE = 10_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBoost = 11_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override maxBoost = 12_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override targetBond = 200 ether;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override workExtraGas = 34_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint32 public override quoteTwapTime = 10 minutes;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBaseFee = 15e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minPriorityFee = 2e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n address public override keep3rV2;\n\n /// @inheritdoc IKeep3rHelperParameters\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Governable(_governance) {\n KP3R = _kp3r;\n keep3rV2 = _keep3rV2;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setKp3rWethPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\n minBoost = _minBoost;\n emit MinBoostChange(minBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\n maxBoost = _maxBoost;\n emit MaxBoostChange(maxBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\n targetBond = _targetBond;\n emit TargetBondChange(targetBond);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\n if (_keep3rV2 == address(0)) revert ZeroAddress();\n keep3rV2 = _keep3rV2;\n emit Keep3rV2Change(keep3rV2);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\n workExtraGas = _workExtraGas;\n emit WorkExtraGasChange(workExtraGas);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\n _setQuoteTwapTime(_quoteTwapTime);\n }\n\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\n quoteTwapTime = _quoteTwapTime;\n emit QuoteTwapTimeChange(quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\n minBaseFee = _minBaseFee;\n emit MinBaseFeeChange(minBaseFee);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\n minPriorityFee = _minPriorityFee;\n emit MinPriorityFeeChange(minPriorityFee);\n }\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function _setKp3rWethPool(address _poolAddress) internal {\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\n\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\n\n return TokenOraclePool(_poolAddress, _isTKNToken0);\n }\n}\n" + }, + "solidity/contracts/libraries/TickMath.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n// solhint-disable\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n // Second inequality must be < because the price can never reach the price at the max tick\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport './pool/IUniswapV3PoolImmutables.sol';\nimport './pool/IUniswapV3PoolState.sol';\nimport './pool/IUniswapV3PoolDerivedState.sol';\nimport './pool/IUniswapV3PoolActions.sol';\nimport './pool/IUniswapV3PoolOwnerActions.sol';\nimport './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolEvents\n{\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// observationIndex The index of the last oracle observation that was written,\n /// observationCardinality The current maximum number of observations stored in the pool,\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper,\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return _liquidity The amount of liquidity in the position,\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 _liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// Returns initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" + }, + "solidity/for-test/UniV3PairManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport '../contracts/libraries/LiquidityAmounts.sol';\nimport '../contracts/libraries/FixedPoint96.sol';\nimport '../contracts/libraries/FullMath.sol';\nimport '../contracts/libraries/TickMath.sol';\nimport '../contracts/UniV3PairManager.sol';\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManagerForTest is UniV3PairManager {\n constructor(address _pool, address _governance) UniV3PairManager(_pool, _governance) {}\n\n function internalAddLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n external\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n return _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n }\n\n function internalPay(\n address token,\n address payer,\n address recipient,\n uint256 value\n ) external {\n return _pay(token, payer, recipient, value);\n }\n\n function internalMint(address dst, uint256 amount) external {\n return _mint(dst, amount);\n }\n\n function internalBurn(address dst, uint256 amount) external {\n return _burn(dst, amount);\n }\n\n function internalTransferTokens(\n address src,\n address dst,\n uint256 amount\n ) external {\n _transferTokens(src, dst, amount);\n }\n\n function internalSafeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) external {\n _safeTransferFrom(token, from, to, value);\n }\n\n receive() external payable {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "solidity/contracts/libraries/LiquidityAmounts.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport './FullMath.sol';\nimport './FixedPoint96.sol';\n\n// solhint-disable\nlibrary LiquidityAmounts {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/contracts/libraries/FixedPoint96.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nlibrary FixedPoint96 {\n // solhint-disable\n uint8 internal constant RESOLUTION = 96;\n uint256 internal constant Q96 = 0x1000000000000000000000000;\n}\n" + }, + "solidity/contracts/UniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport './libraries/LiquidityAmounts.sol';\nimport './libraries/FixedPoint96.sol';\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\n\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\nimport './peripherals/Governable.sol';\n\ncontract UniV3PairManager is IUniV3PairManager, Governable {\n /// @inheritdoc IERC20Metadata\n string public override name;\n\n /// @inheritdoc IERC20Metadata\n string public override symbol;\n\n /// @inheritdoc IERC20\n uint256 public override totalSupply;\n\n /// @inheritdoc IPairManager\n address public immutable override factory;\n\n /// @inheritdoc IPairManager\n address public immutable override token0;\n\n /// @inheritdoc IPairManager\n address public immutable override token1;\n\n /// @inheritdoc IPairManager\n address public immutable override pool;\n\n /// @inheritdoc IUniV3PairManager\n uint24 public immutable override fee;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioAX96;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioBX96;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickLower;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickUpper;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickSpacing;\n\n /// @notice Uniswap's maximum tick\n /// @dev Due to tick spacing, pools with different fees may have differences between _MAX_TICK and tickUpper. Use tickUpper to find the max tick of the pool.\n int24 private constant _MAX_TICK = 887272;\n\n /// @inheritdoc IERC20Metadata\n //solhint-disable-next-line const-name-snakecase\n uint8 public constant override decimals = 18;\n\n /// @inheritdoc IERC20\n mapping(address => mapping(address => uint256)) public override allowance;\n\n /// @inheritdoc IERC20\n mapping(address => uint256) public override balanceOf;\n\n /// @notice Struct that contains token0, token1, and fee of the Uniswap pool\n PoolKey private _poolKey;\n\n constructor(address _pool, address _governance) Governable(_governance) {\n uint24 _fee = IUniswapV3Pool(_pool).fee();\n address _token0 = IUniswapV3Pool(_pool).token0();\n address _token1 = IUniswapV3Pool(_pool).token1();\n int24 _tickSpacing = IUniswapV3Pool(_pool).tickSpacing();\n int24 _tickUpper = _MAX_TICK - (_MAX_TICK % _tickSpacing);\n int24 _tickLower = -_tickUpper;\n\n factory = msg.sender;\n pool = _pool;\n fee = _fee;\n tickSpacing = _tickSpacing;\n tickUpper = _tickUpper;\n tickLower = _tickLower;\n token0 = _token0;\n token1 = _token1;\n name = string(abi.encodePacked('Keep3rLP - ', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n symbol = string(abi.encodePacked('kLP-', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n\n sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(_tickLower);\n sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(_tickUpper);\n _poolKey = PoolKey({token0: _token0, token1: _token1, fee: _fee});\n }\n\n // This low-level function should be called from a contract which performs important safety checks\n /// @inheritdoc IUniV3PairManager\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint128 liquidity) {\n (liquidity, , ) = _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n _mint(to, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external override {\n MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));\n if (msg.sender != pool) revert OnlyPool();\n if (amount0Owed > 0) _pay(decoded._poolKey.token0, decoded.payer, pool, amount0Owed);\n if (amount1Owed > 0) _pay(decoded._poolKey.token1, decoded.payer, pool, amount1Owed);\n }\n\n /// @inheritdoc IUniV3PairManager\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint256 amount0, uint256 amount1) {\n (amount0, amount1) = IUniswapV3Pool(pool).burn(tickLower, tickUpper, liquidity);\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n\n IUniswapV3Pool(pool).collect(to, tickLower, tickUpper, uint128(amount0), uint128(amount1));\n _burn(msg.sender, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function collect() external override onlyGovernance returns (uint256 amount0, uint256 amount1) {\n (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n (amount0, amount1) = IUniswapV3Pool(pool).collect(governance, tickLower, tickUpper, tokensOwed0, tokensOwed1);\n }\n\n /// @inheritdoc IUniV3PairManager\n function position()\n external\n view\n override\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n )\n {\n (liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128, tokensOwed0, tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n }\n\n /// @inheritdoc IERC20\n function approve(address spender, uint256 amount) external override returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transfer(address to, uint256 amount) external override returns (bool) {\n _transferTokens(msg.sender, to, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool) {\n address spender = msg.sender;\n uint256 spenderAllowance = allowance[from][spender];\n\n if (spender != from && spenderAllowance != type(uint256).max) {\n uint256 newAllowance = spenderAllowance - amount;\n allowance[from][spender] = newAllowance;\n\n emit Approval(from, spender, newAllowance);\n }\n\n _transferTokens(from, to, amount);\n return true;\n }\n\n /// @notice Adds liquidity to an initialized pool\n /// @dev Reverts if the returned amount0 is less than amount0Min or if amount1 is less than amount1Min\n /// @dev This function calls the mint function of the corresponding Uniswap pool, which in turn calls UniswapV3Callback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @return liquidity The calculated liquidity we get for the token amounts we provided\n /// @return amount0 The amount of token0 we ended up providing\n /// @return amount1 The amount of token1 we ended up providing\n function _addLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n internal\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(pool).slot0();\n\n liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, amount0Desired, amount1Desired);\n\n (amount0, amount1) = IUniswapV3Pool(pool).mint(\n address(this),\n tickLower,\n tickUpper,\n liquidity,\n abi.encode(MintCallbackData({_poolKey: _poolKey, payer: msg.sender}))\n );\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n }\n\n /// @notice Transfers the passed-in token from the payer to the recipient for the corresponding value\n /// @param token The token to be transferred to the recipient\n /// @param from The address of the payer\n /// @param to The address of the passed-in tokens recipient\n /// @param value How much of that token to be transferred from payer to the recipient\n function _pay(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n _safeTransferFrom(token, from, to, value);\n }\n\n /// @notice Mints Keep3r credits to the passed-in address of recipient and increases total supply of Keep3r credits by the corresponding amount\n /// @param to The recipient of the Keep3r credits\n /// @param amount The amount Keep3r credits to be minted to the recipient\n function _mint(address to, uint256 amount) internal {\n totalSupply += amount;\n balanceOf[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @notice Burns Keep3r credits to the passed-in address of recipient and reduces total supply of Keep3r credits by the corresponding amount\n /// @param to The address that will get its Keep3r credits burned\n /// @param amount The amount Keep3r credits to be burned from the recipient/recipient\n function _burn(address to, uint256 amount) internal {\n totalSupply -= amount;\n balanceOf[to] -= amount;\n emit Transfer(to, address(0), amount);\n }\n\n /// @notice Transfers amount of Keep3r credits between two addresses\n /// @param from The user that transfers the Keep3r credits\n /// @param to The user that receives the Keep3r credits\n /// @param amount The amount of Keep3r credits to be transferred\n function _transferTokens(\n address from,\n address to,\n uint256 amount\n ) internal {\n balanceOf[from] -= amount;\n balanceOf[to] += amount;\n\n emit Transfer(from, to, amount);\n }\n\n /// @notice Transfers the passed-in token from the specified \"from\" to the specified \"to\" for the corresponding value\n /// @dev Reverts with IUniV3PairManager#UnsuccessfulTransfer if the transfer was not successful,\n /// or if the passed data length is different than 0 and the decoded data is not a boolean\n /// @param token The token to be transferred to the specified \"to\"\n /// @param from The address which is going to transfer the tokens\n /// @param value How much of that token to be transferred from \"from\" to \"to\"\n function _safeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert UnsuccessfulTransfer();\n }\n}\n" + }, + "solidity/interfaces/external/IWeth9.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IWeth9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256) external;\n}\n" + }, + "solidity/interfaces/IUniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IPairManager.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\nimport './peripherals/IGovernable.sol';\n\n/// @title Pair Manager contract\n/// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner\n/// so that the user can use it as liquidity for a Keep3rJob\ninterface IUniV3PairManager is IGovernable, IPairManager {\n // Structs\n struct PoolKey {\n address token0;\n address token1;\n uint24 fee;\n }\n\n /// @notice The data to be decoded by the UniswapV3MintCallback function\n struct MintCallbackData {\n PoolKey _poolKey; // Struct that contains token0, token1, and fee of the pool passed into the constructor\n address payer; // The address of the payer, which will be the msg.sender of the mint function\n }\n\n // Variables\n\n /// @notice The fee of the Uniswap pool passed into the constructor\n /// @return _fee The fee of the Uniswap pool passed into the constructor\n function fee() external view returns (uint24 _fee);\n\n /// @notice Highest tick in the Uniswap's curve\n /// @return _tickUpper The highest tick in the Uniswap's curve\n function tickUpper() external view returns (int24 _tickUpper);\n\n /// @notice Lowest tick in the Uniswap's curve\n /// @return _tickLower The lower tick in the Uniswap's curve\n function tickLower() external view returns (int24 _tickLower);\n\n /// @notice The pair tick spacing\n /// @return _tickSpacing The pair tick spacing\n function tickSpacing() external view returns (int24 _tickSpacing);\n\n /// @notice The sqrtRatioAX96 at the lowest tick (-887200) of the Uniswap pool\n /// @return _sqrtPriceA96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the lowest tick\n function sqrtRatioAX96() external view returns (uint160 _sqrtPriceA96);\n\n /// @notice The sqrtRatioBX96 at the highest tick (887200) of the Uniswap pool\n /// @return _sqrtPriceBX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the highest tick\n function sqrtRatioBX96() external view returns (uint160 _sqrtPriceBX96);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the pool\n error OnlyPool();\n\n /// @notice Throws when the slippage exceeds what the user is comfortable with\n error ExcessiveSlippage();\n\n /// @notice Throws when a transfer is unsuccessful\n error UnsuccessfulTransfer();\n\n // Methods\n\n /// @notice This function is called after a user calls IUniV3PairManager#mint function\n /// It ensures that any tokens owed to the pool are paid by the msg.sender of IUniV3PairManager#mint function\n /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity\n /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity\n /// @param data The encoded token0, token1, fee (_poolKey) and the payer (msg.sender) of the IUniV3PairManager#mint function\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external;\n\n /// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool\n /// @dev Triggers UniV3PairManager#uniswapV3MintCallback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @param to The address to which the kLP tokens are going to be minted to\n /// @return liquidity kLP tokens sent in exchange for the provision of tokens\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint128 liquidity);\n\n /// @notice Returns the pair manager's position in the corresponding UniswapV3 pool\n /// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager\n /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position\n /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position\n /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation\n /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation\n function position()\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees\n // owed to a specific position to the recipient, in this case, that recipient is the pair manager\n /// @dev The collected fees will be sent to governance\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect() external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity\n // in the entire range\n /// @param liquidity The amount of liquidity to be burned\n /// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)\n /// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)\n /// @param to The address that will receive the due fees\n /// @return amount0 The calculated amount of token0 that will be sent to the recipient\n /// @return amount1 The calculated amount of token1 that will be sent to the recipient\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint256 amount0, uint256 amount1);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "solidity/interfaces/IPairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IGovernable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ninterface IPairManagerFactory is IGovernable {\n // Variables\n\n /// @notice Maps the address of a Uniswap pool, to the address of the corresponding PairManager\n /// For example, the uniswap address of DAI-WETH, will return the Keep3r/DAI-WETH pair manager address\n /// @param _pool The address of the Uniswap pool\n /// @return _pairManager The address of the corresponding pair manager\n function pairManagers(address _pool) external view returns (address _pairManager);\n\n // Events\n\n /// @notice Emitted when a new pair manager is created\n /// @param _pool The address of the corresponding Uniswap pool\n /// @param _pairManager The address of the just-created pair manager\n event PairCreated(address _pool, address _pairManager);\n\n // Errors\n\n /// @notice Throws an error if the pair manager is already initialized\n error AlreadyInitialized();\n\n /// @notice Throws an error if the caller is not the owner\n error OnlyOwner();\n\n // Methods\n\n /// @notice Creates a new pair manager based on the address of a Uniswap pool\n /// For example, the uniswap address of DAI-WETH, will create the Keep3r/DAI-WETH pool\n /// @param _pool The address of the Uniswap pool the pair manager will be based of\n /// @return _pairManager The address of the just-created pair manager\n function createPairManager(address _pool) external returns (address _pairManager);\n}\n" + }, + "solidity/contracts/UniV3PairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IPairManagerFactory.sol';\nimport './UniV3PairManager.sol';\nimport './peripherals/Governable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ncontract UniV3PairManagerFactory is IPairManagerFactory, Governable {\n mapping(address => address) public override pairManagers;\n\n constructor(address _governance) Governable(_governance) {}\n\n ///@inheritdoc IPairManagerFactory\n function createPairManager(address _pool) external override returns (address _pairManager) {\n if (pairManagers[_pool] != address(0)) revert AlreadyInitialized();\n _pairManager = address(new UniV3PairManager(_pool, governance));\n pairManagers[_pool] = _pairManager;\n emit PairCreated(_pool, _pairManager);\n }\n}\n" + }, + "solidity/for-test/peripherals/GovernableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" + }, + "solidity/for-test/BridgeForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ncontract BridgeForTest is ERC20 {\n address public immutable kp3r;\n\n constructor(address _kp3r) ERC20('Wrapped KP3R', 'wKP3R') {\n kp3r = _kp3r;\n }\n\n function bridge(uint256 _amount) external {\n IERC20(kp3r).transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n }\n\n function bridgeBack(uint256 _amount) external {\n _burn(msg.sender, _amount);\n IERC20(kp3r).transfer(msg.sender, _amount);\n }\n}\n" + }, + "solidity/for-test/ERC20ForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(uint256 _amount) public {\n _mint(msg.sender, _amount);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(uint256 _amount) public {\n _burn(msg.sender, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n function deposit() external payable {\n // Function added for compatibility with WETH\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperFundableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperFundable.sol';\n\ncontract Keep3rKeeperFundableForTest is Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function isKeeper(address _keeper) external view returns (bool) {\n return _keepers.contains(_keeper);\n }\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/Mintable.sol';\nimport '../peripherals/DustCollector.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rEscrow\n address public override wKP3R;\n\n /// @param _governance Address of governance\n /// @param _wKP3R Address of wrapped KP3R implementation\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\n wKP3R = _wKP3R;\n }\n\n /// @inheritdoc IKeep3rEscrow\n function deposit(uint256 _amount) external override {\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function mint(uint256 _amount) external override onlyMinter {\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function setWKP3R(address _wKP3R) external override onlyGovernance {\n if (_wKP3R == address(0)) revert ZeroAddress();\n wKP3R = _wKP3R;\n emit wKP3RSet(wKP3R);\n }\n}\n" + }, + "solidity/contracts/peripherals/Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IMintable.sol';\nimport './Governable.sol';\n\nabstract contract Mintable is Governable, IMintable {\n /// @inheritdoc IMintable\n address public override minter;\n\n constructor(address _governance) Governable(_governance) {}\n\n /// @inheritdoc IMintable\n function setMinter(address _minter) external override onlyGovernance {\n if (_minter == address(0)) revert ZeroAddress();\n minter = _minter;\n emit MinterSet(_minter);\n }\n\n /// @notice Functions with this modifier can only be called by the minter;\n modifier onlyMinter() {\n if (msg.sender != minter) revert OnlyMinter();\n _;\n }\n}\n" + }, + "solidity/for-test/peripherals/DustCollectorForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/DustCollector.sol';\n\ncontract DustCollectorForTest is DustCollector {\n constructor() DustCollector() Governable(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rAccountanceForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rAccountance.sol';\n\ncontract Keep3rAccountanceForTest is Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor() Keep3rRoles(msg.sender) {}\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n\n function setKeeper(address keeper) external {\n _keepers.add(keeper);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableLiquidityForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol';\n\ncontract Keep3rJobFundableLiquidityForTest is Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external returns (bool) {\n return _jobLiquidities[_job].add(_liquidity);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewTickOrder(address _liquidity) external view returns (bool) {\n return _isKP3RToken0[_liquidity];\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function internalSettleJobAccountance(address _job) external {\n _settleJobAccountance(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobDisputable.sol';\n\ncontract Keep3rJobDisputableForTest is Keep3rJobDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function internalJobLiquidityCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobLiquidityCredits[_job];\n }\n\n function internalJobPeriodCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobPeriodCredits[_job];\n }\n\n function internalJobTokens(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobTokens[_job].length());\n for (uint256 i; i < _jobTokens[_job].length(); i++) {\n _tokens[i] = _jobTokens[_job].at(i);\n }\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobLiquidities[_job].length());\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n _tokens[i] = _jobLiquidities[_job].at(i);\n }\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rDisputable.sol';\n\ncontract Keep3rDisputableForTest is Keep3rDisputable {\n constructor() Keep3rParameters(address(0), address(0), address(0)) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperDisputable.sol';\n\ncontract Keep3rKeeperDisputableForTest is Keep3rKeeperDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function internalSlash(\n address _bonded,\n address _keeper,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external {\n _slash(_bonded, _keeper, _bondAmount, _unbondAmount);\n }\n\n function isKeeper(address _address) external view returns (bool _isKeeper) {\n _isKeeper = _keepers.contains(_address);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableCreditsForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableCredits.sol';\n\ncontract Keep3rJobFundableCreditsForTest is Keep3rJobFundableCredits {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job, address _jobOwner) external {\n _jobs.add(_job);\n jobOwner[_job] = _jobOwner;\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function isJobToken(address _job, address _token) external view returns (bool _contains) {\n _contains = _jobTokens[_job].contains(_token);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/IKeep3rHelper.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n /// @inheritdoc IKeep3rHelper\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelper\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\n // solhint-disable-next-line avoid-tx-origin\n return getRewardAmountFor(tx.origin, _gasUsed);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\n _bonds = Math.min(_bonds, targetBond);\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\n _rewardBoost = _cap * _getBasefee();\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\n }\n\n /// @inheritdoc IKeep3rHelper\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\n address _token0;\n address _token1;\n (_token0, _token1) = getPoolTokens(_pool);\n if (_token0 == KP3R) {\n return true;\n } else if (_token1 != KP3R) {\n revert LiquidityPairInvalid();\n }\n }\n\n /// @inheritdoc IKeep3rHelper\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n override\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n )\n {\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\n _tickCumulative1 = _uniswapResponse[0];\n if (_uniswapResponse.length > 1) {\n _tickCumulative2 = _uniswapResponse[1];\n }\n _success = true;\n } catch (bytes memory) {}\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n )\n {\n _oneEthQuote = quote(1 ether);\n _boost = getRewardBoostFor(_bonds);\n _extra = workExtraGas;\n }\n\n /// @inheritdoc IKeep3rHelper\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure override returns (uint256 _kp3rAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) public pure override returns (uint256 _quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\n }\n }\n\n /// @notice Gets the gas basefee cost to calculate keeper rewards\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTestnet is Keep3rHelper {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal pure override returns (uint256) {\n return 1;\n }\n\n /// @dev Overrides oracle validation that uses KP3R and WETH addresses\n function _validateOraclePool(address _poolAddress, address) internal view virtual override returns (TokenOraclePool memory _oraclePool) {\n return TokenOraclePool(_poolAddress, true);\n }\n\n /// @dev Overrides token comparison with KP3R address\n function isKP3RToken0(address) public view virtual override returns (bool) {\n return true;\n }\n}\n" + }, + "solidity/for-test/Keep3rHelperForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTest is Keep3rHelper {\n uint256 public basefee;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal view override returns (uint256) {\n return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee();\n }\n\n function setBaseFee(uint256 _baseFee) external {\n basefee = _baseFee;\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rHelper.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\n /// @inheritdoc IKeep3rHelperSidechain\n mapping(address => address) public override oracle;\n /// @inheritdoc IKeep3rHelperSidechain\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n address public immutable override WETH;\n\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\n /// @param _governance Address of governance\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\n /// @dev Oracle pools should use 18 decimals tokens\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\n WETH = _weth;\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\n _setQuoteTwapTime(1 days);\n workExtraGas = 0;\n }\n\n /// @inheritdoc IKeep3rHelper\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\n oracle[_liquidity] = _oracle;\n emit OracleSet(_liquidity, _oracle);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n /// @dev Oracle is compatible with IUniswapV3Pool\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setWethUsdPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override(Keep3rHelper, IKeep3rHelper)\n returns (\n uint256 _boost,\n uint256 _oneUsdQuote,\n uint256 _extraGas\n )\n {\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\n _boost = getRewardBoostFor(_bonds);\n _extraGas = workExtraGas;\n }\n\n function _setWethUsdPool(address _poolAddress) internal {\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\n }\n\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechainForTestnet is Keep3rHelperSidechain {\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelperSidechain(_keep3rV2, _governance, _kp3r, _weth, _kp3rWethOracle, _wethUsdOracle) {}\n\n /// @dev Overrides oracle validation that uses KP3R and WETH addresses\n function _validateOraclePool(address _poolAddress, address) internal view virtual override returns (TokenOraclePool memory _oraclePool) {\n return TokenOraclePool(_poolAddress, true);\n }\n\n /// @dev Overrides token comparison with KP3R address\n function isKP3RToken0(address) public view virtual override returns (bool) {\n return true;\n }\n\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256) {\n return _usd / 1000;\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rParametersForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rParameters.sol';\n\ncontract Keep3rParametersForTest is Keep3rParameters {\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobWorkableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobWorkable.sol';\n\ncontract Keep3rJobWorkableForTest is Keep3rJobWorkable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewGas() external view returns (uint256) {\n return _initialGas;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobMigrationForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobMigration.sol';\n\ncontract Keep3rJobMigrationForTest is Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(address => uint256) public settleJobAccountanceCallCount;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobTokenListLength(address _job) external view returns (uint256) {\n return _jobTokens[_job].length();\n }\n\n function viewJobLiquidityList(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewMigrationCreatedAt(address _fromJob, address _toJob) external view returns (uint256) {\n return _migrationCreatedAt[_fromJob][_toJob];\n }\n\n function isJob(address _job) external view returns (bool) {\n return _jobs.contains(_job);\n }\n\n function _settleJobAccountance(address _job) internal override {\n settleJobAccountanceCallCount[_job]++;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobManager.sol';\n\ncontract Keep3rJobManagerForTest is Keep3rJobManager {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rRoles(msg.sender) {}\n\n function isJob(address _job) external view returns (bool _isJob) {\n _isJob = _jobs.contains(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobOwnershipForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobOwnership.sol';\n\ncontract Keep3rJobOwnershipForTest is Keep3rJobOwnership {}\n" + }, + "solidity/for-test/libraries/LiquidityAmountsForTest.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/libraries/FullMath.sol';\nimport '../../contracts/libraries/FixedPoint96.sol';\n\n/// @dev Made this library into a contract to be able to calculate liquidity more precisely for tests\n\n// solhint-disable\ncontract LiquidityAmountsForTest {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) external pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) external pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/for-test/IUniswapV3PoolForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n// solhint-disable-next-line no-empty-blocks\ninterface IUniswapV3PoolForTest is IERC20Minimal, IUniswapV3Pool {\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Minimal ERC20 interface for Uniswap\n/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3\ninterface IERC20Minimal {\n /// @notice Returns the balance of a token\n /// @param account The account for which to look up the number of tokens it has, i.e. its balance\n /// @return The number of tokens held by the account\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Transfers the amount of token from the `msg.sender` to the recipient\n /// @param recipient The account that will receive the amount transferred\n /// @param amount The number of tokens to send from the sender to the recipient\n /// @return Returns true for a successful transfer, false for an unsuccessful transfer\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /// @notice Returns the current allowance given to a spender by an owner\n /// @param owner The account of the token owner\n /// @param spender The account of the token spender\n /// @return The current allowance granted by `owner` to `spender`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`\n /// @param spender The account which will be allowed to spend a given amount of the owners tokens\n /// @param amount The amount of tokens allowed to be used by `spender`\n /// @return Returns true for a successful approval, false for unsuccessful\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`\n /// @param sender The account from which the transfer will be initiated\n /// @param recipient The recipient of the transfer\n /// @param amount The amount of the transfer\n /// @return Returns true for a successful transfer, false for unsuccessful\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.\n /// @param from The account from which the tokens were sent, i.e. the balance decreased\n /// @param to The account to which the tokens were sent, i.e. the balance increased\n /// @param value The amount of tokens that were transferred\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.\n /// @param owner The account that approved spending of its tokens\n /// @param spender The account for which the spending allowance was modified\n /// @param value The new allowance from the owner to the spender\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 33 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimisticEthereum/.chainId b/deployments/optimisticEthereum/.chainId new file mode 100644 index 0000000..9a03714 --- /dev/null +++ b/deployments/optimisticEthereum/.chainId @@ -0,0 +1 @@ +10 \ No newline at end of file diff --git a/deployments/optimisticEthereum/KP3Rv1.json b/deployments/optimisticEthereum/KP3Rv1.json new file mode 100644 index 0000000..638440c --- /dev/null +++ b/deployments/optimisticEthereum/KP3Rv1.json @@ -0,0 +1,189 @@ +{ + "address": "0x74bcb73fA7010EB523a81feE2bB23EaB3d12c2f8", + "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" + } + ], + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/optimisticEthereum/Keep3rEscrow.json b/deployments/optimisticEthereum/Keep3rEscrow.json new file mode 100644 index 0000000..9e1c7df --- /dev/null +++ b/deployments/optimisticEthereum/Keep3rEscrow.json @@ -0,0 +1,539 @@ +{ + "address": "0xDBc6501645407CF4D3af383FbD5Bf7586b135d81", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_governance", + "type": "address" + }, + { + "internalType": "address", + "name": "_wKP3R", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "NoGovernanceZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyGovernance", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyMinter", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingGovernance", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "DustSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_pendingGovernance", + "type": "address" + } + ], + "name": "GovernanceProposal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_governance", + "type": "address" + } + ], + "name": "GovernanceSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "MinterSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_wKP3R", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "wKP3RDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_wKP3R", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "wKP3RMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newWKP3R", + "type": "address" + } + ], + "name": "wKP3RSet", + "type": "event" + }, + { + "inputs": [], + "name": "acceptGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "governance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingGovernance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sendDust", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governance", + "type": "address" + } + ], + "name": "setGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_wKP3R", + "type": "address" + } + ], + "name": "setWKP3R", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "wKP3R", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x643cdd83070bedbd129bc9d1cdf807ae7d28c447d784bb9fa54d0ae26f227834", + "receipt": { + "to": null, + "from": "0xA825fc60eB4B1269F1dF0f6E574b953d2b5f7EFc", + "contractAddress": "0xDBc6501645407CF4D3af383FbD5Bf7586b135d81", + "transactionIndex": 0, + "gasUsed": "665788", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xf65ba7e8bcc2e52ea5691b65b2822dfd8e971136c16269c7989a4bad9c00a042", + "transactionHash": "0x643cdd83070bedbd129bc9d1cdf807ae7d28c447d784bb9fa54d0ae26f227834", + "logs": [], + "blockNumber": 46380652, + "cumulativeGasUsed": "665788", + "status": 1, + "byzantium": true + }, + "args": [ + "0x7d6daDb31dBeBc68c8A0b2cCfE5C1f26F24bD41d", + "0x74bcb73fA7010EB523a81feE2bB23EaB3d12c2f8" + ], + "numDeployments": 1, + "solcInputHash": "aa1ee30f4d8e78611039940e35c6db8b", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"DustSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_minter\",\"type\":\"address\"}],\"name\":\"MinterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"wKP3RDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"wKP3RMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newWKP3R\",\"type\":\"address\"}],\"name\":\"wKP3RSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sendDust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_minter\",\"type\":\"address\"}],\"name\":\"setMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"}],\"name\":\"setWKP3R\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wKP3R\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_governance\":\"Address of governance\",\"_wKP3R\":\"Address of wrapped KP3R implementation\"}},\"deposit(uint256)\":{\"params\":{\"_amount\":\"The amount of wKP3R to deposit\"}},\"mint(uint256)\":{\"params\":{\"_amount\":\"The amount of wKP3R to mint\"}},\"sendDust(address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of the token that will be transferred\",\"_to\":\"The address that will receive the idle funds\",\"_token\":\"The token that will be transferred\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setMinter(address)\":{\"params\":{\"_minter\":\"The address set as the minter\"}},\"setWKP3R(address)\":{\"params\":{\"_wKP3R\":\"the wKP3R address\"}}},\"stateVariables\":{\"wKP3R\":{\"return\":\"_wKP3RAddress The address of wKP3R\",\"returns\":{\"_0\":\"_wKP3RAddress The address of wKP3R\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InsufficientBalance()\":[{\"notice\":\"Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyMinter()\":[{\"notice\":\"Throws if the caller of the function is not the minter\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"DustSent(address,uint256,address)\":{\"notice\":\"Emitted when dust is sent\"},\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"MinterSet(address)\":{\"notice\":\"Emitted when governance sets a new minter\"},\"wKP3RDeposited(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rEscrow#deposit function is called\"},\"wKP3RMinted(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rEscrow#mint function is called\"},\"wKP3RSet(address)\":{\"notice\":\"Emitted when Keep3rEscrow#setWKP3R function is called\"}},\"kind\":\"user\",\"methods\":{\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"deposit(uint256)\":{\"notice\":\"Deposits wKP3R into the contract\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"mint(uint256)\":{\"notice\":\"mints wKP3R to the recipient\"},\"minter()\":{\"notice\":\"Stores the minter address\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"sendDust(address,uint256,address)\":{\"notice\":\"Allows an authorized user to transfer the tokens or eth that may have been left in a contract\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setMinter(address)\":{\"notice\":\"Sets a new address to be the minter\"},\"setWKP3R(address)\":{\"notice\":\"sets the wKP3R address\"},\"wKP3R()\":{\"notice\":\"Lists the address of the wKP3R contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/sidechain/Keep3rEscrow.sol\":\"Keep3rEscrow\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/DustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '../../contracts/peripherals/Governable.sol';\\nimport '../../interfaces/peripherals/IDustCollector.sol';\\n\\nabstract contract DustCollector is IDustCollector, Governable {\\n using SafeERC20 for IERC20;\\n\\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external override onlyGovernance {\\n if (_to == address(0)) revert ZeroAddress();\\n if (_token == _ETH_ADDRESS) {\\n payable(_to).transfer(_amount);\\n } else {\\n IERC20(_token).safeTransfer(_to, _amount);\\n }\\n emit DustSent(_token, _amount, _to);\\n }\\n}\\n\",\"keccak256\":\"0x246ac2c4057520bb627ea8040367549786f4477a04fd79358927cd607952bc2f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Mintable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IMintable.sol';\\nimport './Governable.sol';\\n\\nabstract contract Mintable is Governable, IMintable {\\n /// @inheritdoc IMintable\\n address public override minter;\\n\\n constructor(address _governance) Governable(_governance) {}\\n\\n /// @inheritdoc IMintable\\n function setMinter(address _minter) external override onlyGovernance {\\n if (_minter == address(0)) revert ZeroAddress();\\n minter = _minter;\\n emit MinterSet(_minter);\\n }\\n\\n /// @notice Functions with this modifier can only be called by the minter;\\n modifier onlyMinter() {\\n if (msg.sender != minter) revert OnlyMinter();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xc995899a6f8f32a0302fa017197b566012c2fefee9dc6fd2dac9d2674a5588f6\",\"license\":\"MIT\"},\"solidity/contracts/sidechain/Keep3rEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/Mintable.sol';\\nimport '../peripherals/DustCollector.sol';\\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rEscrow\\n address public override wKP3R;\\n\\n /// @param _governance Address of governance\\n /// @param _wKP3R Address of wrapped KP3R implementation\\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\\n wKP3R = _wKP3R;\\n }\\n\\n /// @inheritdoc IKeep3rEscrow\\n function deposit(uint256 _amount) external override {\\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rEscrow\\n function mint(uint256 _amount) external override onlyMinter {\\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rEscrow\\n function setWKP3R(address _wKP3R) external override onlyGovernance {\\n if (_wKP3R == address(0)) revert ZeroAddress();\\n wKP3R = _wKP3R;\\n emit wKP3RSet(wKP3R);\\n }\\n}\\n\",\"keccak256\":\"0x4ff5e6a73a0d479b9404d9df59031955541bb195647b0da46c979682843aeaac\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IMintable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IGovernable.sol';\\nimport './IBaseErrors.sol';\\n\\n/// @title Mintable contract\\n/// @notice Manages the minter role\\ninterface IMintable is IBaseErrors, IGovernable {\\n // Events\\n\\n /// @notice Emitted when governance sets a new minter\\n /// @param _minter Address of the new minter\\n event MinterSet(address _minter);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not the minter\\n error OnlyMinter();\\n\\n // Variables\\n\\n /// @notice Stores the minter address\\n /// @return _minter The minter addresss\\n function minter() external view returns (address _minter);\\n\\n // Methods\\n\\n /// @notice Sets a new address to be the minter\\n /// @param _minter The address set as the minter\\n function setMinter(address _minter) external;\\n}\\n\",\"keccak256\":\"0x255f4ed4b7c4ddf4fcff9db7524365ef734806583acca7c7912e867f110d9c81\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\nimport '../peripherals/IMintable.sol';\\n\\n/// @title Keep3rEscrow contract\\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\\ninterface IKeep3rEscrow is IMintable {\\n /// @notice Emitted when Keep3rEscrow#deposit function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _sender The address that called the function\\n /// @param _amount The amount of wKP3R the user deposited\\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#mint function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _recipient The address that will received the newly minted wKP3R\\n /// @param _amount The amount of wKP3R minted to the recipient\\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\\n /// @param _newWKP3R The address of the wKP3R contract\\n event wKP3RSet(address _newWKP3R);\\n\\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\\n error InsufficientBalance();\\n\\n /// @notice Lists the address of the wKP3R contract\\n /// @return _wKP3RAddress The address of wKP3R\\n function wKP3R() external view returns (address _wKP3RAddress);\\n\\n /// @notice Deposits wKP3R into the contract\\n /// @param _amount The amount of wKP3R to deposit\\n function deposit(uint256 _amount) external;\\n\\n /// @notice mints wKP3R to the recipient\\n /// @param _amount The amount of wKP3R to mint\\n function mint(uint256 _amount) external;\\n\\n /// @notice sets the wKP3R address\\n /// @param _wKP3R the wKP3R address\\n function setWKP3R(address _wKP3R) external;\\n}\\n\",\"keccak256\":\"0xf4796dde1afba7f50805aeae92ac0a4848525aeca8355d9b1c6b36c15cca4322\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610b20380380610b2083398101604081905261002f916100ab565b81806001600160a01b0381166100575760405162b293ed60e81b815260040160405180910390fd5b600080546001600160a01b039283166001600160a01b0319918216179091556003805494909216931692909217909155506100de9050565b80516001600160a01b03811681146100a657600080fd5b919050565b600080604083850312156100be57600080fd5b6100c78361008f565b91506100d56020840161008f565b90509250929050565b610a33806100ed6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063a0712d6811610071578063a0712d6814610120578063ab033ea914610133578063b509ec4514610146578063b6b55f2514610159578063f39c38a01461016c578063fca3b5aa1461017f57600080fd5b806307546172146100ae57806321316064146100dd578063238efcbc146100f25780635aa6e675146100fa578063966abd001461010d575b600080fd5b6002546100c1906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b6100f06100eb3660046108f0565b610192565b005b6100f0610239565b6000546100c1906001600160a01b031681565b6100f061011b36600461090b565b6102c2565b6100f061012e366004610969565b6103d8565b6100f06101413660046108f0565b610463565b6003546100c1906001600160a01b031681565b6100f0610167366004610969565b6104dc565b6001546100c1906001600160a01b031681565b6100f061018d3660046108f0565b61053d565b6000546001600160a01b031633146101bd576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166101e45760405163d92e233d60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f8592ade84fad7cc1c020f9783980e05e1be8bf3c0b6b557f3f5d5b48b5147647906020015b60405180910390a150565b6001546001600160a01b0316331461026457604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69060200160405180910390a1565b6000546001600160a01b031633146102ed576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166103145760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610375576040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561036f573d6000803e3d6000fd5b50610389565b6103896001600160a01b03841682846105dd565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6002546001600160a01b0316331461040357604051639cdc2ed560e01b815260040160405180910390fd5b60035461041a906001600160a01b031633836105dd565b600354604080516001600160a01b03909216825233602083015281018290527f5c5d429f40d64606e3af1c2373aa5f5b0846566f2bb3871dcccf094850ed4fc89060600161022e565b6000546001600160a01b0316331461048e576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f9060200161022e565b6003546104f4906001600160a01b0316333084610645565b600354604080516001600160a01b03909216825233602083015281018290527fb0c9218af42df0588074c7f30948dd6d1293a5ef42e7762e83d62c5daa7c9b849060600161022e565b6000546001600160a01b03163314610568576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661058f5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f726b590ef91a8c76ad05bbe91a57ef84605276528f49cd47d787f558a4e755b69060200161022e565b6040516001600160a01b03831660248201526044810182905261064090849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610683565b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261067d9085906323b872dd60e01b90608401610609565b50505050565b60006106d8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661075a9092919063ffffffff16565b80519091501561064057808060200190518101906106f69190610947565b6106405760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60606107698484600085610773565b90505b9392505050565b6060824710156107d45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610751565b843b6108225760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610751565b600080866001600160a01b0316858760405161083e9190610982565b60006040518083038185875af1925050503d806000811461087b576040519150601f19603f3d011682016040523d82523d6000602084013e610880565b606091505b509150915061089082828661089b565b979650505050505050565b606083156108aa57508161076c565b8251156108ba5782518084602001fd5b8160405162461bcd60e51b8152600401610751919061099e565b80356001600160a01b03811681146108eb57600080fd5b919050565b60006020828403121561090257600080fd5b61076c826108d4565b60008060006060848603121561092057600080fd5b610929846108d4565b92506020840135915061093e604085016108d4565b90509250925092565b60006020828403121561095957600080fd5b8151801515811461076c57600080fd5b60006020828403121561097b57600080fd5b5035919050565b600082516109948184602087016109d1565b9190910192915050565b60208152600082518060208401526109bd8160408501602087016109d1565b601f01601f19169190910160400192915050565b60005b838110156109ec5781810151838201526020016109d4565b8381111561067d575050600091015256fea2646970667358221220440d01c7061b90b70e2f708b93a96dfa66993b2443aa5c5a3a0267ce92aeadcb64736f6c63430008070033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a95760003560e01c8063a0712d6811610071578063a0712d6814610120578063ab033ea914610133578063b509ec4514610146578063b6b55f2514610159578063f39c38a01461016c578063fca3b5aa1461017f57600080fd5b806307546172146100ae57806321316064146100dd578063238efcbc146100f25780635aa6e675146100fa578063966abd001461010d575b600080fd5b6002546100c1906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b6100f06100eb3660046108f0565b610192565b005b6100f0610239565b6000546100c1906001600160a01b031681565b6100f061011b36600461090b565b6102c2565b6100f061012e366004610969565b6103d8565b6100f06101413660046108f0565b610463565b6003546100c1906001600160a01b031681565b6100f0610167366004610969565b6104dc565b6001546100c1906001600160a01b031681565b6100f061018d3660046108f0565b61053d565b6000546001600160a01b031633146101bd576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166101e45760405163d92e233d60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f8592ade84fad7cc1c020f9783980e05e1be8bf3c0b6b557f3f5d5b48b5147647906020015b60405180910390a150565b6001546001600160a01b0316331461026457604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69060200160405180910390a1565b6000546001600160a01b031633146102ed576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166103145760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610375576040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561036f573d6000803e3d6000fd5b50610389565b6103896001600160a01b03841682846105dd565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6002546001600160a01b0316331461040357604051639cdc2ed560e01b815260040160405180910390fd5b60035461041a906001600160a01b031633836105dd565b600354604080516001600160a01b03909216825233602083015281018290527f5c5d429f40d64606e3af1c2373aa5f5b0846566f2bb3871dcccf094850ed4fc89060600161022e565b6000546001600160a01b0316331461048e576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f9060200161022e565b6003546104f4906001600160a01b0316333084610645565b600354604080516001600160a01b03909216825233602083015281018290527fb0c9218af42df0588074c7f30948dd6d1293a5ef42e7762e83d62c5daa7c9b849060600161022e565b6000546001600160a01b03163314610568576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661058f5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f726b590ef91a8c76ad05bbe91a57ef84605276528f49cd47d787f558a4e755b69060200161022e565b6040516001600160a01b03831660248201526044810182905261064090849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610683565b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261067d9085906323b872dd60e01b90608401610609565b50505050565b60006106d8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661075a9092919063ffffffff16565b80519091501561064057808060200190518101906106f69190610947565b6106405760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60606107698484600085610773565b90505b9392505050565b6060824710156107d45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610751565b843b6108225760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610751565b600080866001600160a01b0316858760405161083e9190610982565b60006040518083038185875af1925050503d806000811461087b576040519150601f19603f3d011682016040523d82523d6000602084013e610880565b606091505b509150915061089082828661089b565b979650505050505050565b606083156108aa57508161076c565b8251156108ba5782518084602001fd5b8160405162461bcd60e51b8152600401610751919061099e565b80356001600160a01b03811681146108eb57600080fd5b919050565b60006020828403121561090257600080fd5b61076c826108d4565b60008060006060848603121561092057600080fd5b610929846108d4565b92506020840135915061093e604085016108d4565b90509250925092565b60006020828403121561095957600080fd5b8151801515811461076c57600080fd5b60006020828403121561097b57600080fd5b5035919050565b600082516109948184602087016109d1565b9190910192915050565b60208152600082518060208401526109bd8160408501602087016109d1565b601f01601f19169190910160400192915050565b60005b838110156109ec5781810151838201526020016109d4565b8381111561067d575050600091015256fea2646970667358221220440d01c7061b90b70e2f708b93a96dfa66993b2443aa5c5a3a0267ce92aeadcb64736f6c63430008070033", + "devdoc": { + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_governance": "Address of governance", + "_wKP3R": "Address of wrapped KP3R implementation" + } + }, + "deposit(uint256)": { + "params": { + "_amount": "The amount of wKP3R to deposit" + } + }, + "mint(uint256)": { + "params": { + "_amount": "The amount of wKP3R to mint" + } + }, + "sendDust(address,uint256,address)": { + "params": { + "_amount": "The amount of the token that will be transferred", + "_to": "The address that will receive the idle funds", + "_token": "The token that will be transferred" + } + }, + "setGovernance(address)": { + "params": { + "_governance": "The address being proposed as the new governance" + } + }, + "setMinter(address)": { + "params": { + "_minter": "The address set as the minter" + } + }, + "setWKP3R(address)": { + "params": { + "_wKP3R": "the wKP3R address" + } + } + }, + "stateVariables": { + "wKP3R": { + "return": "_wKP3RAddress The address of wKP3R", + "returns": { + "_0": "_wKP3RAddress The address of wKP3R" + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "InsufficientBalance()": [ + { + "notice": "Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance" + } + ], + "NoGovernanceZeroAddress()": [ + { + "notice": "Throws if trying to set governance to zero address" + } + ], + "OnlyGovernance()": [ + { + "notice": "Throws if the caller of the function is not governance" + } + ], + "OnlyMinter()": [ + { + "notice": "Throws if the caller of the function is not the minter" + } + ], + "OnlyPendingGovernance()": [ + { + "notice": "Throws if the caller of the function is not pendingGovernance" + } + ], + "ZeroAddress()": [ + { + "notice": "Throws if a variable is assigned to the zero address" + } + ] + }, + "events": { + "DustSent(address,uint256,address)": { + "notice": "Emitted when dust is sent" + }, + "GovernanceProposal(address)": { + "notice": "Emitted when a new governance is proposed" + }, + "GovernanceSet(address)": { + "notice": "Emitted when pendingGovernance accepts to be governance" + }, + "MinterSet(address)": { + "notice": "Emitted when governance sets a new minter" + }, + "wKP3RDeposited(address,address,uint256)": { + "notice": "Emitted when Keep3rEscrow#deposit function is called" + }, + "wKP3RMinted(address,address,uint256)": { + "notice": "Emitted when Keep3rEscrow#mint function is called" + }, + "wKP3RSet(address)": { + "notice": "Emitted when Keep3rEscrow#setWKP3R function is called" + } + }, + "kind": "user", + "methods": { + "acceptGovernance()": { + "notice": "Changes the governance from the current governance to the previously proposed address" + }, + "deposit(uint256)": { + "notice": "Deposits wKP3R into the contract" + }, + "governance()": { + "notice": "Stores the governance address" + }, + "mint(uint256)": { + "notice": "mints wKP3R to the recipient" + }, + "minter()": { + "notice": "Stores the minter address" + }, + "pendingGovernance()": { + "notice": "Stores the pendingGovernance address" + }, + "sendDust(address,uint256,address)": { + "notice": "Allows an authorized user to transfer the tokens or eth that may have been left in a contract" + }, + "setGovernance(address)": { + "notice": "Proposes a new address to be governance" + }, + "setMinter(address)": { + "notice": "Sets a new address to be the minter" + }, + "setWKP3R(address)": { + "notice": "sets the wKP3R address" + }, + "wKP3R()": { + "notice": "Lists the address of the wKP3R contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 5362, + "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", + "label": "governance", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 5366, + "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", + "label": "pendingGovernance", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 6185, + "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", + "label": "minter", + "offset": 0, + "slot": "2", + "type": "t_address" + }, + { + "astId": 9638, + "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", + "label": "wKP3R", + "offset": 0, + "slot": "3", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimisticEthereum/Keep3rHelperSidechain.json b/deployments/optimisticEthereum/Keep3rHelperSidechain.json new file mode 100644 index 0000000..aba7f8e --- /dev/null +++ b/deployments/optimisticEthereum/Keep3rHelperSidechain.json @@ -0,0 +1,1548 @@ +{ + "address": "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rV2", + "type": "address" + }, + { + "internalType": "address", + "name": "_governance", + "type": "address" + }, + { + "internalType": "address", + "name": "_kp3r", + "type": "address" + }, + { + "internalType": "address", + "name": "_weth", + "type": "address" + }, + { + "internalType": "address", + "name": "_kp3rWethOracle", + "type": "address" + }, + { + "internalType": "address", + "name": "_wethUsdOracle", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidOraclePool", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidityPairInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "NoGovernanceZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyGovernance", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingGovernance", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_pendingGovernance", + "type": "address" + } + ], + "name": "GovernanceProposal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_governance", + "type": "address" + } + ], + "name": "GovernanceSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_keep3rV2", + "type": "address" + } + ], + "name": "Keep3rV2Change", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_isKP3RToken0", + "type": "bool" + } + ], + "name": "Kp3rWethPoolChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_maxBoost", + "type": "uint256" + } + ], + "name": "MaxBoostChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_minBaseFee", + "type": "uint256" + } + ], + "name": "MinBaseFeeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_minBoost", + "type": "uint256" + } + ], + "name": "MinBoostChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_minPriorityFee", + "type": "uint256" + } + ], + "name": "MinPriorityFeeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_oraclePool", + "type": "address" + } + ], + "name": "OracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "_quoteTwapTime", + "type": "uint32" + } + ], + "name": "QuoteTwapTimeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_targetBond", + "type": "uint256" + } + ], + "name": "TargetBondChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_isWETHToken0", + "type": "bool" + } + ], + "name": "WethUSDPoolChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_workExtraGas", + "type": "uint256" + } + ], + "name": "WorkExtraGasChange", + "type": "event" + }, + { + "inputs": [], + "name": "BOOST_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "KP3R", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + } + ], + "name": "bonds", + "outputs": [ + { + "internalType": "uint256", + "name": "_amountBonded", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_liquidityAmount", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "_tickDifference", + "type": "int56" + }, + { + "internalType": "uint256", + "name": "_timeInterval", + "type": "uint256" + } + ], + "name": "getKP3RsAtTick", + "outputs": [ + { + "internalType": "uint256", + "name": "_kp3rAmount", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bonds", + "type": "uint256" + } + ], + "name": "getPaymentParams", + "outputs": [ + { + "internalType": "uint256", + "name": "_boost", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_oneUsdQuote", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_extraGas", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "getPoolTokens", + "outputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "_baseAmount", + "type": "uint128" + }, + { + "internalType": "int56", + "name": "_tickDifference", + "type": "int56" + }, + { + "internalType": "uint256", + "name": "_timeInterval", + "type": "uint256" + } + ], + "name": "getQuoteAtTick", + "outputs": [ + { + "internalType": "uint256", + "name": "_quoteAmount", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_gasUsed", + "type": "uint256" + } + ], + "name": "getRewardAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_gasUsed", + "type": "uint256" + } + ], + "name": "getRewardAmountFor", + "outputs": [ + { + "internalType": "uint256", + "name": "_kp3r", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bonds", + "type": "uint256" + } + ], + "name": "getRewardBoostFor", + "outputs": [ + { + "internalType": "uint256", + "name": "_rewardBoost", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "isKP3RToken0", + "outputs": [ + { + "internalType": "bool", + "name": "_isKP3RToken0", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keep3rV2", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "kp3rWethPool", + "outputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isTKNToken0", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxBoost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minBaseFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minBoost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minPriorityFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "uint32[]", + "name": "_secondsAgo", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56", + "name": "_tickCumulative1", + "type": "int56" + }, + { + "internalType": "int56", + "name": "_tickCumulative2", + "type": "int56" + }, + { + "internalType": "bool", + "name": "_success", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "oracle", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingGovernance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eth", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "_amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "quoteTwapTime", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_usd", + "type": "uint256" + } + ], + "name": "quoteUsdToEth", + "outputs": [ + { + "internalType": "uint256", + "name": "_amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governance", + "type": "address" + } + ], + "name": "setGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rV2", + "type": "address" + } + ], + "name": "setKeep3rV2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolAddress", + "type": "address" + } + ], + "name": "setKp3rWethPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxBoost", + "type": "uint256" + } + ], + "name": "setMaxBoost", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minBaseFee", + "type": "uint256" + } + ], + "name": "setMinBaseFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minBoost", + "type": "uint256" + } + ], + "name": "setMinBoost", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minPriorityFee", + "type": "uint256" + } + ], + "name": "setMinPriorityFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "address", + "name": "_oracle", + "type": "address" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_quoteTwapTime", + "type": "uint32" + } + ], + "name": "setQuoteTwapTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_targetBond", + "type": "uint256" + } + ], + "name": "setTargetBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolAddress", + "type": "address" + } + ], + "name": "setWethUsdPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_workExtraGas", + "type": "uint256" + } + ], + "name": "setWorkExtraGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "targetBond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wethUSDPool", + "outputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isTKNToken0", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "workExtraGas", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xbc42302955086d877f21d80a176b48f565778fe114c809e98c1aaa1727f3d936", + "receipt": { + "to": null, + "from": "0xA825fc60eB4B1269F1dF0f6E574b953d2b5f7EFc", + "contractAddress": "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "transactionIndex": 0, + "gasUsed": "2178151", + "logsBloom": "0x00000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000100000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000008000000000000000000", + "blockHash": "0xecc1690014ebb297cceeee0638aa9844377250d90e8a84fbd4c9da3557a17909", + "transactionHash": "0xbc42302955086d877f21d80a176b48f565778fe114c809e98c1aaa1727f3d936", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 46380664, + "transactionHash": "0xbc42302955086d877f21d80a176b48f565778fe114c809e98c1aaa1727f3d936", + "address": "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "topics": [ + "0x554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf4108" + ], + "data": "0x0000000000000000000000004ab2c969c64302e5d931e5cef4755392dc0056040000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 0, + "blockHash": "0xecc1690014ebb297cceeee0638aa9844377250d90e8a84fbd4c9da3557a17909" + }, + { + "transactionIndex": 0, + "blockNumber": 46380664, + "transactionHash": "0xbc42302955086d877f21d80a176b48f565778fe114c809e98c1aaa1727f3d936", + "address": "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "topics": [ + "0xc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000015180", + "logIndex": 1, + "blockHash": "0xecc1690014ebb297cceeee0638aa9844377250d90e8a84fbd4c9da3557a17909" + } + ], + "blockNumber": 46380664, + "cumulativeGasUsed": "2178151", + "status": 1, + "byzantium": true + }, + "args": [ + "0x745a50320B6eB8FF281f1664Fc6713991661B129", + "0x7d6daDb31dBeBc68c8A0b2cCfE5C1f26F24bD41d", + "0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44", + "0x4200000000000000000000000000000000000006", + "0x4Ab2c969C64302e5d931e5cEf4755392DC005604", + "0x03aF20bDAaFfB4cC0A521796a223f7D85e2aAc31" + ], + "numDeployments": 1, + "solcInputHash": "aa1ee30f4d8e78611039940e35c6db8b", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kp3r\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kp3rWethOracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_wethUsdOracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidOraclePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"Keep3rV2Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isKP3RToken0\",\"type\":\"bool\"}],\"name\":\"Kp3rWethPoolChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"MaxBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"MinBaseFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"MinBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"MinPriorityFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_oraclePool\",\"type\":\"address\"}],\"name\":\"OracleSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"QuoteTwapTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"TargetBondChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isWETHToken0\",\"type\":\"bool\"}],\"name\":\"WethUSDPoolChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"WorkExtraGasChange\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BOOST_BASE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"KP3R\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WETH\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountBonded\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityAmount\",\"type\":\"uint256\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getKP3RsAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3rAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getPaymentParams\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_boost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_oneUsdQuote\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_extraGas\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"}],\"name\":\"getPoolTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token1\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_baseAmount\",\"type\":\"uint128\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getQuoteAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_quoteAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmountFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3r\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getRewardBoostFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardBoost\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"}],\"name\":\"isKP3RToken0\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isKP3RToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV2\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"kp3rWethPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isTKNToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBaseFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minPriorityFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"},{\"internalType\":\"uint32[]\",\"name\":\"_secondsAgo\",\"type\":\"uint32[]\"}],\"name\":\"observe\",\"outputs\":[{\"internalType\":\"int56\",\"name\":\"_tickCumulative1\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"_tickCumulative2\",\"type\":\"int56\"},{\"internalType\":\"bool\",\"name\":\"_success\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eth\",\"type\":\"uint256\"}],\"name\":\"quote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"quoteTwapTime\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_usd\",\"type\":\"uint256\"}],\"name\":\"quoteUsdToEth\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"setKeep3rV2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddress\",\"type\":\"address\"}],\"name\":\"setKp3rWethPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"setMaxBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"setMinBaseFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"setMinBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"setMinPriorityFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"}],\"name\":\"setOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"setQuoteTwapTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"setTargetBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddress\",\"type\":\"address\"}],\"name\":\"setWethUsdPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"setWorkExtraGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetBond\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wethUSDPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isTKNToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"workExtraGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bonds(address)\":{\"params\":{\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_amountBonded\":\"The amount of KP3R the keeper has bonded\"}},\"constructor\":{\"details\":\"Oracle pools should use 18 decimals tokens\",\"params\":{\"_governance\":\"Address of governance\",\"_keep3rV2\":\"Address of sidechain Keep3r implementation\",\"_kp3rWethOracle\":\"Address of oracle used for KP3R/WETH quote\",\"_wethUsdOracle\":\"Address of oracle used for WETH/USD quote\"}},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"params\":{\"_liquidityAmount\":\"Amount of liquidity to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_kp3rAmount\":\"Amount of KP3R tokens underlying on the given liquidity\"}},\"getPaymentParams(uint256)\":{\"params\":{\"_bonds\":\"Amount of bonded KP3R owned by the keeper\"},\"returns\":{\"_boost\":\"Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\",\"_extraGas\":\"Amount of extra gas that should be added to the gas spent\",\"_oneUsdQuote\":\"Amount of KP3R tokens equivalent to 1 ETH\"}},\"getPoolTokens(address)\":{\"params\":{\"_pool\":\"Address of the correspondant pool\"},\"returns\":{\"_token0\":\"Address of the first token of the pair\",\"_token1\":\"Address of the second token of the pair\"}},\"getQuoteAtTick(uint128,int56,uint256)\":{\"params\":{\"_baseAmount\":\"Amount of token to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_quoteAmount\":\"Amount of credits deserved for the baseAmount at the tick value\"}},\"getRewardAmount(uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\"},\"returns\":{\"_amount\":\"The amount of KP3R that should be awarded to tx.origin\"}},\"getRewardAmountFor(address,uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\",\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_kp3r\":\"The amount of KP3R that should be awarded to the keeper\"}},\"getRewardBoostFor(uint256)\":{\"details\":\"If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\",\"params\":{\"_bonds\":\"The amount of KP3R tokens bonded by the keeper\"},\"returns\":{\"_rewardBoost\":\"The reward boost that corresponds to the keeper\"}},\"isKP3RToken0(address)\":{\"params\":{\"_pool\":\"Address of the correspondant pool\"},\"returns\":{\"_isKP3RToken0\":\"Boolean indicating the order of the tokens in the pair\"}},\"observe(address,uint32[])\":{\"params\":{\"_pool\":\"Address of the pool to observe\",\"_secondsAgo\":\"Array with time references to observe\"},\"returns\":{\"_success\":\"Boolean indicating if the observe call was succesfull\",\"_tickCumulative1\":\"Cumulative sum of ticks until first time reference\",\"_tickCumulative2\":\"Cumulative sum of ticks until second time reference\"}},\"quote(uint256)\":{\"details\":\"This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\",\"params\":{\"_eth\":\"The amount of ETH\"},\"returns\":{\"_amountOut\":\"The amount of KP3R\"}},\"quoteUsdToEth(uint256)\":{\"details\":\"Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\",\"params\":{\"_usd\":\"The amount of USD to quote to ETH\"},\"returns\":{\"_amountOut\":\"The resulting amount of ETH after quoting the USD\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setKeep3rV2(address)\":{\"params\":{\"_keep3rV2\":\"The address of Keep3r V2\"}},\"setKp3rWethPool(address)\":{\"params\":{\"_poolAddress\":\"The address of the KP3R-WETH pool\"}},\"setMaxBoost(uint256)\":{\"params\":{\"_maxBoost\":\"The maximum boost multiplier\"}},\"setMinBaseFee(uint256)\":{\"params\":{\"_minBaseFee\":\"The minimum rewarded gas fee\"}},\"setMinBoost(uint256)\":{\"params\":{\"_minBoost\":\"The minimum boost multiplier\"}},\"setMinPriorityFee(uint256)\":{\"params\":{\"_minPriorityFee\":\"The minimum rewarded priority fee\"}},\"setOracle(address,address)\":{\"details\":\"The oracle must contain KP3R as either token0 or token1\",\"params\":{\"_liquidity\":\"The address of the liquidity\",\"_oracle\":\"The address of the pool used to quote the liquidity from\"}},\"setQuoteTwapTime(uint32)\":{\"params\":{\"_quoteTwapTime\":\"The twap time for quoting\"}},\"setTargetBond(uint256)\":{\"params\":{\"_targetBond\":\"The target bond amount\"}},\"setWethUsdPool(address)\":{\"details\":\"The oracle must contain WETH as either token0 or token1\",\"params\":{\"_poolAddress\":\"The address of the pool used as oracle\"}},\"setWorkExtraGas(uint256)\":{\"params\":{\"_workExtraGas\":\"The work extra gas\"}}},\"stateVariables\":{\"oracle\":{\"return\":\"_oracle The address of the observable pool for given liquidity\",\"returns\":{\"_0\":\"_oracle The address of the observable pool for given liquidity\"}},\"wethUSDPool\":{\"returns\":{\"isTKNToken0\":\"True if calling the token0 method of the pool returns the WETH token address\",\"poolAddress\":\"Address of the pool\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidOraclePool()\":[{\"notice\":\"Throws when pool does not have KP3R as token0 nor token1\"}],\"LiquidityPairInvalid()\":[{\"notice\":\"Throws when none of the tokens in the liquidity pair is KP3R\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"Keep3rV2Change(address)\":{\"notice\":\"Emitted when the Keep3r V2 address is changed\"},\"Kp3rWethPoolChange(address,bool)\":{\"notice\":\"Emitted when the kp3r weth pool is changed\"},\"MaxBoostChange(uint256)\":{\"notice\":\"Emitted when the maximum boost multiplier is changed\"},\"MinBaseFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded gas fee is changed\"},\"MinBoostChange(uint256)\":{\"notice\":\"Emitted when the minimum boost multiplier is changed\"},\"MinPriorityFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded priority fee is changed\"},\"OracleSet(address,address)\":{\"notice\":\"The oracle for a liquidity has been saved\"},\"QuoteTwapTimeChange(uint32)\":{\"notice\":\"Emitted when the quote twap time is changed\"},\"TargetBondChange(uint256)\":{\"notice\":\"Emitted when the target bond amount is changed\"},\"WethUSDPoolChange(address,bool)\":{\"notice\":\"Emitted when the WETH USD pool is changed\"},\"WorkExtraGasChange(uint256)\":{\"notice\":\"Emitted when the work extra gas amount is changed\"}},\"kind\":\"user\",\"methods\":{\"BOOST_BASE()\":{\"notice\":\"The boost base used to calculate the boost rewards for the keeper\"},\"KP3R()\":{\"notice\":\"Address of KP3R token\"},\"WETH()\":{\"notice\":\"Ethereum mainnet WETH address used for quoting references\"},\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"bonds(address)\":{\"notice\":\"Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\"},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"notice\":\"Given a tick and a liquidity amount, calculates the underlying KP3R tokens\"},\"getPaymentParams(uint256)\":{\"notice\":\"Get multiplier, quote, and extra, in order to calculate keeper payment\"},\"getPoolTokens(address)\":{\"notice\":\"Given a pool address, returns the underlying tokens of the pair\"},\"getQuoteAtTick(uint128,int56,uint256)\":{\"notice\":\"Given a tick and a token amount, calculates the output in correspondant token\"},\"getRewardAmount(uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\"},\"getRewardAmountFor(address,uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to a keeper for using gas\"},\"getRewardBoostFor(uint256)\":{\"notice\":\"Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"isKP3RToken0(address)\":{\"notice\":\"Defines the order of the tokens in the pair for twap calculations\"},\"keep3rV2()\":{\"notice\":\"Address of Keep3r V2\"},\"kp3rWethPool()\":{\"notice\":\"KP3R-WETH pool that is being used as oracle\"},\"maxBoost()\":{\"notice\":\"The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\"},\"minBaseFee()\":{\"notice\":\"The minimum base fee that is used to calculate keeper rewards\"},\"minBoost()\":{\"notice\":\"The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\"},\"minPriorityFee()\":{\"notice\":\"The minimum priority fee that is also rewarded for keepers\"},\"observe(address,uint32[])\":{\"notice\":\"Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"quote(uint256)\":{\"notice\":\"Calculates the amount of KP3R that corresponds to the ETH passed into the function\"},\"quoteTwapTime()\":{\"notice\":\"The twap time for quoting\"},\"quoteUsdToEth(uint256)\":{\"notice\":\"Quotes USD to ETH\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setKeep3rV2(address)\":{\"notice\":\"Sets the Keep3r V2 address\"},\"setKp3rWethPool(address)\":{\"notice\":\"Sets KP3R-WETH pool\"},\"setMaxBoost(uint256)\":{\"notice\":\"Sets the maximum boost multiplier\"},\"setMinBaseFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas fee\"},\"setMinBoost(uint256)\":{\"notice\":\"Sets the minimum boost multiplier\"},\"setMinPriorityFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas priority fee\"},\"setOracle(address,address)\":{\"notice\":\"Sets an oracle for a given liquidity\"},\"setQuoteTwapTime(uint32)\":{\"notice\":\"Sets the quote twap time\"},\"setTargetBond(uint256)\":{\"notice\":\"Sets the target bond amount\"},\"setWethUsdPool(address)\":{\"notice\":\"Sets an oracle for querying WETH/USD quote\"},\"setWorkExtraGas(uint256)\":{\"notice\":\"Sets the work extra gas amount\"},\"targetBond()\":{\"notice\":\"The targeted amount of bonded KP3Rs to max-up reward multiplier For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\"},\"wethUSDPool()\":{\"notice\":\"WETH-USD pool that is being used as oracle\"},\"workExtraGas()\":{\"notice\":\"The amount of unaccounted gas that is going to be added to keeper payments\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/sidechain/Keep3rHelperSidechain.sol\":\"Keep3rHelperSidechain\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\nimport './pool/IUniswapV3PoolImmutables.sol';\\nimport './pool/IUniswapV3PoolState.sol';\\nimport './pool/IUniswapV3PoolDerivedState.sol';\\nimport './pool/IUniswapV3PoolActions.sol';\\nimport './pool/IUniswapV3PoolOwnerActions.sol';\\nimport './pool/IUniswapV3PoolEvents.sol';\\n\\n/// @title The interface for a Uniswap V3 Pool\\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\\n/// to the ERC20 specification\\n/// @dev The pool interface is broken up into many smaller pieces\\ninterface IUniswapV3Pool is\\n IUniswapV3PoolImmutables,\\n IUniswapV3PoolState,\\n IUniswapV3PoolDerivedState,\\n IUniswapV3PoolActions,\\n IUniswapV3PoolOwnerActions,\\n IUniswapV3PoolEvents\\n{\\n\\n}\\n\",\"keccak256\":\"0xfe6113d518466cd6652c85b111e01f33eb62157f49ae5ed7d5a3947a2044adb1\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissionless pool actions\\n/// @notice Contains pool methods that can be called by anyone\\ninterface IUniswapV3PoolActions {\\n /// @notice Sets the initial price for the pool\\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\\n function initialize(uint160 sqrtPriceX96) external;\\n\\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\\n /// @param recipient The address for which the liquidity will be created\\n /// @param tickLower The lower tick of the position in which to add liquidity\\n /// @param tickUpper The upper tick of the position in which to add liquidity\\n /// @param amount The amount of liquidity to mint\\n /// @param data Any data that should be passed through to the callback\\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n function mint(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount,\\n bytes calldata data\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Collects tokens owed to a position\\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\\n /// @param recipient The address which should receive the fees collected\\n /// @param tickLower The lower tick of the position for which to collect fees\\n /// @param tickUpper The upper tick of the position for which to collect fees\\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\\n /// @return amount0 The amount of fees collected in token0\\n /// @return amount1 The amount of fees collected in token1\\n function collect(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n\\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\\n /// @dev Fees must be collected separately via a call to #collect\\n /// @param tickLower The lower tick of the position for which to burn liquidity\\n /// @param tickUpper The upper tick of the position for which to burn liquidity\\n /// @param amount How much liquidity to burn\\n /// @return amount0 The amount of token0 sent to the recipient\\n /// @return amount1 The amount of token1 sent to the recipient\\n function burn(\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Swap token0 for token1, or token1 for token0\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\\n /// @param recipient The address to receive the output of the swap\\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\\n /// @param data Any data to be passed through to the callback\\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\\n /// @param recipient The address which will receive the token0 and token1 amounts\\n /// @param amount0 The amount of token0 to send\\n /// @param amount1 The amount of token1 to send\\n /// @param data Any data to be passed through to the callback\\n function flash(\\n address recipient,\\n uint256 amount0,\\n uint256 amount1,\\n bytes calldata data\\n ) external;\\n\\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\\n /// the input observationCardinalityNext.\\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0x9453dd0e7442188667d01d9b65de3f1e14e9511ff3e303179a15f6fc267f7634\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that is not stored\\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\\n/// blockchain. The functions here may have variable gas costs.\\ninterface IUniswapV3PoolDerivedState {\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\\n /// you must call it with secondsAgos = [3600, 0].\\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\\n /// timestamp\\n function observe(uint32[] calldata secondsAgos)\\n external\\n view\\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\\n\\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\\n /// snapshot is taken and the second snapshot is taken.\\n /// @param tickLower The lower tick of the range\\n /// @param tickUpper The upper tick of the range\\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\\n /// @return secondsInside The snapshot of seconds per liquidity for the range\\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\\n external\\n view\\n returns (\\n int56 tickCumulativeInside,\\n uint160 secondsPerLiquidityInsideX128,\\n uint32 secondsInside\\n );\\n}\\n\",\"keccak256\":\"0xe603ac5b17ecdee73ba2b27efdf386c257a19c14206e87eee77e2017b742d9e5\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Events emitted by a pool\\n/// @notice Contains all events emitted by the pool\\ninterface IUniswapV3PoolEvents {\\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\\n event Initialize(uint160 sqrtPriceX96, int24 tick);\\n\\n /// @notice Emitted when liquidity is minted for a given position\\n /// @param sender The address that minted the liquidity\\n /// @param owner The owner of the position and recipient of any minted liquidity\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity minted to the position range\\n /// @param amount0 How much token0 was required for the minted liquidity\\n /// @param amount1 How much token1 was required for the minted liquidity\\n event Mint(\\n address sender,\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted when fees are collected by the owner of a position\\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\\n /// @param owner The owner of the position for which fees are collected\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount0 The amount of token0 fees collected\\n /// @param amount1 The amount of token1 fees collected\\n event Collect(\\n address indexed owner,\\n address recipient,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount0,\\n uint128 amount1\\n );\\n\\n /// @notice Emitted when a position's liquidity is removed\\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\\n /// @param owner The owner of the position for which liquidity is removed\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity to remove\\n /// @param amount0 The amount of token0 withdrawn\\n /// @param amount1 The amount of token1 withdrawn\\n event Burn(\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted by the pool for any swaps between token0 and token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the output of the swap\\n /// @param amount0 The delta of the token0 balance of the pool\\n /// @param amount1 The delta of the token1 balance of the pool\\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param liquidity The liquidity of the pool after the swap\\n /// @param tick The log base 1.0001 of price of the pool after the swap\\n event Swap(\\n address indexed sender,\\n address indexed recipient,\\n int256 amount0,\\n int256 amount1,\\n uint160 sqrtPriceX96,\\n uint128 liquidity,\\n int24 tick\\n );\\n\\n /// @notice Emitted by the pool for any flashes of token0/token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the tokens from flash\\n /// @param amount0 The amount of token0 that was flashed\\n /// @param amount1 The amount of token1 that was flashed\\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\\n event Flash(\\n address indexed sender,\\n address indexed recipient,\\n uint256 amount0,\\n uint256 amount1,\\n uint256 paid0,\\n uint256 paid1\\n );\\n\\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\\n /// just before a mint/swap/burn.\\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(\\n uint16 observationCardinalityNextOld,\\n uint16 observationCardinalityNextNew\\n );\\n\\n /// @notice Emitted when the protocol fee is changed by the pool\\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\\n /// @param feeProtocol0New The updated value of the token0 protocol fee\\n /// @param feeProtocol1New The updated value of the token1 protocol fee\\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\\n\\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\\n /// @param sender The address that collects the protocol fees\\n /// @param recipient The address that receives the collected protocol fees\\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x8071514d0fe5d17d6fbd31c191cdfb703031c24e0ece3621d88ab10e871375cd\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that never changes\\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\\ninterface IUniswapV3PoolImmutables {\\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\\n /// @return The contract address\\n function factory() external view returns (address);\\n\\n /// @notice The first of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token0() external view returns (address);\\n\\n /// @notice The second of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token1() external view returns (address);\\n\\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\\n /// @return The fee\\n function fee() external view returns (uint24);\\n\\n /// @notice The pool tick spacing\\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\\n /// This value is an int24 to avoid casting even though it is always positive.\\n /// @return The tick spacing\\n function tickSpacing() external view returns (int24);\\n\\n /// @notice The maximum amount of position liquidity that can use any tick in the range\\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\\n /// @return The max amount of liquidity per tick\\n function maxLiquidityPerTick() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xf6e5d2cd1139c4c276bdbc8e1d2b256e456c866a91f1b868da265c6d2685c3f7\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissioned pool actions\\n/// @notice Contains pool methods that may only be called by the factory owner\\ninterface IUniswapV3PoolOwnerActions {\\n /// @notice Set the denominator of the protocol's % share of the fees\\n /// @param feeProtocol0 new protocol fee for token0 of the pool\\n /// @param feeProtocol1 new protocol fee for token1 of the pool\\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\\n\\n /// @notice Collect the protocol fee accrued to the pool\\n /// @param recipient The address to which collected protocol fees should be sent\\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\\n /// @return amount0 The protocol fee collected in token0\\n /// @return amount1 The protocol fee collected in token1\\n function collectProtocol(\\n address recipient,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x759b78a2918af9e99e246dc3af084f654e48ef32bb4e4cb8a966aa3dcaece235\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that can change\\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\\n/// per transaction\\ninterface IUniswapV3PoolState {\\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\\n /// when accessed externally.\\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\\n /// boundary.\\n /// observationIndex The index of the last oracle observation that was written,\\n /// observationCardinality The current maximum number of observations stored in the pool,\\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// feeProtocol The protocol fee for both tokens of the pool.\\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\\n /// unlocked Whether the pool is currently locked to reentrancy\\n function slot0()\\n external\\n view\\n returns (\\n uint160 sqrtPriceX96,\\n int24 tick,\\n uint16 observationIndex,\\n uint16 observationCardinality,\\n uint16 observationCardinalityNext,\\n uint8 feeProtocol,\\n bool unlocked\\n );\\n\\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal0X128() external view returns (uint256);\\n\\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal1X128() external view returns (uint256);\\n\\n /// @notice The amounts of token0 and token1 that are owed to the protocol\\n /// @dev Protocol fees will never exceed uint128 max in either token\\n function protocolFees() external view returns (uint128 token0, uint128 token1);\\n\\n /// @notice The currently in range liquidity available to the pool\\n /// @dev This value has no relationship to the total liquidity across all ticks\\n function liquidity() external view returns (uint128);\\n\\n /// @notice Look up information about a specific tick in the pool\\n /// @param tick The tick to look up\\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\\n /// tick upper,\\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\\n /// a specific position.\\n function ticks(int24 tick)\\n external\\n view\\n returns (\\n uint128 liquidityGross,\\n int128 liquidityNet,\\n uint256 feeGrowthOutside0X128,\\n uint256 feeGrowthOutside1X128,\\n int56 tickCumulativeOutside,\\n uint160 secondsPerLiquidityOutsideX128,\\n uint32 secondsOutside,\\n bool initialized\\n );\\n\\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\\n function tickBitmap(int16 wordPosition) external view returns (uint256);\\n\\n /// @notice Returns the information about a position by the position's key\\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\\n /// @return _liquidity The amount of liquidity in the position,\\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\\n function positions(bytes32 key)\\n external\\n view\\n returns (\\n uint128 _liquidity,\\n uint256 feeGrowthInside0LastX128,\\n uint256 feeGrowthInside1LastX128,\\n uint128 tokensOwed0,\\n uint128 tokensOwed1\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param index The element of the observations array to fetch\\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\\n /// ago, rather than at a specific index in the array.\\n /// @return blockTimestamp The timestamp of the observation,\\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// Returns initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 index)\\n external\\n view\\n returns (\\n uint32 blockTimestamp,\\n int56 tickCumulative,\\n uint160 secondsPerLiquidityCumulativeX128,\\n bool initialized\\n );\\n}\\n\",\"keccak256\":\"0x852dc1f5df7dcf7f11e7bb3eed79f0cea72ad4b25f6a9d2c35aafb48925fd49f\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/Keep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2003\\u2003\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2003\\u2003\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/IKeep3rHelper.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\\n\\n /// @inheritdoc IKeep3rHelper\\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\\n uint32[] memory _secondsAgos = new uint32[](2);\\n _secondsAgos[1] = quoteTwapTime;\\n\\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\\n // solhint-disable-next-line avoid-tx-origin\\n return getRewardAmountFor(tx.origin, _gasUsed);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\\n _bonds = Math.min(_bonds, targetBond);\\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\\n _rewardBoost = _cap * _getBasefee();\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\\n address _token0;\\n address _token1;\\n (_token0, _token1) = getPoolTokens(_pool);\\n if (_token0 == KP3R) {\\n return true;\\n } else if (_token1 != KP3R) {\\n revert LiquidityPairInvalid();\\n }\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n override\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n )\\n {\\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\\n _tickCumulative1 = _uniswapResponse[0];\\n if (_uniswapResponse.length > 1) {\\n _tickCumulative2 = _uniswapResponse[1];\\n }\\n _success = true;\\n } catch (bytes memory) {}\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n virtual\\n override\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n )\\n {\\n _oneEthQuote = quote(1 ether);\\n _boost = getRewardBoostFor(_bonds);\\n _extra = workExtraGas;\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure override returns (uint256 _kp3rAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) public pure override returns (uint256 _quoteAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n\\n if (sqrtRatioX96 <= type(uint128).max) {\\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\\n } else {\\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\\n }\\n }\\n\\n /// @notice Gets the gas basefee cost to calculate keeper rewards\\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\\n }\\n}\\n\",\"keccak256\":\"0x022987525462636329608fd3032553a123451854d6191d863f068de237302d17\",\"license\":\"MIT\"},\"solidity/contracts/Keep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/peripherals/IBaseErrors.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/external/IKeep3rV1.sol';\\nimport '../interfaces/IKeep3rHelperParameters.sol';\\nimport './peripherals/Governable.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\\n /// @inheritdoc IKeep3rHelperParameters\\n address public immutable override KP3R;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public constant override BOOST_BASE = 10_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBoost = 11_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override maxBoost = 12_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override targetBond = 200 ether;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override workExtraGas = 34_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint32 public override quoteTwapTime = 10 minutes;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBaseFee = 15e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minPriorityFee = 2e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n address public override keep3rV2;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\\n\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Governable(_governance) {\\n KP3R = _kp3r;\\n keep3rV2 = _keep3rV2;\\n\\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\\n if (_poolAddress == address(0)) revert ZeroAddress();\\n _setKp3rWethPool(_poolAddress);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\\n minBoost = _minBoost;\\n emit MinBoostChange(minBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\\n maxBoost = _maxBoost;\\n emit MaxBoostChange(maxBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\\n targetBond = _targetBond;\\n emit TargetBondChange(targetBond);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\\n if (_keep3rV2 == address(0)) revert ZeroAddress();\\n keep3rV2 = _keep3rV2;\\n emit Keep3rV2Change(keep3rV2);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\\n workExtraGas = _workExtraGas;\\n emit WorkExtraGasChange(workExtraGas);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\\n _setQuoteTwapTime(_quoteTwapTime);\\n }\\n\\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\\n quoteTwapTime = _quoteTwapTime;\\n emit QuoteTwapTimeChange(quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\\n minBaseFee = _minBaseFee;\\n emit MinBaseFeeChange(minBaseFee);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\\n minPriorityFee = _minPriorityFee;\\n emit MinPriorityFeeChange(minPriorityFee);\\n }\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function _setKp3rWethPool(address _poolAddress) internal {\\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\\n }\\n\\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\\n\\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\\n\\n return TokenOraclePool(_poolAddress, _isTKNToken0);\\n }\\n}\\n\",\"keccak256\":\"0xff1d1cdd8acec9bed3ac67c0980c1e211e6e09483e30a090c05ed4698a5c0dd4\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n// solhint-disable\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\\n\\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n // Second inequality must be < because the price can never reach the price at the max tick\\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n}\\n\",\"keccak256\":\"0x11b965ba576ff91b4a6e9533c0f334f2b7b6024ee1c54e36d21799de5580899d\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/contracts/sidechain/Keep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3rHelper.sol';\\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\\n\\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\\n /// @inheritdoc IKeep3rHelperSidechain\\n mapping(address => address) public override oracle;\\n /// @inheritdoc IKeep3rHelperSidechain\\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n address public immutable override WETH;\\n\\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\\n /// @param _governance Address of governance\\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\\n /// @dev Oracle pools should use 18 decimals tokens\\n constructor(\\n address _keep3rV2,\\n address _governance,\\n address _kp3r,\\n address _weth,\\n address _kp3rWethOracle,\\n address _wethUsdOracle\\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\\n WETH = _weth;\\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\\n _setQuoteTwapTime(1 days);\\n workExtraGas = 0;\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\\n oracle[_liquidity] = _oracle;\\n emit OracleSet(_liquidity, _oracle);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\\n uint32[] memory _secondsAgos = new uint32[](2);\\n _secondsAgos[1] = quoteTwapTime;\\n\\n /// @dev Oracle is compatible with IUniswapV3Pool\\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\\n if (_poolAddress == address(0)) revert ZeroAddress();\\n _setWethUsdPool(_poolAddress);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n virtual\\n override(Keep3rHelper, IKeep3rHelper)\\n returns (\\n uint256 _boost,\\n uint256 _oneUsdQuote,\\n uint256 _extraGas\\n )\\n {\\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\\n _boost = getRewardBoostFor(_bonds);\\n _extraGas = workExtraGas;\\n }\\n\\n function _setWethUsdPool(address _poolAddress) internal {\\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\\n }\\n\\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\\n return 1;\\n }\\n}\\n\",\"keccak256\":\"0x8f5dca78861e4112fce04e55d2231d7dbf5d7938e70bdf0248cc06eab1f39401\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct TokenOraclePool {\\n address poolAddress;\\n bool isTKNToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0x76f99ca04361c0459fc9e99f0387ddb76da18cc470ec5bc744e7dc3bf6e9d334\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0xf4748c236ddf409e45e7169c735e2fc54e627b2b3ccd189ebb438ad768f1deb1\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../IKeep3rHelper.sol';\\n\\n/// @title Keep3rHelperSidechain contract\\n/// @notice Contains all the helper functions for sidechain keep3r implementations\\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\\n // Events\\n\\n /// @notice The oracle for a liquidity has been saved\\n /// @param _liquidity The address of the given liquidity\\n /// @param _oraclePool The address of the oracle pool\\n event OracleSet(address _liquidity, address _oraclePool);\\n\\n /// @notice Emitted when the WETH USD pool is changed\\n /// @param _address Address of the new WETH USD pool\\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\\n\\n /// Variables\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n /// @return _weth Address of WETH token\\n // solhint-disable func-name-mixedcase\\n function WETH() external view returns (address _weth);\\n\\n /// @return _oracle The address of the observable pool for given liquidity\\n function oracle(address _liquidity) external view returns (address _oracle);\\n\\n /// @notice WETH-USD pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice Quotes USD to ETH\\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\\n /// @param _usd The amount of USD to quote to ETH\\n /// @return _eth The resulting amount of ETH after quoting the USD\\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\\n\\n /// Methods\\n\\n /// @notice Sets an oracle for a given liquidity\\n /// @param _liquidity The address of the liquidity\\n /// @param _oracle The address of the pool used to quote the liquidity from\\n /// @dev The oracle must contain KP3R as either token0 or token1\\n function setOracle(address _liquidity, address _oracle) external;\\n\\n /// @notice Sets an oracle for querying WETH/USD quote\\n /// @param _poolAddress The address of the pool used as oracle\\n /// @dev The oracle must contain WETH as either token0 or token1\\n function setWethUsdPool(address _poolAddress) external;\\n}\\n\",\"keccak256\":\"0xb6d5459e8a47ab09a052e1acac1c28304f9f0762d20f01819559b4d39729c987\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60c0604052612af8600255612ee0600355680ad78ebc5ac62000006004556184d06005556006805463ffffffff191661025817905564037e11d60060075563773594006008553480156200005257600080fd5b5060405162002690380380620026908339810160408190526200007591620003f1565b8386868483838383816001600160a01b038116620000a55760405162b293ed60e81b815260040160405180910390fd5b600080546001600160a01b03199081166001600160a01b0393841617909155606086901b6001600160601b03191660805260098054909116918516919091179055620000f28185620001e7565b8051600a80546020938401511515600160a01b9081026001600160a81b03199092166001600160a01b03948516179190911791829055604080519383168452910460ff161515928201929092527f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf4108910160405180910390a15050505050606086901b6001600160601b03191660a0525062000192915082905084620001e7565b8051600c80546020909301511515600160a01b026001600160a81b03199093166001600160a01b0390921691909117919091179055620001d56201518062000361565b50506000600555506200047292505050565b60408051808201909152600080825260208201526000826001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156200024157600080fd5b505afa15801562000256573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200027c9190620003cc565b6001600160a01b03161490508015816200031c5750826001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015620002d557600080fd5b505afa158015620002ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003109190620003cc565b6001600160a01b031614155b156200033b5760405163db60809d60e01b815260040160405180910390fd5b604080518082019091526001600160a01b03851681529015156020820152905092915050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de9060200160405180910390a150565b80516001600160a01b0381168114620003c757600080fd5b919050565b600060208284031215620003df57600080fd5b620003ea82620003af565b9392505050565b60008060008060008060c087890312156200040b57600080fd5b6200041687620003af565b95506200042660208801620003af565b94506200043660408801620003af565b93506200044660608801620003af565b92506200045660808801620003af565b91506200046660a08801620003af565b90509295509295509295565b60805160601c60a05160601c6121d6620004ba600039600081816104e801526119ba01526000818161025d01528181610bf001528181610c3401526113f601526121d66000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c80637b40c91311610146578063b2e0df96116100c3578063e244208b11610087578063e244208b146105ae578063eb37d349146105c1578063ed1bd76c146105ea578063f39c38a0146105fd578063fae63d6114610610578063fe10d7741461062357600080fd5b8063b2e0df961461050a578063b93f5af01461051d578063c84993af14610530578063ca4f280314610543578063dc686d911461057657600080fd5b8063a62611a21161010a578063a62611a2146104a1578063ab033ea9146104aa578063ab5dce00146104bd578063ab8cedc5146104d0578063ad5c4648146104e357600080fd5b80637b40c913146104385780638561579c146104575780638a9b1b09146104605780639aaad67914610469578063a0d271071461048e57600080fd5b806337090c2f116101d4578063516c332311610198578063516c3323146103c95780635aa6e675146103dc5780635c38eb3a146103ef578063607e48d414610402578063696a437b1461041557600080fd5b806337090c2f146103635780633b67c3bd1461036c5780633cc7ab301461037f5780633facf24214610392578063435b21c11461039b57600080fd5b8063238efcbc1161021b578063238efcbc146102f857806325f09e61146103005780632742b9e7146103095780632750c0f914610312578063289adb441461035057600080fd5b806305e0b9a0146102585780630c5258351461029c578063117cfc1b146102b1578063160e1e31146102c45780632248e82d146102d7575b600080fd5b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6102af6102aa366004611ec3565b610636565b005b60095461027f906001600160a01b031681565b6102af6102d2366004611c57565b61069d565b6102ea6102e5366004611d7e565b6106fb565b604051908152602001610293565b6102af61072e565b6102ea61271081565b6102ea60045481565b600c54610331906001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b039093168352901515602083015201610293565b6102af61035e366004611ec3565b6107b7565b6102ea60035481565b6102ea61037a366004611ec3565b610817565b6102af61038d366004611c57565b61097b565b6102ea60055481565b6103ae6103a9366004611ec3565b610a1b565b60408051938452602084019290925290820152606001610293565b6102ea6103d7366004611ec3565b610a4c565b60005461027f906001600160a01b031681565b6102af6103fd366004611c91565b610aa7565b6102af610410366004611ec3565b610b78565b610428610423366004611c57565b610bd8565b6040519015158152602001610293565b600a54610331906001600160a01b03811690600160a01b900460ff1682565b6102ea60025481565b6102ea60085481565b6006546104799063ffffffff1681565b60405163ffffffff9091168152602001610293565b6102ea61049c366004611ef5565b610c8b565b6102ea60075481565b6102af6104b8366004611c57565b610cbe565b6102af6104cb366004611ec3565b610d37565b6102ea6104de366004611e76565b610d97565b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6102af610518366004611ec3565b610e40565b6102af61052b366004611f1c565b610ea0565b6102ea61053e366004611ec3565b610ed4565b610556610551366004611c57565b610ee6565b604080516001600160a01b03938416815292909116602083015201610293565b610589610584366004611cca565b610fd4565b60408051600694850b81529290930b6020830152151591810191909152606001610293565b6102af6105bc366004611ec3565b6110df565b61027f6105cf366004611c57565b600b602052600090815260409020546001600160a01b031681565b6102ea6105f8366004611ec3565b61113f565b60015461027f906001600160a01b031681565b6102af61061e366004611c57565b611285565b6102ea610631366004611c57565b6112e0565b6000546001600160a01b03163314610661576040516354348f0360e01b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b031633146106c8576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166106ef5760405163d92e233d60e01b815260040160405180910390fd5b6106f8816113f0565b50565b60008061070a6103d7856112e0565b905061072661271061071c8386612030565b6105f8919061201c565b949350505050565b6001546001600160a01b0316331461075957604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69060200160405180910390a1565b6000546001600160a01b031633146107e2576040516354348f0360e01b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b90602001610692565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff1691839150600190811061085b5761085b612150565b63ffffffff90921660209283029190910190910152600c5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd906108a1908590600401611f37565b60006040518083038186803b1580156108b957600080fd5b505afa1580156108cd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108f59190810190611daa565b50905060008160018151811061090d5761090d612150565b60200260200101518260008151811061092857610928612150565b602002602001015161093a919061204f565b600c54909150610972908690600160a01b900460ff166109625761095d8361210a565b610964565b825b60065463ffffffff16610d97565b95945050505050565b6000546001600160a01b031633146109a6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166109cd5760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a90602001610692565b6000806000610a346105f8670de0b6b3a7640000610817565b9150610a3f84610a4c565b6005549095929450925050565b6000610a5a8260045461148f565b9150600060045483600254600354610a72919061209f565b610a7c9190612030565b610a86919061201c565b600254610a939190611fd6565b9050610aa0600182612030565b9392505050565b6000546001600160a01b03163314610ad2576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0382161580610aef57506001600160a01b038116155b15610b0d5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038281166000818152600b602090815260409182902080546001600160a01b031916948616948517905581519283528201929092527fc1d3048301c0d23629a2532c8defa6d68f8e1a0e4157918769e9fb1b2eeb888e910160405180910390a15050565b6000546001600160a01b03163314610ba3576040516354348f0360e01b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b90602001610692565b6000806000610be684610ee6565b80925081935050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610c32575060019392505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614610c8457604051637d7c8f2760e11b815260040160405180910390fd5b5050919050565b600080610ca4610c9f84600687900b611fee565b6114a5565b9050610972600160601b86836001600160a01b03166118be565b6000546001600160a01b03163314610ce9576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90602001610692565b6000546001600160a01b03163314610d62576040516354348f0360e01b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e90602001610692565b600080610dab610c9f84600687900b611fee565b90506001600160801b036001600160a01b03821611610dfb576000610dd96001600160a01b03831680612030565b9050610df3600160c01b876001600160801b0316836118be565b925050610e38565b6000610e1a6001600160a01b03831680680100000000000000006118be565b9050610e34600160801b876001600160801b0316836118be565b9250505b509392505050565b6000546001600160a01b03163314610e6b576040516354348f0360e01b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa90602001610692565b6000546001600160a01b03163314610ecb576040516354348f0360e01b815260040160405180910390fd5b6106f88161196c565b6000610ee032836106fb565b92915050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610f2257600080fd5b505afa158015610f36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5a9190611c74565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9357600080fd5b505afa158015610fa7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcb9190611c74565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b81526004016110059190611f37565b60006040518083038186803b15801561101d57600080fd5b505afa92505050801561105257506040513d6000823e601f3d908101601f1916820160405261104f9190810190611daa565b60015b61108c573d808015611080576040519150601f19603f3d011682016040523d82523d6000602084013e611085565b606091505b50506110d8565b8160008151811061109f5761109f612150565b602002602001015194506001825111156110d157816001815181106110c6576110c6612150565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b0316331461110a576040516354348f0360e01b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d5415922190602001610692565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff1691839150600190811061118357611183612150565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd906111c9908590600401611f37565b60006040518083038186803b1580156111e157600080fd5b505afa1580156111f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261121d9190810190611daa565b50905060008160018151811061123557611235612150565b60200260200101518260008151811061125057611250612150565b6020026020010151611262919061204f565b600a54909150610972908690600160a01b900460ff166109625761095d8361210a565b6000546001600160a01b031633146112b0576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166112d75760405163d92e233d60e01b815260040160405180910390fd5b6106f8816119b4565b600080600960009054906101000a90046001600160a01b03166001600160a01b0316631ef94b916040518163ffffffff1660e01b815260040160206040518083038186803b15801561133157600080fd5b505afa158015611345573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113699190611c74565b60095460405163a39744b560e01b81526001600160a01b038681166004830152808416602483015292935091169063a39744b59060440160206040518083038186803b1580156113b857600080fd5b505afa1580156113cc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa09190611edc565b61141a817f0000000000000000000000000000000000000000000000000000000000000000611a53565b8051600a80546020938401511515600160a01b9081026001600160a81b03199092166001600160a01b03948516179190911791829055604080519383168452910460ff161515928201929092527f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf41089101610692565b600081831061149e5781610aa0565b5090919050565b60008060008360020b126114bc578260020b6114c9565b8260020b6114c9906120ed565b90506114d8620d89e7196120ca565b60020b8111156115125760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b60006001821661152657600160801b611538565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615611577576080611572826ffff97272373d413259a46990580e213a612030565b901c90505b60048216156115a157608061159c826ffff2e50f5f656932ef12357cf3c7fdcc612030565b901c90505b60088216156115cb5760806115c6826fffe5caca7e10e4e61c3624eaa0941cd0612030565b901c90505b60108216156115f55760806115f0826fffcb9843d60f6159c9db58835c926644612030565b901c90505b602082161561161f57608061161a826fff973b41fa98c081472e6896dfb254c0612030565b901c90505b6040821615611649576080611644826fff2ea16466c96a3843ec78b326b52861612030565b901c90505b608082161561167357608061166e826ffe5dee046a99a2a811c461f1969c3053612030565b901c90505b61010082161561169e576080611699826ffcbe86c7900a88aedcffc83b479aa3a4612030565b901c90505b6102008216156116c95760806116c4826ff987a7253ac413176f2b074cf7815e54612030565b901c90505b6104008216156116f45760806116ef826ff3392b0822b70005940c7a398e4b70f3612030565b901c90505b61080082161561171f57608061171a826fe7159475a2c29b7443b29c7fa6e889d9612030565b901c90505b61100082161561174a576080611745826fd097f3bdfd2022b8845ad8f792aa5825612030565b901c90505b612000821615611775576080611770826fa9f746462d870fdf8a65dc1f90e061e5612030565b901c90505b6140008216156117a057608061179b826f70d869a156d2a1b890bb3df62baf32f7612030565b901c90505b6180008216156117cb5760806117c6826f31be135f97d08fd981231505542fcfa6612030565b901c90505b620100008216156117f75760806117f2826f09aa508b5b7a84e1c677de54f3e99bc9612030565b901c90505b6202000082161561182257608061181d826e5d6af8dedb81196699c329225ee604612030565b901c90505b6204000082161561184c576080611847826d2216e584f5fa1ea926041bedfe98612030565b901c90505b6208000082161561187457608061186f826b048a170391f7dc42444e8fa2612030565b901c90505b60008460020b131561188f5761188c8160001961201c565b90505b61189e640100000000826120b6565b156118aa5760016118ad565b60005b6107269060ff16602083901c611fd6565b6000808060001985870985870292508281108382030391505080600014156118f857600084116118ed57600080fd5b508290049050610aa0565b80841161190457600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de90602001610692565b6119de817f0000000000000000000000000000000000000000000000000000000000000000611a53565b8051600c80546020938401511515600160a01b9081026001600160a81b03199092166001600160a01b03948516179190911791829055604080519383168452910460ff161515928201929092527fefe4783561b790425a9d83dd379f0e184938b04965a63d14ec51c27cb4ca1b3c9101610692565b60408051808201909152600080825260208201526000826001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015611aac57600080fd5b505afa158015611ac0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae49190611c74565b6001600160a01b0316149050801581611b7f5750826001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015611b3b57600080fd5b505afa158015611b4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b739190611c74565b6001600160a01b031614155b15611b9d5760405163db60809d60e01b815260040160405180910390fd5b604080518082019091526001600160a01b03851681529015156020820152905092915050565b600082601f830112611bd457600080fd5b81516020611be9611be483611fb2565b611f81565b80838252828201915082860187848660051b8901011115611c0957600080fd5b60005b85811015611c31578151611c1f8161217c565b84529284019290840190600101611c0c565b5090979650505050505050565b803563ffffffff81168114611c5257600080fd5b919050565b600060208284031215611c6957600080fd5b8135610aa08161217c565b600060208284031215611c8657600080fd5b8151610aa08161217c565b60008060408385031215611ca457600080fd5b8235611caf8161217c565b91506020830135611cbf8161217c565b809150509250929050565b60008060408385031215611cdd57600080fd5b8235611ce88161217c565b915060208381013567ffffffffffffffff811115611d0557600080fd5b8401601f81018613611d1657600080fd5b8035611d24611be482611fb2565b80828252848201915084840189868560051b8701011115611d4457600080fd5b600094505b83851015611d6e57611d5a81611c3e565b835260019490940193918501918501611d49565b5080955050505050509250929050565b60008060408385031215611d9157600080fd5b8235611d9c8161217c565b946020939093013593505050565b60008060408385031215611dbd57600080fd5b825167ffffffffffffffff80821115611dd557600080fd5b818501915085601f830112611de957600080fd5b81516020611df9611be483611fb2565b8083825282820191508286018a848660051b8901011115611e1957600080fd5b600096505b84871015611e45578051611e3181612191565b835260019690960195918301918301611e1e565b5091880151919650909350505080821115611e5f57600080fd5b50611e6c85828601611bc3565b9150509250929050565b600080600060608486031215611e8b57600080fd5b83356001600160801b0381168114611ea257600080fd5b92506020840135611eb281612191565b929592945050506040919091013590565b600060208284031215611ed557600080fd5b5035919050565b600060208284031215611eee57600080fd5b5051919050565b600080600060608486031215611f0a57600080fd5b833592506020840135611eb281612191565b600060208284031215611f2e57600080fd5b610aa082611c3e565b6020808252825182820181905260009190848201906040850190845b81811015611f7557835163ffffffff1683529284019291840191600101611f53565b50909695505050505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715611faa57611faa612166565b604052919050565b600067ffffffffffffffff821115611fcc57611fcc612166565b5060051b60200190565b60008219821115611fe957611fe9612124565b500190565b600082611ffd57611ffd61213a565b600160ff1b82146000198414161561201757612017612124565b500590565b60008261202b5761202b61213a565b500490565b600081600019048311821515161561204a5761204a612124565b500290565b60008160060b8360060b6000811281667fffffffffffff190183128115161561207a5761207a612124565b81667fffffffffffff01831381161561209557612095612124565b5090039392505050565b6000828210156120b1576120b1612124565b500390565b6000826120c5576120c561213a565b500690565b60008160020b627fffff198114156120e4576120e4612124565b60000392915050565b6000600160ff1b82141561210357612103612124565b5060000390565b60008160060b667fffffffffffff198114156120e4576120e45b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146106f857600080fd5b8060060b81146106f857600080fdfea2646970667358221220fb94e7420b7ee3ff2bd9c044cae13941443e40df0a75dc886dd69b62c62d91a264736f6c63430008070033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102535760003560e01c80637b40c91311610146578063b2e0df96116100c3578063e244208b11610087578063e244208b146105ae578063eb37d349146105c1578063ed1bd76c146105ea578063f39c38a0146105fd578063fae63d6114610610578063fe10d7741461062357600080fd5b8063b2e0df961461050a578063b93f5af01461051d578063c84993af14610530578063ca4f280314610543578063dc686d911461057657600080fd5b8063a62611a21161010a578063a62611a2146104a1578063ab033ea9146104aa578063ab5dce00146104bd578063ab8cedc5146104d0578063ad5c4648146104e357600080fd5b80637b40c913146104385780638561579c146104575780638a9b1b09146104605780639aaad67914610469578063a0d271071461048e57600080fd5b806337090c2f116101d4578063516c332311610198578063516c3323146103c95780635aa6e675146103dc5780635c38eb3a146103ef578063607e48d414610402578063696a437b1461041557600080fd5b806337090c2f146103635780633b67c3bd1461036c5780633cc7ab301461037f5780633facf24214610392578063435b21c11461039b57600080fd5b8063238efcbc1161021b578063238efcbc146102f857806325f09e61146103005780632742b9e7146103095780632750c0f914610312578063289adb441461035057600080fd5b806305e0b9a0146102585780630c5258351461029c578063117cfc1b146102b1578063160e1e31146102c45780632248e82d146102d7575b600080fd5b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6102af6102aa366004611ec3565b610636565b005b60095461027f906001600160a01b031681565b6102af6102d2366004611c57565b61069d565b6102ea6102e5366004611d7e565b6106fb565b604051908152602001610293565b6102af61072e565b6102ea61271081565b6102ea60045481565b600c54610331906001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b039093168352901515602083015201610293565b6102af61035e366004611ec3565b6107b7565b6102ea60035481565b6102ea61037a366004611ec3565b610817565b6102af61038d366004611c57565b61097b565b6102ea60055481565b6103ae6103a9366004611ec3565b610a1b565b60408051938452602084019290925290820152606001610293565b6102ea6103d7366004611ec3565b610a4c565b60005461027f906001600160a01b031681565b6102af6103fd366004611c91565b610aa7565b6102af610410366004611ec3565b610b78565b610428610423366004611c57565b610bd8565b6040519015158152602001610293565b600a54610331906001600160a01b03811690600160a01b900460ff1682565b6102ea60025481565b6102ea60085481565b6006546104799063ffffffff1681565b60405163ffffffff9091168152602001610293565b6102ea61049c366004611ef5565b610c8b565b6102ea60075481565b6102af6104b8366004611c57565b610cbe565b6102af6104cb366004611ec3565b610d37565b6102ea6104de366004611e76565b610d97565b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6102af610518366004611ec3565b610e40565b6102af61052b366004611f1c565b610ea0565b6102ea61053e366004611ec3565b610ed4565b610556610551366004611c57565b610ee6565b604080516001600160a01b03938416815292909116602083015201610293565b610589610584366004611cca565b610fd4565b60408051600694850b81529290930b6020830152151591810191909152606001610293565b6102af6105bc366004611ec3565b6110df565b61027f6105cf366004611c57565b600b602052600090815260409020546001600160a01b031681565b6102ea6105f8366004611ec3565b61113f565b60015461027f906001600160a01b031681565b6102af61061e366004611c57565b611285565b6102ea610631366004611c57565b6112e0565b6000546001600160a01b03163314610661576040516354348f0360e01b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b031633146106c8576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166106ef5760405163d92e233d60e01b815260040160405180910390fd5b6106f8816113f0565b50565b60008061070a6103d7856112e0565b905061072661271061071c8386612030565b6105f8919061201c565b949350505050565b6001546001600160a01b0316331461075957604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69060200160405180910390a1565b6000546001600160a01b031633146107e2576040516354348f0360e01b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b90602001610692565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff1691839150600190811061085b5761085b612150565b63ffffffff90921660209283029190910190910152600c5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd906108a1908590600401611f37565b60006040518083038186803b1580156108b957600080fd5b505afa1580156108cd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108f59190810190611daa565b50905060008160018151811061090d5761090d612150565b60200260200101518260008151811061092857610928612150565b602002602001015161093a919061204f565b600c54909150610972908690600160a01b900460ff166109625761095d8361210a565b610964565b825b60065463ffffffff16610d97565b95945050505050565b6000546001600160a01b031633146109a6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166109cd5760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a90602001610692565b6000806000610a346105f8670de0b6b3a7640000610817565b9150610a3f84610a4c565b6005549095929450925050565b6000610a5a8260045461148f565b9150600060045483600254600354610a72919061209f565b610a7c9190612030565b610a86919061201c565b600254610a939190611fd6565b9050610aa0600182612030565b9392505050565b6000546001600160a01b03163314610ad2576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0382161580610aef57506001600160a01b038116155b15610b0d5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038281166000818152600b602090815260409182902080546001600160a01b031916948616948517905581519283528201929092527fc1d3048301c0d23629a2532c8defa6d68f8e1a0e4157918769e9fb1b2eeb888e910160405180910390a15050565b6000546001600160a01b03163314610ba3576040516354348f0360e01b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b90602001610692565b6000806000610be684610ee6565b80925081935050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610c32575060019392505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614610c8457604051637d7c8f2760e11b815260040160405180910390fd5b5050919050565b600080610ca4610c9f84600687900b611fee565b6114a5565b9050610972600160601b86836001600160a01b03166118be565b6000546001600160a01b03163314610ce9576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90602001610692565b6000546001600160a01b03163314610d62576040516354348f0360e01b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e90602001610692565b600080610dab610c9f84600687900b611fee565b90506001600160801b036001600160a01b03821611610dfb576000610dd96001600160a01b03831680612030565b9050610df3600160c01b876001600160801b0316836118be565b925050610e38565b6000610e1a6001600160a01b03831680680100000000000000006118be565b9050610e34600160801b876001600160801b0316836118be565b9250505b509392505050565b6000546001600160a01b03163314610e6b576040516354348f0360e01b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa90602001610692565b6000546001600160a01b03163314610ecb576040516354348f0360e01b815260040160405180910390fd5b6106f88161196c565b6000610ee032836106fb565b92915050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610f2257600080fd5b505afa158015610f36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5a9190611c74565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9357600080fd5b505afa158015610fa7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcb9190611c74565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b81526004016110059190611f37565b60006040518083038186803b15801561101d57600080fd5b505afa92505050801561105257506040513d6000823e601f3d908101601f1916820160405261104f9190810190611daa565b60015b61108c573d808015611080576040519150601f19603f3d011682016040523d82523d6000602084013e611085565b606091505b50506110d8565b8160008151811061109f5761109f612150565b602002602001015194506001825111156110d157816001815181106110c6576110c6612150565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b0316331461110a576040516354348f0360e01b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d5415922190602001610692565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff1691839150600190811061118357611183612150565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd906111c9908590600401611f37565b60006040518083038186803b1580156111e157600080fd5b505afa1580156111f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261121d9190810190611daa565b50905060008160018151811061123557611235612150565b60200260200101518260008151811061125057611250612150565b6020026020010151611262919061204f565b600a54909150610972908690600160a01b900460ff166109625761095d8361210a565b6000546001600160a01b031633146112b0576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166112d75760405163d92e233d60e01b815260040160405180910390fd5b6106f8816119b4565b600080600960009054906101000a90046001600160a01b03166001600160a01b0316631ef94b916040518163ffffffff1660e01b815260040160206040518083038186803b15801561133157600080fd5b505afa158015611345573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113699190611c74565b60095460405163a39744b560e01b81526001600160a01b038681166004830152808416602483015292935091169063a39744b59060440160206040518083038186803b1580156113b857600080fd5b505afa1580156113cc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa09190611edc565b61141a817f0000000000000000000000000000000000000000000000000000000000000000611a53565b8051600a80546020938401511515600160a01b9081026001600160a81b03199092166001600160a01b03948516179190911791829055604080519383168452910460ff161515928201929092527f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf41089101610692565b600081831061149e5781610aa0565b5090919050565b60008060008360020b126114bc578260020b6114c9565b8260020b6114c9906120ed565b90506114d8620d89e7196120ca565b60020b8111156115125760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b60006001821661152657600160801b611538565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615611577576080611572826ffff97272373d413259a46990580e213a612030565b901c90505b60048216156115a157608061159c826ffff2e50f5f656932ef12357cf3c7fdcc612030565b901c90505b60088216156115cb5760806115c6826fffe5caca7e10e4e61c3624eaa0941cd0612030565b901c90505b60108216156115f55760806115f0826fffcb9843d60f6159c9db58835c926644612030565b901c90505b602082161561161f57608061161a826fff973b41fa98c081472e6896dfb254c0612030565b901c90505b6040821615611649576080611644826fff2ea16466c96a3843ec78b326b52861612030565b901c90505b608082161561167357608061166e826ffe5dee046a99a2a811c461f1969c3053612030565b901c90505b61010082161561169e576080611699826ffcbe86c7900a88aedcffc83b479aa3a4612030565b901c90505b6102008216156116c95760806116c4826ff987a7253ac413176f2b074cf7815e54612030565b901c90505b6104008216156116f45760806116ef826ff3392b0822b70005940c7a398e4b70f3612030565b901c90505b61080082161561171f57608061171a826fe7159475a2c29b7443b29c7fa6e889d9612030565b901c90505b61100082161561174a576080611745826fd097f3bdfd2022b8845ad8f792aa5825612030565b901c90505b612000821615611775576080611770826fa9f746462d870fdf8a65dc1f90e061e5612030565b901c90505b6140008216156117a057608061179b826f70d869a156d2a1b890bb3df62baf32f7612030565b901c90505b6180008216156117cb5760806117c6826f31be135f97d08fd981231505542fcfa6612030565b901c90505b620100008216156117f75760806117f2826f09aa508b5b7a84e1c677de54f3e99bc9612030565b901c90505b6202000082161561182257608061181d826e5d6af8dedb81196699c329225ee604612030565b901c90505b6204000082161561184c576080611847826d2216e584f5fa1ea926041bedfe98612030565b901c90505b6208000082161561187457608061186f826b048a170391f7dc42444e8fa2612030565b901c90505b60008460020b131561188f5761188c8160001961201c565b90505b61189e640100000000826120b6565b156118aa5760016118ad565b60005b6107269060ff16602083901c611fd6565b6000808060001985870985870292508281108382030391505080600014156118f857600084116118ed57600080fd5b508290049050610aa0565b80841161190457600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de90602001610692565b6119de817f0000000000000000000000000000000000000000000000000000000000000000611a53565b8051600c80546020938401511515600160a01b9081026001600160a81b03199092166001600160a01b03948516179190911791829055604080519383168452910460ff161515928201929092527fefe4783561b790425a9d83dd379f0e184938b04965a63d14ec51c27cb4ca1b3c9101610692565b60408051808201909152600080825260208201526000826001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015611aac57600080fd5b505afa158015611ac0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae49190611c74565b6001600160a01b0316149050801581611b7f5750826001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015611b3b57600080fd5b505afa158015611b4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b739190611c74565b6001600160a01b031614155b15611b9d5760405163db60809d60e01b815260040160405180910390fd5b604080518082019091526001600160a01b03851681529015156020820152905092915050565b600082601f830112611bd457600080fd5b81516020611be9611be483611fb2565b611f81565b80838252828201915082860187848660051b8901011115611c0957600080fd5b60005b85811015611c31578151611c1f8161217c565b84529284019290840190600101611c0c565b5090979650505050505050565b803563ffffffff81168114611c5257600080fd5b919050565b600060208284031215611c6957600080fd5b8135610aa08161217c565b600060208284031215611c8657600080fd5b8151610aa08161217c565b60008060408385031215611ca457600080fd5b8235611caf8161217c565b91506020830135611cbf8161217c565b809150509250929050565b60008060408385031215611cdd57600080fd5b8235611ce88161217c565b915060208381013567ffffffffffffffff811115611d0557600080fd5b8401601f81018613611d1657600080fd5b8035611d24611be482611fb2565b80828252848201915084840189868560051b8701011115611d4457600080fd5b600094505b83851015611d6e57611d5a81611c3e565b835260019490940193918501918501611d49565b5080955050505050509250929050565b60008060408385031215611d9157600080fd5b8235611d9c8161217c565b946020939093013593505050565b60008060408385031215611dbd57600080fd5b825167ffffffffffffffff80821115611dd557600080fd5b818501915085601f830112611de957600080fd5b81516020611df9611be483611fb2565b8083825282820191508286018a848660051b8901011115611e1957600080fd5b600096505b84871015611e45578051611e3181612191565b835260019690960195918301918301611e1e565b5091880151919650909350505080821115611e5f57600080fd5b50611e6c85828601611bc3565b9150509250929050565b600080600060608486031215611e8b57600080fd5b83356001600160801b0381168114611ea257600080fd5b92506020840135611eb281612191565b929592945050506040919091013590565b600060208284031215611ed557600080fd5b5035919050565b600060208284031215611eee57600080fd5b5051919050565b600080600060608486031215611f0a57600080fd5b833592506020840135611eb281612191565b600060208284031215611f2e57600080fd5b610aa082611c3e565b6020808252825182820181905260009190848201906040850190845b81811015611f7557835163ffffffff1683529284019291840191600101611f53565b50909695505050505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715611faa57611faa612166565b604052919050565b600067ffffffffffffffff821115611fcc57611fcc612166565b5060051b60200190565b60008219821115611fe957611fe9612124565b500190565b600082611ffd57611ffd61213a565b600160ff1b82146000198414161561201757612017612124565b500590565b60008261202b5761202b61213a565b500490565b600081600019048311821515161561204a5761204a612124565b500290565b60008160060b8360060b6000811281667fffffffffffff190183128115161561207a5761207a612124565b81667fffffffffffff01831381161561209557612095612124565b5090039392505050565b6000828210156120b1576120b1612124565b500390565b6000826120c5576120c561213a565b500690565b60008160020b627fffff198114156120e4576120e4612124565b60000392915050565b6000600160ff1b82141561210357612103612124565b5060000390565b60008160060b667fffffffffffff198114156120e4576120e45b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146106f857600080fd5b8060060b81146106f857600080fdfea2646970667358221220fb94e7420b7ee3ff2bd9c044cae13941443e40df0a75dc886dd69b62c62d91a264736f6c63430008070033", + "devdoc": { + "kind": "dev", + "methods": { + "bonds(address)": { + "params": { + "_keeper": "The address of the keeper to check" + }, + "returns": { + "_amountBonded": "The amount of KP3R the keeper has bonded" + } + }, + "constructor": { + "details": "Oracle pools should use 18 decimals tokens", + "params": { + "_governance": "Address of governance", + "_keep3rV2": "Address of sidechain Keep3r implementation", + "_kp3rWethOracle": "Address of oracle used for KP3R/WETH quote", + "_wethUsdOracle": "Address of oracle used for WETH/USD quote" + } + }, + "getKP3RsAtTick(uint256,int56,uint256)": { + "params": { + "_liquidityAmount": "Amount of liquidity to be converted", + "_tickDifference": "Tick value used to calculate the quote", + "_timeInterval": "Time value used to calculate the quote" + }, + "returns": { + "_kp3rAmount": "Amount of KP3R tokens underlying on the given liquidity" + } + }, + "getPaymentParams(uint256)": { + "params": { + "_bonds": "Amount of bonded KP3R owned by the keeper" + }, + "returns": { + "_boost": "Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R", + "_extraGas": "Amount of extra gas that should be added to the gas spent", + "_oneUsdQuote": "Amount of KP3R tokens equivalent to 1 ETH" + } + }, + "getPoolTokens(address)": { + "params": { + "_pool": "Address of the correspondant pool" + }, + "returns": { + "_token0": "Address of the first token of the pair", + "_token1": "Address of the second token of the pair" + } + }, + "getQuoteAtTick(uint128,int56,uint256)": { + "params": { + "_baseAmount": "Amount of token to be converted", + "_tickDifference": "Tick value used to calculate the quote", + "_timeInterval": "Time value used to calculate the quote" + }, + "returns": { + "_quoteAmount": "Amount of credits deserved for the baseAmount at the tick value" + } + }, + "getRewardAmount(uint256)": { + "params": { + "_gasUsed": "The amount of gas used that will be rewarded" + }, + "returns": { + "_amount": "The amount of KP3R that should be awarded to tx.origin" + } + }, + "getRewardAmountFor(address,uint256)": { + "params": { + "_gasUsed": "The amount of gas used that will be rewarded", + "_keeper": "The address of the keeper to check" + }, + "returns": { + "_kp3r": "The amount of KP3R that should be awarded to the keeper" + } + }, + "getRewardBoostFor(uint256)": { + "details": "If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%", + "params": { + "_bonds": "The amount of KP3R tokens bonded by the keeper" + }, + "returns": { + "_rewardBoost": "The reward boost that corresponds to the keeper" + } + }, + "isKP3RToken0(address)": { + "params": { + "_pool": "Address of the correspondant pool" + }, + "returns": { + "_isKP3RToken0": "Boolean indicating the order of the tokens in the pair" + } + }, + "observe(address,uint32[])": { + "params": { + "_pool": "Address of the pool to observe", + "_secondsAgo": "Array with time references to observe" + }, + "returns": { + "_success": "Boolean indicating if the observe call was succesfull", + "_tickCumulative1": "Cumulative sum of ticks until first time reference", + "_tickCumulative2": "Cumulative sum of ticks until second time reference" + } + }, + "quote(uint256)": { + "details": "This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas", + "params": { + "_eth": "The amount of ETH" + }, + "returns": { + "_amountOut": "The amount of KP3R" + } + }, + "quoteUsdToEth(uint256)": { + "details": "Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R", + "params": { + "_usd": "The amount of USD to quote to ETH" + }, + "returns": { + "_amountOut": "The resulting amount of ETH after quoting the USD" + } + }, + "setGovernance(address)": { + "params": { + "_governance": "The address being proposed as the new governance" + } + }, + "setKeep3rV2(address)": { + "params": { + "_keep3rV2": "The address of Keep3r V2" + } + }, + "setKp3rWethPool(address)": { + "params": { + "_poolAddress": "The address of the KP3R-WETH pool" + } + }, + "setMaxBoost(uint256)": { + "params": { + "_maxBoost": "The maximum boost multiplier" + } + }, + "setMinBaseFee(uint256)": { + "params": { + "_minBaseFee": "The minimum rewarded gas fee" + } + }, + "setMinBoost(uint256)": { + "params": { + "_minBoost": "The minimum boost multiplier" + } + }, + "setMinPriorityFee(uint256)": { + "params": { + "_minPriorityFee": "The minimum rewarded priority fee" + } + }, + "setOracle(address,address)": { + "details": "The oracle must contain KP3R as either token0 or token1", + "params": { + "_liquidity": "The address of the liquidity", + "_oracle": "The address of the pool used to quote the liquidity from" + } + }, + "setQuoteTwapTime(uint32)": { + "params": { + "_quoteTwapTime": "The twap time for quoting" + } + }, + "setTargetBond(uint256)": { + "params": { + "_targetBond": "The target bond amount" + } + }, + "setWethUsdPool(address)": { + "details": "The oracle must contain WETH as either token0 or token1", + "params": { + "_poolAddress": "The address of the pool used as oracle" + } + }, + "setWorkExtraGas(uint256)": { + "params": { + "_workExtraGas": "The work extra gas" + } + } + }, + "stateVariables": { + "oracle": { + "return": "_oracle The address of the observable pool for given liquidity", + "returns": { + "_0": "_oracle The address of the observable pool for given liquidity" + } + }, + "wethUSDPool": { + "returns": { + "isTKNToken0": "True if calling the token0 method of the pool returns the WETH token address", + "poolAddress": "Address of the pool" + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidOraclePool()": [ + { + "notice": "Throws when pool does not have KP3R as token0 nor token1" + } + ], + "LiquidityPairInvalid()": [ + { + "notice": "Throws when none of the tokens in the liquidity pair is KP3R" + } + ], + "NoGovernanceZeroAddress()": [ + { + "notice": "Throws if trying to set governance to zero address" + } + ], + "OnlyGovernance()": [ + { + "notice": "Throws if the caller of the function is not governance" + } + ], + "OnlyPendingGovernance()": [ + { + "notice": "Throws if the caller of the function is not pendingGovernance" + } + ], + "ZeroAddress()": [ + { + "notice": "Throws if a variable is assigned to the zero address" + } + ] + }, + "events": { + "GovernanceProposal(address)": { + "notice": "Emitted when a new governance is proposed" + }, + "GovernanceSet(address)": { + "notice": "Emitted when pendingGovernance accepts to be governance" + }, + "Keep3rV2Change(address)": { + "notice": "Emitted when the Keep3r V2 address is changed" + }, + "Kp3rWethPoolChange(address,bool)": { + "notice": "Emitted when the kp3r weth pool is changed" + }, + "MaxBoostChange(uint256)": { + "notice": "Emitted when the maximum boost multiplier is changed" + }, + "MinBaseFeeChange(uint256)": { + "notice": "Emitted when minimum rewarded gas fee is changed" + }, + "MinBoostChange(uint256)": { + "notice": "Emitted when the minimum boost multiplier is changed" + }, + "MinPriorityFeeChange(uint256)": { + "notice": "Emitted when minimum rewarded priority fee is changed" + }, + "OracleSet(address,address)": { + "notice": "The oracle for a liquidity has been saved" + }, + "QuoteTwapTimeChange(uint32)": { + "notice": "Emitted when the quote twap time is changed" + }, + "TargetBondChange(uint256)": { + "notice": "Emitted when the target bond amount is changed" + }, + "WethUSDPoolChange(address,bool)": { + "notice": "Emitted when the WETH USD pool is changed" + }, + "WorkExtraGasChange(uint256)": { + "notice": "Emitted when the work extra gas amount is changed" + } + }, + "kind": "user", + "methods": { + "BOOST_BASE()": { + "notice": "The boost base used to calculate the boost rewards for the keeper" + }, + "KP3R()": { + "notice": "Address of KP3R token" + }, + "WETH()": { + "notice": "Ethereum mainnet WETH address used for quoting references" + }, + "acceptGovernance()": { + "notice": "Changes the governance from the current governance to the previously proposed address" + }, + "bonds(address)": { + "notice": "Uses valid wKP3R address from Keep3rSidechain to query keeper bonds" + }, + "getKP3RsAtTick(uint256,int56,uint256)": { + "notice": "Given a tick and a liquidity amount, calculates the underlying KP3R tokens" + }, + "getPaymentParams(uint256)": { + "notice": "Get multiplier, quote, and extra, in order to calculate keeper payment" + }, + "getPoolTokens(address)": { + "notice": "Given a pool address, returns the underlying tokens of the pair" + }, + "getQuoteAtTick(uint128,int56,uint256)": { + "notice": "Given a tick and a token amount, calculates the output in correspondant token" + }, + "getRewardAmount(uint256)": { + "notice": "Calculates the reward (in KP3R) that corresponds to tx.origin for using gas" + }, + "getRewardAmountFor(address,uint256)": { + "notice": "Calculates the reward (in KP3R) that corresponds to a keeper for using gas" + }, + "getRewardBoostFor(uint256)": { + "notice": "Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded" + }, + "governance()": { + "notice": "Stores the governance address" + }, + "isKP3RToken0(address)": { + "notice": "Defines the order of the tokens in the pair for twap calculations" + }, + "keep3rV2()": { + "notice": "Address of Keep3r V2" + }, + "kp3rWethPool()": { + "notice": "KP3R-WETH pool that is being used as oracle" + }, + "maxBoost()": { + "notice": "The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE" + }, + "minBaseFee()": { + "notice": "The minimum base fee that is used to calculate keeper rewards" + }, + "minBoost()": { + "notice": "The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE" + }, + "minPriorityFee()": { + "notice": "The minimum priority fee that is also rewarded for keepers" + }, + "observe(address,uint32[])": { + "notice": "Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment" + }, + "pendingGovernance()": { + "notice": "Stores the pendingGovernance address" + }, + "quote(uint256)": { + "notice": "Calculates the amount of KP3R that corresponds to the ETH passed into the function" + }, + "quoteTwapTime()": { + "notice": "The twap time for quoting" + }, + "quoteUsdToEth(uint256)": { + "notice": "Quotes USD to ETH" + }, + "setGovernance(address)": { + "notice": "Proposes a new address to be governance" + }, + "setKeep3rV2(address)": { + "notice": "Sets the Keep3r V2 address" + }, + "setKp3rWethPool(address)": { + "notice": "Sets KP3R-WETH pool" + }, + "setMaxBoost(uint256)": { + "notice": "Sets the maximum boost multiplier" + }, + "setMinBaseFee(uint256)": { + "notice": "Sets the minimum rewarded gas fee" + }, + "setMinBoost(uint256)": { + "notice": "Sets the minimum boost multiplier" + }, + "setMinPriorityFee(uint256)": { + "notice": "Sets the minimum rewarded gas priority fee" + }, + "setOracle(address,address)": { + "notice": "Sets an oracle for a given liquidity" + }, + "setQuoteTwapTime(uint32)": { + "notice": "Sets the quote twap time" + }, + "setTargetBond(uint256)": { + "notice": "Sets the target bond amount" + }, + "setWethUsdPool(address)": { + "notice": "Sets an oracle for querying WETH/USD quote" + }, + "setWorkExtraGas(uint256)": { + "notice": "Sets the work extra gas amount" + }, + "targetBond()": { + "notice": "The targeted amount of bonded KP3Rs to max-up reward multiplier For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get the maximum boost possible in his rewards, if it's less, the reward boost will be proportional" + }, + "wethUSDPool()": { + "notice": "WETH-USD pool that is being used as oracle" + }, + "workExtraGas()": { + "notice": "The amount of unaccounted gas that is going to be added to keeper payments" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 5362, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "governance", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 5366, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "pendingGovernance", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 2989, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "minBoost", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 2994, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "maxBoost", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 2999, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "targetBond", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 3004, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "workExtraGas", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 3009, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "quoteTwapTime", + "offset": 0, + "slot": "6", + "type": "t_uint32" + }, + { + "astId": 3014, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "minBaseFee", + "offset": 0, + "slot": "7", + "type": "t_uint256" + }, + { + "astId": 3019, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "minPriorityFee", + "offset": 0, + "slot": "8", + "type": "t_uint256" + }, + { + "astId": 3023, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "keep3rV2", + "offset": 0, + "slot": "9", + "type": "t_address" + }, + { + "astId": 3028, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "kp3rWethPool", + "offset": 0, + "slot": "10", + "type": "t_struct(TokenOraclePool)12811_storage" + }, + { + "astId": 9751, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "oracle", + "offset": 0, + "slot": "11", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 9756, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "wethUSDPool", + "offset": 0, + "slot": "12", + "type": "t_struct(TokenOraclePool)12811_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_struct(TokenOraclePool)12811_storage": { + "encoding": "inplace", + "label": "struct IKeep3rHelperParameters.TokenOraclePool", + "members": [ + { + "astId": 12808, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "poolAddress", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 12810, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "isTKNToken0", + "offset": 20, + "slot": "0", + "type": "t_bool" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimisticEthereum/Keep3rSidechain.json b/deployments/optimisticEthereum/Keep3rSidechain.json new file mode 100644 index 0000000..e26f581 --- /dev/null +++ b/deployments/optimisticEthereum/Keep3rSidechain.json @@ -0,0 +1,4013 @@ +{ + "address": "0x745a50320B6eB8FF281f1664Fc6713991661B129", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_governance", + "type": "address" + }, + { + "internalType": "address", + "name": "_keep3rHelperSidechain", + "type": "address" + }, + { + "internalType": "address", + "name": "_wrappedKP3R", + "type": "address" + }, + { + "internalType": "address", + "name": "_keep3rEscrow", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AlreadyAJob", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyAKeeper", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyDisputed", + "type": "error" + }, + { + "inputs": [], + "name": "BondsLocked", + "type": "error" + }, + { + "inputs": [], + "name": "BondsUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "Deprecated", + "type": "error" + }, + { + "inputs": [], + "name": "Disputed", + "type": "error" + }, + { + "inputs": [], + "name": "DisputerExistent", + "type": "error" + }, + { + "inputs": [], + "name": "DisputerUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "GasNotInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientFunds", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientJobTokenCredits", + "type": "error" + }, + { + "inputs": [], + "name": "JobAlreadyAdded", + "type": "error" + }, + { + "inputs": [], + "name": "JobDisputed", + "type": "error" + }, + { + "inputs": [], + "name": "JobLiquidityInsufficient", + "type": "error" + }, + { + "inputs": [], + "name": "JobLiquidityLessThanMin", + "type": "error" + }, + { + "inputs": [], + "name": "JobLiquidityUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "JobMigrationImpossible", + "type": "error" + }, + { + "inputs": [], + "name": "JobMigrationLocked", + "type": "error" + }, + { + "inputs": [], + "name": "JobMigrationUnavailable", + "type": "error" + }, + { + "inputs": [], + "name": "JobTokenCreditsLocked", + "type": "error" + }, + { + "inputs": [], + "name": "JobTokenInsufficient", + "type": "error" + }, + { + "inputs": [], + "name": "JobTokenUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "JobUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "JobUnavailable", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidityPairApproved", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidityPairUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidityPairUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "MinRewardPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "NoGovernanceZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "NotDisputed", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyDisputer", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyGovernance", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyJobOwner", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingGovernance", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingJobOwner", + "type": "error" + }, + { + "inputs": [], + "name": "OnlySlasher", + "type": "error" + }, + { + "inputs": [], + "name": "SlasherExistent", + "type": "error" + }, + { + "inputs": [], + "name": "SlasherUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "TokenUnallowed", + "type": "error" + }, + { + "inputs": [], + "name": "UnbondsLocked", + "type": "error" + }, + { + "inputs": [], + "name": "UnbondsUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_bond", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Activation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_bondTime", + "type": "uint256" + } + ], + "name": "BondTimeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_bonding", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Bonding", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_jobOrKeeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_disputer", + "type": "address" + } + ], + "name": "Dispute", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_disputer", + "type": "address" + } + ], + "name": "DisputerAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_disputer", + "type": "address" + } + ], + "name": "DisputerRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "DustSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "FeeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_pendingGovernance", + "type": "address" + } + ], + "name": "GovernanceProposal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_governance", + "type": "address" + } + ], + "name": "GovernanceSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_inflationPeriod", + "type": "uint256" + } + ], + "name": "InflationPeriodChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_jobOwner", + "type": "address" + } + ], + "name": "JobAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_fromJob", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_toJob", + "type": "address" + } + ], + "name": "JobMigrationRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_fromJob", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_toJob", + "type": "address" + } + ], + "name": "JobMigrationSuccessful", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "JobOwnershipAssent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_pendingOwner", + "type": "address" + } + ], + "name": "JobOwnershipChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_slasher", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "JobSlashLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_slasher", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "JobSlashToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_keep3rHelper", + "type": "address" + } + ], + "name": "Keep3rHelperChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_keep3rV1", + "type": "address" + } + ], + "name": "Keep3rV1Change", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_keep3rV1Proxy", + "type": "address" + } + ], + "name": "Keep3rV1ProxyChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_slasher", + "type": "address" + } + ], + "name": "KeeperRevoke", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_slasher", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "KeeperSlash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_gasLeft", + "type": "uint256" + } + ], + "name": "KeeperValidation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_credit", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_payment", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_gasLeft", + "type": "uint256" + } + ], + "name": "KeeperWork", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "LiquidityAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_liquidity", + "type": "address" + } + ], + "name": "LiquidityApproval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rewardedAt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_currentCredits", + "type": "uint256" + } + ], + "name": "LiquidityCreditsForced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rewardedAt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_currentCredits", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_periodCredits", + "type": "uint256" + } + ], + "name": "LiquidityCreditsReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_liquidityMinimum", + "type": "uint256" + } + ], + "name": "LiquidityMinimumChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_liquidity", + "type": "address" + } + ], + "name": "LiquidityRevocation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "LiquidityWithdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_jobOrKeeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_resolver", + "type": "address" + } + ], + "name": "Resolve", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_rewardPeriodTime", + "type": "uint256" + } + ], + "name": "RewardPeriodTimeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_slasher", + "type": "address" + } + ], + "name": "SlasherAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_slasher", + "type": "address" + } + ], + "name": "SlasherRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "TokenCreditAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "TokenCreditWithdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_unbondTime", + "type": "uint256" + } + ], + "name": "UnbondTimeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeperOrJob", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_unbonding", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Unbonding", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_bond", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "acceptGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_fromJob", + "type": "address" + }, + { + "internalType": "address", + "name": "_toJob", + "type": "address" + } + ], + "name": "acceptJobMigration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + } + ], + "name": "acceptJobOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bonding", + "type": "address" + } + ], + "name": "activate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_disputer", + "type": "address" + } + ], + "name": "addDisputer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + } + ], + "name": "addJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "addLiquidityToJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_slasher", + "type": "address" + } + ], + "name": "addSlasher", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "addTokenCreditsToJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + } + ], + "name": "approveLiquidity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "approvedLiquidities", + "outputs": [ + { + "internalType": "address[]", + "name": "_list", + "type": "address[]" + } + ], + "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": [], + "name": "bondTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_payment", + "type": "uint256" + } + ], + "name": "bondedPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "bonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "canActivateAfter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "canWithdrawAfter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "changeJobOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "directTokenPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_jobOrKeeper", + "type": "address" + } + ], + "name": "dispute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "disputers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "disputes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "firstSeen", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "forceLiquidityCreditsToJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "governance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "hasBonded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inflationPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "address", + "name": "_bond", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minBond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_earned", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_age", + "type": "uint256" + } + ], + "name": "isBondedKeeper", + "outputs": [ + { + "internalType": "bool", + "name": "_isBondedKeeper", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + } + ], + "name": "isKeeper", + "outputs": [ + { + "internalType": "bool", + "name": "_isKeeper", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + } + ], + "name": "jobLiquidityCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "_liquidityCredits", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "jobOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "jobPendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + } + ], + "name": "jobPeriodCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "_periodCredits", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "jobTokenCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "jobTokenCreditsAddedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "jobs", + "outputs": [ + { + "internalType": "address[]", + "name": "_list", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keep3rHelper", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keep3rV1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keep3rV1Proxy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keepers", + "outputs": [ + { + "internalType": "address[]", + "name": "_list", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "liquidityAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidityMinimum", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_fromJob", + "type": "address" + }, + { + "internalType": "address", + "name": "_toJob", + "type": "address" + } + ], + "name": "migrateJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + } + ], + "name": "observeLiquidity", + "outputs": [ + { + "components": [ + { + "internalType": "int56", + "name": "current", + "type": "int56" + }, + { + "internalType": "int56", + "name": "difference", + "type": "int56" + }, + { + "internalType": "uint256", + "name": "period", + "type": "uint256" + } + ], + "internalType": "struct IKeep3rJobFundableLiquidity.TickCache", + "name": "_tickCache", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pendingBonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingGovernance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pendingJobMigrations", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pendingUnbonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "quoteLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "_periodCredits", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_disputer", + "type": "address" + } + ], + "name": "removeDisputer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_slasher", + "type": "address" + } + ], + "name": "removeSlasher", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_jobOrKeeper", + "type": "address" + } + ], + "name": "resolve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + } + ], + "name": "revoke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + } + ], + "name": "revokeLiquidity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPeriodTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sendDust", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bondTime", + "type": "uint256" + } + ], + "name": "setBondTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governance", + "type": "address" + } + ], + "name": "setGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_inflationPeriod", + "type": "uint256" + } + ], + "name": "setInflationPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rHelper", + "type": "address" + } + ], + "name": "setKeep3rHelper", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rV1", + "type": "address" + } + ], + "name": "setKeep3rV1", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rV1Proxy", + "type": "address" + } + ], + "name": "setKeep3rV1Proxy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_liquidityMinimum", + "type": "uint256" + } + ], + "name": "setLiquidityMinimum", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rewardPeriodTime", + "type": "uint256" + } + ], + "name": "setRewardPeriodTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_unbondTime", + "type": "uint256" + } + ], + "name": "setUnbondTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "address", + "name": "_bonded", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_bondAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_unbondAmount", + "type": "uint256" + } + ], + "name": "slash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "slashLiquidityFromJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "slashTokenFromJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "slashers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + } + ], + "name": "totalJobCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "_credits", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bonding", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "unbond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "unbondLiquidityFromJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unbondTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "virtualReserves", + "outputs": [ + { + "internalType": "int256", + "name": "_virtualReserves", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bonding", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "withdrawLiquidityFromJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "withdrawTokenCreditsFromJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "workCompleted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "worked", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_usdPerGasUnit", + "type": "uint256" + } + ], + "name": "worked", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "workedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x24d8d0348e51864db8e415548ceb1070b6fbde116ccf8b5da735895d155dfc4f", + "receipt": { + "to": null, + "from": "0xA825fc60eB4B1269F1dF0f6E574b953d2b5f7EFc", + "contractAddress": "0x745a50320B6eB8FF281f1664Fc6713991661B129", + "transactionIndex": 0, + "gasUsed": "5569093", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x27301598254cb9ba843166200a4ac45497b7db8cc1808f50ceabb7542f838586", + "transactionHash": "0x24d8d0348e51864db8e415548ceb1070b6fbde116ccf8b5da735895d155dfc4f", + "logs": [], + "blockNumber": 46380707, + "cumulativeGasUsed": "5569093", + "status": 1, + "byzantium": true + }, + "args": [ + "0x7d6daDb31dBeBc68c8A0b2cCfE5C1f26F24bD41d", + "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "0x74bcb73fA7010EB523a81feE2bB23EaB3d12c2f8", + "0xDBc6501645407CF4D3af383FbD5Bf7586b135d81" + ], + "numDeployments": 1, + "solcInputHash": "aa1ee30f4d8e78611039940e35c6db8b", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rHelperSidechain\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_wrappedKP3R\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rEscrow\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyAJob\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyAKeeper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Deprecated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Disputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasNotInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientJobTokenCredits\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityLessThanMin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationImpossible\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenCreditsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MinRewardPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDisputer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySlasher\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenUnallowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Activation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"BondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Bonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"Dispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"DustSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"FeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"InflationPeriodChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOwner\",\"type\":\"address\"}],\"name\":\"JobAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationSuccessful\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipAssent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_pendingOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashLiquidity\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"Keep3rHelperChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"Keep3rV1Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"Keep3rV1ProxyChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"KeeperRevoke\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"KeeperSlash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperValidation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_credit\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperWork\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityApproval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsForced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsReward\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"LiquidityMinimumChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityRevocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_resolver\",\"type\":\"address\"}],\"name\":\"Resolve\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"RewardPeriodTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"UnbondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeperOrJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_unbonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Unbonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"acceptJobMigration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"acceptJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"activate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"addDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"addJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addLiquidityToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"addSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addTokenCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"approveLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"approvedLiquidities\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"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\":[],\"name\":\"bondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"}],\"name\":\"bondedPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canActivateAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canWithdrawAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"changeJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"directTokenPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"dispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"firstSeen\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"forceLiquidityCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"hasBonded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"inflationPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minBond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_earned\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_age\",\"type\":\"uint256\"}],\"name\":\"isBondedKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isBondedKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"isKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobLiquidityCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobPendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobPeriodCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCreditsAddedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"jobs\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rHelper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1Proxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keepers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"liquidityAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidityMinimum\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"migrateJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"observeLiquidity\",\"outputs\":[{\"components\":[{\"internalType\":\"int56\",\"name\":\"current\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"difference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"}],\"internalType\":\"struct IKeep3rJobFundableLiquidity.TickCache\",\"name\":\"_tickCache\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingJobMigrations\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingUnbonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"quoteLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"removeDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"removeSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"resolve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"revoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"revokeLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardPeriodTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"rewardedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sendDust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"setBondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"setInflationPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"setKeep3rHelper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"setKeep3rV1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"setKeep3rV1Proxy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"setLiquidityMinimum\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"setRewardPeriodTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"setUnbondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bonded\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_bondAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_unbondAmount\",\"type\":\"uint256\"}],\"name\":\"slash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashTokenFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"slashers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"totalJobCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_credits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbondLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unbondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"virtualReserves\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"_virtualReserves\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawTokenCreditsFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workCompleted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"worked\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_usdPerGasUnit\",\"type\":\"uint256\"}],\"name\":\"worked\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptJobMigration(address,address)\":{\"details\":\"Unbond/withdraw process doesn't get migrated\",\"params\":{\"_fromJob\":\"The address of the job that requested to migrate\",\"_toJob\":\"The address to which the job wants to migrate to\"}},\"acceptJobOwnership(address)\":{\"params\":{\"_job\":\"The address of the job\"}},\"activate(address)\":{\"params\":{\"_bonding\":\"The asset being activated as bond collateral\"}},\"addJob(address)\":{\"params\":{\"_job\":\"Address of the contract for which work should be performed\"}},\"addLiquidityToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity tokens to add\",\"_job\":\"The address of the job to assign liquidity to\",\"_liquidity\":\"The liquidity being added\"}},\"addTokenCreditsToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of credit being added\",\"_job\":\"The address of the job being credited\",\"_token\":\"The address of the token being credited\"}},\"approveLiquidity(address)\":{\"details\":\"Function should be called after setting an oracle in Keep3rHelperSidechain\",\"params\":{\"_liquidity\":\"Address of the liquidity token being approved\"}},\"approvedLiquidities()\":{\"returns\":{\"_list\":\"An array of addresses with all the approved liquidity pairs\"}},\"bond(address,uint256)\":{\"params\":{\"_amount\":\"The amount of bonding asset being bonded\",\"_bonding\":\"The asset being bonded\"}},\"bondedPayment(address,uint256)\":{\"details\":\"Pays the keeper that performs the work with KP3R\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\",\"_payment\":\"The reward that should be allocated for the job\"}},\"changeJobOwnership(address,address)\":{\"params\":{\"_job\":\"The address of the job\",\"_newOwner\":\"The address of the proposed new owner\"}},\"constructor\":{\"params\":{\"_governance\":\"Address of governance\",\"_keep3rEscrow\":\"Address of sidechain Keep3rEscrow\",\"_keep3rHelperSidechain\":\"Address of sidechain Keep3rHelper\",\"_wrappedKP3R\":\"Address of wrapped KP3R implementation\"}},\"directTokenPayment(address,address,uint256)\":{\"details\":\"Pays the keeper that performs the work with a specific token\",\"params\":{\"_amount\":\"The reward that should be allocated\",\"_keeper\":\"Address of the keeper that performed the work\",\"_token\":\"The asset being awarded to the keeper\"}},\"dispute(address)\":{\"params\":{\"_jobOrKeeper\":\"The address in dispute\"}},\"forceLiquidityCreditsToJob(address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity credits to gift\",\"_job\":\"The address of the job being credited\"}},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"details\":\"Should be used for protected functions\",\"params\":{\"_age\":\"The minimum keeper age required\",\"_bond\":\"The bond token being evaluated\",\"_earned\":\"The minimum funds earned in the keepers lifetime\",\"_keeper\":\"The keeper to check\",\"_minBond\":\"The minimum amount of bonded tokens\"},\"returns\":{\"_isBondedKeeper\":\"Whether the `_keeper` meets the given requirements\"}},\"isKeeper(address)\":{\"details\":\"Can be used for general (non critical) functions\",\"params\":{\"_keeper\":\"The keeper being investigated\"},\"returns\":{\"_isKeeper\":\"Whether the address passed as a parameter is a keeper or not\"}},\"jobLiquidityCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the liquidity credits\"},\"returns\":{\"_liquidityCredits\":\"The liquidity credits of a given job\"}},\"jobPeriodCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the period credits\"},\"returns\":{\"_periodCredits\":\"The credits the given job has at the current period\"}},\"jobs()\":{\"returns\":{\"_list\":\"Array with all the jobs in _jobs\"}},\"keepers()\":{\"returns\":{\"_list\":\"Array with all the keepers in _keepers\"}},\"migrateJob(address,address)\":{\"params\":{\"_fromJob\":\"The address of the job that is requesting to migrate\",\"_toJob\":\"The address at which the job is requesting to migrate\"}},\"observeLiquidity(address)\":{\"params\":{\"_liquidity\":\"Address of the liquidity token being observed\"}},\"quoteLiquidity(address,uint256)\":{\"details\":\"_periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\",\"params\":{\"_amount\":\"The amount of liquidity to provide\",\"_liquidity\":\"The address of the liquidity to provide\"},\"returns\":{\"_periodCredits\":\"The amount of KP3R periodically minted for the given liquidity\"}},\"resolve(address)\":{\"params\":{\"_jobOrKeeper\":\"The address cleared\"}},\"revoke(address)\":{\"params\":{\"_keeper\":\"The address being slashed\"}},\"revokeLiquidity(address)\":{\"params\":{\"_liquidity\":\"The liquidity no longer accepted\"}},\"sendDust(address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of the token that will be transferred\",\"_to\":\"The address that will receive the idle funds\",\"_token\":\"The token that will be transferred\"}},\"setBondTime(uint256)\":{\"params\":{\"_bond\":\"The new bond time\"}},\"setFee(uint256)\":{\"params\":{\"_fee\":\"The new fee\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setInflationPeriod(uint256)\":{\"params\":{\"_inflationPeriod\":\"The new inflation period\"}},\"setKeep3rHelper(address)\":{\"params\":{\"_keep3rHelper\":\"The Keep3rHelper address\"}},\"setKeep3rV1(address)\":{\"params\":{\"_keep3rV1\":\"The Keep3rV1 address\"}},\"setKeep3rV1Proxy(address)\":{\"params\":{\"_keep3rV1Proxy\":\"The Keep3rV1Proxy address\"}},\"setLiquidityMinimum(uint256)\":{\"params\":{\"_liquidityMinimum\":\"The new minimum amount of liquidity\"}},\"setRewardPeriodTime(uint256)\":{\"params\":{\"_rewardPeriodTime\":\"The new amount of time required to pass between rewards\"}},\"setUnbondTime(uint256)\":{\"params\":{\"_unbond\":\"The new unbond time\"}},\"slash(address,address,uint256,uint256)\":{\"params\":{\"_bondAmount\":\"The bonded amount being slashed\",\"_bonded\":\"The asset being slashed\",\"_keeper\":\"The address being slashed\",\"_unbondAmount\":\"The pending unbond amount being slashed\"}},\"slashLiquidityFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity that will be slashed\",\"_job\":\"The address being slashed\",\"_liquidity\":\"The address of the liquidity that will be slashed\"}},\"slashTokenFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of the token that will be slashed\",\"_job\":\"The address of the job from which the token will be slashed\",\"_token\":\"The address of the token that will be slashed\"}},\"totalJobCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the total credits\"},\"returns\":{\"_credits\":\"The total credits of the given job\"}},\"unbond(address,uint256)\":{\"params\":{\"_amount\":\"Allows for partial unbonding\",\"_bonding\":\"The asset being unbonded\"}},\"unbondLiquidityFromJob(address,address,uint256)\":{\"details\":\"Can only be called by the job's owner\",\"params\":{\"_amount\":\"The amount of liquidity being removed\",\"_job\":\"The address of the job being unbonded from\",\"_liquidity\":\"The liquidity being unbonded\"}},\"virtualReserves()\":{\"returns\":{\"_virtualReserves\":\"The surplus amount of wKP3Rs in escrow contract\"}},\"withdraw(address)\":{\"params\":{\"_bonding\":\"The asset to withdraw from the bonding pool\"}},\"withdrawLiquidityFromJob(address,address,address)\":{\"params\":{\"_job\":\"The address of the job being withdrawn from\",\"_liquidity\":\"The liquidity being withdrawn\",\"_receiver\":\"The address that will receive the withdrawn liquidity\"}},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of token to be withdrawn\",\"_job\":\"The address of the job from which the credits are withdrawn\",\"_receiver\":\"The user that will receive tokens\",\"_token\":\"The address of the token being withdrawn\"}},\"worked(address)\":{\"details\":\"Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\"},\"worked(address,uint256)\":{\"details\":\"Uses a USD per gas unit payment mechanism\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\",\"_usdPerGasUnit\":\"Units of USD (in wei) per gas unit that should be rewarded to the keeper\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"AlreadyAJob()\":[{\"notice\":\"Throws when the address that is trying to register as a job is already a job\"}],\"AlreadyAKeeper()\":[{\"notice\":\"Throws when the address that is trying to register as a keeper is already a keeper\"}],\"AlreadyDisputed()\":[{\"notice\":\"Throws when a job or keeper is already disputed\"}],\"BondsLocked()\":[{\"notice\":\"Throws if the time required to bond an asset has not passed yet\"}],\"BondsUnexistent()\":[{\"notice\":\"Throws if there are no bonded assets\"}],\"Deprecated()\":[{\"notice\":\"Throws when job contract calls deprecated worked(address) function\"}],\"Disputed()\":[{\"notice\":\"Throws if either a job or a keeper is disputed\"}],\"DisputerExistent()\":[{\"notice\":\"Throws if the address is already a registered disputer\"}],\"DisputerUnexistent()\":[{\"notice\":\"Throws if caller is not a registered disputer\"}],\"GasNotInitialized()\":[{\"notice\":\"Throws if work method was called without calling isKeeper or isBondedKeeper\"}],\"InsufficientFunds()\":[{\"notice\":\"Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\"}],\"InsufficientJobTokenCredits()\":[{\"notice\":\"Throws when the user tries to withdraw more tokens than it has\"}],\"JobAlreadyAdded()\":[{\"notice\":\"Throws when trying to add a job that has already been added\"}],\"JobDisputed()\":[{\"notice\":\"Throws when an action that requires an undisputed job is applied on a disputed job\"}],\"JobLiquidityInsufficient()\":[{\"notice\":\"Throws when trying to remove more liquidity than the job has\"}],\"JobLiquidityLessThanMin()\":[{\"notice\":\"Throws when trying to add less liquidity than the minimum liquidity required\"}],\"JobLiquidityUnexistent()\":[{\"notice\":\"Throws when the job doesn't have the requested liquidity\"}],\"JobMigrationImpossible()\":[{\"notice\":\"Throws when the address of the job that requests to migrate wants to migrate to its same address\"}],\"JobMigrationLocked()\":[{\"notice\":\"Throws when cooldown between migrations has not yet passed\"}],\"JobMigrationUnavailable()\":[{\"notice\":\"Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\"}],\"JobTokenCreditsLocked()\":[{\"notice\":\"Throws when the token withdraw cooldown has not yet passed\"}],\"JobTokenInsufficient()\":[{\"notice\":\"Throws when someone tries to slash more tokens than the job has\"}],\"JobTokenUnexistent()\":[{\"notice\":\"Throws when the token trying to be slashed doesn't exist\"}],\"JobUnapproved()\":[{\"notice\":\"Throws if the address claiming to be a job is not in the list of approved jobs\"}],\"JobUnavailable()\":[{\"notice\":\"Throws when an address is passed as a job, but that address is not a job\"}],\"LiquidityPairApproved()\":[{\"notice\":\"Throws when the liquidity being approved has already been approved\"}],\"LiquidityPairUnapproved()\":[{\"notice\":\"Throws when trying to add liquidity to an unapproved pool\"}],\"LiquidityPairUnexistent()\":[{\"notice\":\"Throws when the liquidity being removed has not been approved\"}],\"MinRewardPeriod()\":[{\"notice\":\"Throws if the reward period is less than the minimum reward period time\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"NotDisputed()\":[{\"notice\":\"Throws when a job or keeper is not disputed and someone tries to resolve the dispute\"}],\"OnlyDisputer()\":[{\"notice\":\"Throws if the msg.sender is not a disputer or is not a part of governance\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the job owner\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"OnlyPendingJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the pending job owner\"}],\"OnlySlasher()\":[{\"notice\":\"Throws if the msg.sender is not a slasher or is not a part of governance\"}],\"SlasherExistent()\":[{\"notice\":\"Throws if the address is already a registered slasher\"}],\"SlasherUnexistent()\":[{\"notice\":\"Throws if caller is not a registered slasher\"}],\"TokenUnallowed()\":[{\"notice\":\"Throws when the token is KP3R, as it should not be used for direct token payments\"}],\"UnbondsLocked()\":[{\"notice\":\"Throws if the time required to withdraw the bonds has not passed yet\"}],\"UnbondsUnexistent()\":[{\"notice\":\"Throws if there are no bonds to withdraw\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"Activation(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#activate is called\"},\"BondTimeChange(uint256)\":{\"notice\":\"Emitted when bondTime is changed\"},\"Bonding(address,address,uint256)\":{\"notice\":\"Emitted when the bonding process of a new keeper begins\"},\"Dispute(address,address)\":{\"notice\":\"Emitted when a keeper or a job is disputed\"},\"DisputerAdded(address)\":{\"notice\":\"Emitted when a disputer is added\"},\"DisputerRemoved(address)\":{\"notice\":\"Emitted when a disputer is removed\"},\"DustSent(address,uint256,address)\":{\"notice\":\"Emitted when dust is sent\"},\"FeeChange(uint256)\":{\"notice\":\"Emitted when the fee is changed\"},\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"InflationPeriodChange(uint256)\":{\"notice\":\"Emitted when the inflationPeriod is changed\"},\"JobAddition(address,address)\":{\"notice\":\"Emitted when Keep3rJobManager#addJob is called\"},\"JobMigrationRequested(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#migrateJob function is called\"},\"JobMigrationSuccessful(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#acceptJobMigration function is called\"},\"JobOwnershipAssent(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\"},\"JobOwnershipChange(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#changeJobOwnership is called\"},\"JobSlashLiquidity(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\"},\"JobSlashToken(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashTokenFromJob is called\"},\"Keep3rHelperChange(address)\":{\"notice\":\"Emitted when the Keep3rHelper address is changed\"},\"Keep3rV1Change(address)\":{\"notice\":\"Emitted when the Keep3rV1 address is changed\"},\"Keep3rV1ProxyChange(address)\":{\"notice\":\"Emitted when the Keep3rV1Proxy address is changed\"},\"KeeperRevoke(address,address)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#revoke is called\"},\"KeeperSlash(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#slash is called\"},\"KeeperValidation(uint256)\":{\"notice\":\"Emitted when a keeper is validated before a job\"},\"KeeperWork(address,address,address,uint256,uint256)\":{\"notice\":\"Emitted when a keeper works a job\"},\"LiquidityAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityApproval(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\"},\"LiquidityCreditsForced(address,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\"},\"LiquidityCreditsReward(address,uint256,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityMinimumChange(uint256)\":{\"notice\":\"Emitted when _liquidityMinimum is changed\"},\"LiquidityRevocation(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\"},\"LiquidityWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\"},\"Resolve(address,address)\":{\"notice\":\"Emitted when a dispute is resolved\"},\"RewardPeriodTimeChange(uint256)\":{\"notice\":\"Emitted when _rewardPeriodTime is changed\"},\"SlasherAdded(address)\":{\"notice\":\"Emitted when a slasher is added\"},\"SlasherRemoved(address)\":{\"notice\":\"Emitted when a slasher is removed\"},\"TokenCreditAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\"},\"TokenCreditWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\"},\"UnbondTimeChange(uint256)\":{\"notice\":\"Emitted when _unbondTime is changed\"},\"Unbonding(address,address,uint256)\":{\"notice\":\"Emitted when a keeper or job begins the unbonding process to withdraw the funds\"},\"Withdrawal(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#withdraw is called\"}},\"kind\":\"user\",\"methods\":{\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"acceptJobMigration(address,address)\":{\"notice\":\"Completes the migration process for a job\"},\"acceptJobOwnership(address)\":{\"notice\":\"The proposed address accepts to be the owner of the job\"},\"activate(address)\":{\"notice\":\"End of the bonding process after bonding time has passed\"},\"addDisputer(address)\":{\"notice\":\"Registers a disputer by updating the disputers mapping\"},\"addJob(address)\":{\"notice\":\"Allows any caller to add a new job\"},\"addLiquidityToJob(address,address,uint256)\":{\"notice\":\"Allows anyone to fund a job with liquidity\"},\"addSlasher(address)\":{\"notice\":\"Registers a slasher by updating the slashers mapping\"},\"addTokenCreditsToJob(address,address,uint256)\":{\"notice\":\"Add credit to a job to be paid out for work\"},\"approveLiquidity(address)\":{\"notice\":\"Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\"},\"approvedLiquidities()\":{\"notice\":\"Lists liquidity pairs\"},\"bond(address,uint256)\":{\"notice\":\"Beginning of the bonding process\"},\"bondTime()\":{\"notice\":\"The amount of time required to pass after a keeper has bonded assets for it to be able to activate\"},\"bondedPayment(address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"bonds(address,address)\":{\"notice\":\"Mapping (job => bonding => amount)\"},\"canActivateAfter(address,address)\":{\"notice\":\"Tracks when a bonding for a keeper can be activated\"},\"canWithdrawAfter(address,address)\":{\"notice\":\"Tracks when keeper bonds are ready to be withdrawn\"},\"changeJobOwnership(address,address)\":{\"notice\":\"Proposes a new address to be the owner of the job\"},\"directTokenPayment(address,address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"dispute(address)\":{\"notice\":\"Allows governance to create a dispute for a given keeper/job\"},\"disputers(address)\":{\"notice\":\"Tracks whether the address is a disputer or not\"},\"disputes(address)\":{\"notice\":\"Tracks if a keeper or job has a pending dispute\"},\"fee()\":{\"notice\":\"The fee to be sent to governance when a user adds liquidity to a job\"},\"firstSeen(address)\":{\"notice\":\"Tracks when a keeper was first registered\"},\"forceLiquidityCreditsToJob(address,uint256)\":{\"notice\":\"Gifts liquidity credits to the specified job\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"hasBonded(address)\":{\"notice\":\"Checks whether the address has ever bonded an asset\"},\"inflationPeriod()\":{\"notice\":\"The inflation period is the denominator used to regulate the emission of KP3R\"},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"notice\":\"Confirms if the current keeper is registered and has a minimum bond of any asset.\"},\"isKeeper(address)\":{\"notice\":\"Confirms if the current keeper is registered\"},\"jobLiquidityCredits(address)\":{\"notice\":\"Returns the liquidity credits of a given job\"},\"jobOwner(address)\":{\"notice\":\"Maps the job to the owner of the job\"},\"jobPendingOwner(address)\":{\"notice\":\"Maps the job to its pending owner\"},\"jobPeriodCredits(address)\":{\"notice\":\"Returns the credits of a given job for the current period\"},\"jobTokenCredits(address,address)\":{\"notice\":\"The current token credits available for a job\"},\"jobTokenCreditsAddedAt(address,address)\":{\"notice\":\"Last block where tokens were added to the job\"},\"jobs()\":{\"notice\":\"Lists all jobs\"},\"keep3rHelper()\":{\"notice\":\"Address of Keep3rHelper's contract\"},\"keep3rV1()\":{\"notice\":\"Address of Keep3rV1's contract\"},\"keep3rV1Proxy()\":{\"notice\":\"Address of Keep3rV1Proxy's contract\"},\"keepers()\":{\"notice\":\"Lists all keepers\"},\"liquidityAmount(address,address)\":{\"notice\":\"Amount of liquidity in a specified job\"},\"liquidityMinimum()\":{\"notice\":\"The minimum amount of liquidity required to fund a job per liquidity\"},\"migrateJob(address,address)\":{\"notice\":\"Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\"},\"observeLiquidity(address)\":{\"notice\":\"Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\"},\"pendingBonds(address,address)\":{\"notice\":\"Tracks the amount of assets deposited in pending bonds\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"pendingJobMigrations(address)\":{\"notice\":\"Maps the jobs that have requested a migration to the address they have requested to migrate to\"},\"pendingUnbonds(address,address)\":{\"notice\":\"Tracks how much keeper bonds are to be withdrawn\"},\"quoteLiquidity(address,uint256)\":{\"notice\":\"Calculates how many credits should be rewarded periodically for a given liquidity amount\"},\"removeDisputer(address)\":{\"notice\":\"Removes a disputer by updating the disputers mapping\"},\"removeSlasher(address)\":{\"notice\":\"Removes a slasher by updating the slashers mapping\"},\"resolve(address)\":{\"notice\":\"Allows governance to resolve a dispute on a keeper/job\"},\"revoke(address)\":{\"notice\":\"Blacklists a keeper from participating in the network\"},\"revokeLiquidity(address)\":{\"notice\":\"Revoke a liquidity pair from being accepted in future\"},\"rewardPeriodTime()\":{\"notice\":\"The amount of time between each scheduled credits reward given to a job\"},\"rewardedAt(address)\":{\"notice\":\"Last time the job was rewarded liquidity credits\"},\"sendDust(address,uint256,address)\":{\"notice\":\"Allows an authorized user to transfer the tokens or eth that may have been left in a contract\"},\"setBondTime(uint256)\":{\"notice\":\"Sets the bond time required to activate as a keeper\"},\"setFee(uint256)\":{\"notice\":\"Sets the new fee\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setInflationPeriod(uint256)\":{\"notice\":\"Sets the new inflation period\"},\"setKeep3rHelper(address)\":{\"notice\":\"Sets the Keep3rHelper address\"},\"setKeep3rV1(address)\":{\"notice\":\"Sets the Keep3rV1 address\"},\"setKeep3rV1Proxy(address)\":{\"notice\":\"Sets the Keep3rV1Proxy address\"},\"setLiquidityMinimum(uint256)\":{\"notice\":\"Sets the minimum amount of liquidity required to fund a job\"},\"setRewardPeriodTime(uint256)\":{\"notice\":\"Sets the time required to pass between rewards for jobs\"},\"setUnbondTime(uint256)\":{\"notice\":\"Sets the unbond time required unbond what has been bonded\"},\"slash(address,address,uint256,uint256)\":{\"notice\":\"Allows governance to slash a keeper based on a dispute\"},\"slashLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Allows governance or a slasher to slash liquidity from a job\"},\"slashTokenFromJob(address,address,uint256)\":{\"notice\":\"Allows governance or slasher to slash a job specific token\"},\"slashers(address)\":{\"notice\":\"Tracks whether the address is a slasher or not\"},\"totalBonds()\":{\"notice\":\"Tracks the total amount of bonded KP3Rs in the contract\"},\"totalJobCredits(address)\":{\"notice\":\"Calculates the total credits of a given job\"},\"unbond(address,uint256)\":{\"notice\":\"Beginning of the unbonding process\"},\"unbondLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Unbond liquidity for a job\"},\"unbondTime()\":{\"notice\":\"The amount of time required to pass before a keeper can unbond what he has bonded\"},\"virtualReserves()\":{\"notice\":\"The surplus amount of wKP3Rs in escrow contract\"},\"withdraw(address)\":{\"notice\":\"Withdraw funds after unbonding has finished\"},\"withdrawLiquidityFromJob(address,address,address)\":{\"notice\":\"Withdraw liquidity from a job\"},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"notice\":\"Withdraw credit from a job\"},\"workCompleted(address)\":{\"notice\":\"Tracks the total KP3R earnings of a keeper since it started working\"},\"worked(address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"workedAt(address)\":{\"notice\":\"Last time the job was worked\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/sidechain/Keep3rSidechain.sol\":\"Keep3rSidechain\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"solidity/contracts/Keep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../interfaces/IKeep3r.sol';\\nimport './peripherals/jobs/Keep3rJobs.sol';\\nimport './peripherals/keepers/Keep3rKeepers.sol';\\nimport './peripherals/DustCollector.sol';\\n\\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\\n constructor(\\n address _governance,\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\\n}\\n\",\"keccak256\":\"0x8b7a11409585a734b97d64773753921ea64b17ea6ee45d712d0478898990a8b0\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/DustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '../../contracts/peripherals/Governable.sol';\\nimport '../../interfaces/peripherals/IDustCollector.sol';\\n\\nabstract contract DustCollector is IDustCollector, Governable {\\n using SafeERC20 for IERC20;\\n\\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external override onlyGovernance {\\n if (_to == address(0)) revert ZeroAddress();\\n if (_token == _ETH_ADDRESS) {\\n payable(_to).transfer(_amount);\\n } else {\\n IERC20(_token).safeTransfer(_to, _amount);\\n }\\n emit DustSent(_token, _amount, _to);\\n }\\n}\\n\",\"keccak256\":\"0x246ac2c4057520bb627ea8040367549786f4477a04fd79358927cd607952bc2f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\\nimport './Keep3rRoles.sol';\\n\\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @notice List of all enabled keepers\\n EnumerableSet.AddressSet internal _keepers;\\n\\n /// @inheritdoc IKeep3rAccountance\\n uint256 public override totalBonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override workCompleted;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override firstSeen;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override disputes;\\n\\n /// @inheritdoc IKeep3rAccountance\\n /// @notice Mapping (job => bonding => amount)\\n mapping(address => mapping(address => uint256)) public override bonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\\n\\n /// @notice The current liquidity credits available for a job\\n mapping(address => uint256) internal _jobLiquidityCredits;\\n\\n /// @notice Map the address of a job to its correspondent periodCredits\\n mapping(address => uint256) internal _jobPeriodCredits;\\n\\n /// @notice Enumerable array of Job Tokens for Credits\\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\\n\\n /// @notice List of liquidities that a job has (job => liquidities)\\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\\n\\n /// @notice Liquidity pool to observe\\n mapping(address => address) internal _liquidityPool;\\n\\n /// @notice Tracks if a pool has KP3R as token0\\n mapping(address => bool) internal _isKP3RToken0;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingBonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override hasBonded;\\n\\n /// @notice List of all enabled jobs\\n EnumerableSet.AddressSet internal _jobs;\\n\\n /// @inheritdoc IKeep3rAccountance\\n function jobs() external view override returns (address[] memory _list) {\\n _list = _jobs.values();\\n }\\n\\n /// @inheritdoc IKeep3rAccountance\\n function keepers() external view override returns (address[] memory _list) {\\n _list = _keepers.values();\\n }\\n}\\n\",\"keccak256\":\"0xcd2a525e6567eea4f2a7f93e8eb686e484d2a078686f2744dde35a8383881730\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rParameters.sol';\\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\\n\\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\\n /// @inheritdoc IKeep3rDisputable\\n function dispute(address _jobOrKeeper) external override onlyDisputer {\\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\\n disputes[_jobOrKeeper] = true;\\n emit Dispute(_jobOrKeeper, msg.sender);\\n }\\n\\n /// @inheritdoc IKeep3rDisputable\\n function resolve(address _jobOrKeeper) external override onlyDisputer {\\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\\n disputes[_jobOrKeeper] = false;\\n emit Resolve(_jobOrKeeper, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x664b54040aa4e734f68a01fcfb5bf67cbb1a70efd03862cd3a456457536b1fb4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/IKeep3rHelper.sol';\\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\\nimport './Keep3rAccountance.sol';\\n\\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1Proxy;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rHelper;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override bondTime = 3 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override unbondTime = 14 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override liquidityMinimum = 3 ether;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override rewardPeriodTime = 5 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override inflationPeriod = 34 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override fee = 30;\\n\\n /// @notice The base that will be used to calculate the fee\\n uint256 internal constant _BASE = 10_000;\\n\\n /// @notice The minimum reward period\\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\\n\\n constructor(\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) {\\n keep3rHelper = _keep3rHelper;\\n keep3rV1 = _keep3rV1;\\n keep3rV1Proxy = _keep3rV1Proxy;\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\\n if (_keep3rHelper == address(0)) revert ZeroAddress();\\n keep3rHelper = _keep3rHelper;\\n emit Keep3rHelperChange(_keep3rHelper);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\\n if (_keep3rV1 == address(0)) revert ZeroAddress();\\n _mint(totalBonds);\\n\\n keep3rV1 = _keep3rV1;\\n emit Keep3rV1Change(_keep3rV1);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\\n keep3rV1Proxy = _keep3rV1Proxy;\\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\\n bondTime = _bondTime;\\n emit BondTimeChange(_bondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\\n unbondTime = _unbondTime;\\n emit UnbondTimeChange(_unbondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\\n liquidityMinimum = _liquidityMinimum;\\n emit LiquidityMinimumChange(_liquidityMinimum);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\\n rewardPeriodTime = _rewardPeriodTime;\\n emit RewardPeriodTimeChange(_rewardPeriodTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\\n inflationPeriod = _inflationPeriod;\\n emit InflationPeriodChange(_inflationPeriod);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setFee(uint256 _fee) external override onlyGovernance {\\n fee = _fee;\\n emit FeeChange(_fee);\\n }\\n\\n function _mint(uint256 _amount) internal {\\n totalBonds -= _amount;\\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\\n }\\n}\\n\",\"keccak256\":\"0x180349c0ff1fffec1566fba13b494595dcc5ca7eaf049d3f7a2a8d1c60de7d0f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport './DustCollector.sol';\\nimport './Governable.sol';\\n\\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override slashers;\\n\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override disputers;\\n\\n constructor(address _governance) Governable(_governance) DustCollector() {}\\n\\n /// @inheritdoc IKeep3rRoles\\n function addSlasher(address _slasher) external override onlyGovernance {\\n if (_slasher == address(0)) revert ZeroAddress();\\n if (slashers[_slasher]) revert SlasherExistent();\\n slashers[_slasher] = true;\\n emit SlasherAdded(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeSlasher(address _slasher) external override onlyGovernance {\\n if (!slashers[_slasher]) revert SlasherUnexistent();\\n delete slashers[_slasher];\\n emit SlasherRemoved(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function addDisputer(address _disputer) external override onlyGovernance {\\n if (_disputer == address(0)) revert ZeroAddress();\\n if (disputers[_disputer]) revert DisputerExistent();\\n disputers[_disputer] = true;\\n emit DisputerAdded(_disputer);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeDisputer(address _disputer) external override onlyGovernance {\\n if (!disputers[_disputer]) revert DisputerUnexistent();\\n delete disputers[_disputer];\\n emit DisputerRemoved(_disputer);\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a slasher or governance\\n modifier onlySlasher {\\n if (!slashers[msg.sender]) revert OnlySlasher();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a disputer or governance\\n modifier onlyDisputer {\\n if (!disputers[msg.sender]) revert OnlyDisputer();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x61a1cf0d52db8fe78fa8cfb76d9b02f93ef3adc23e6655969bc1a4bb83ea9a95\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\nimport '../Keep3rDisputable.sol';\\n\\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\\n\\n try IERC20(_token).transfer(governance, _amount) {} catch {}\\n jobTokenCredits[_job][_token] -= _amount;\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit JobSlashToken(_job, _token, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x86cdbf44dfa46c6b6e184e48e11cb8571e26cf50c793b6b07227c29e743da397\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice Cooldown between withdrawals\\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n // KP3R shouldn't be used for direct token payments\\n if (_token == keep3rV1) revert TokenUnallowed();\\n uint256 _before = IERC20(_token).balanceOf(address(this));\\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\\n uint256 _tokenFee = (_received * fee) / _BASE;\\n jobTokenCredits[_job][_token] += _received - _tokenFee;\\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\\n IERC20(_token).safeTransfer(governance, _tokenFee);\\n _jobTokens[_job].add(_token);\\n\\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external override nonReentrant onlyJobOwner(_job) {\\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\\n if (disputes[_job]) revert JobDisputed();\\n\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xb600d18903a008a1ca03743de7cef8330c2d5e66db52c900822551a4be75f7a5\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/IPairManager.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '../../libraries/FullMath.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice List of liquidities that are accepted in the system\\n EnumerableSet.AddressSet internal _approvedLiquidities;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override rewardedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override workedAt;\\n\\n /// @notice Tracks an address and returns its TickCache\\n mapping(address => TickCache) internal _tick;\\n\\n // Views\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approvedLiquidities() external view override returns (address[] memory _list) {\\n _list = _approvedLiquidities.values();\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n _periodCredits += _getReward(\\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\\n );\\n }\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n\\n // If the job was rewarded in the past 1 period time\\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\\n // If the job has period credits, update minted job credits to new twap\\n _liquidityCredits = _periodCredits > 0\\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\\n } else {\\n // Else return a full period worth of credits if current credits have expired\\n _liquidityCredits = _periodCredits;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n uint256 _cooldown = block.timestamp;\\n\\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\\n // Will calculate cooldown if it outdated\\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will calculate cooldown from last reward reference in this period\\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\\n } else {\\n // Will calculate cooldown from last reward timestamp\\n _cooldown -= rewardedAt[_job];\\n }\\n } else {\\n // Will calculate cooldown from period start if expired\\n _cooldown -= _period(block.timestamp);\\n }\\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\\n if (_tick[_liquidity].period == _period(block.timestamp)) {\\n // Will return cached twaps if liquidity is updated\\n _tickCache = _tick[_liquidity];\\n } else {\\n bool success;\\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\\n\\n if (_tick[_liquidity].period == lastPeriod) {\\n // Will only ask for current period accumulator if liquidity is outdated\\n uint32[] memory _secondsAgo = new uint32[](1);\\n int56 previousTick = _tick[_liquidity].current;\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n\\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - previousTick;\\n } else if (_tick[_liquidity].period < lastPeriod) {\\n // Will ask for 2 accumulators if liquidity is expired\\n uint32[] memory _secondsAgo = new uint32[](2);\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\\n\\n int56 _tickCumulative2;\\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - _tickCumulative2;\\n }\\n if (success) {\\n _tickCache.period = _period(block.timestamp);\\n } else {\\n delete _tickCache.period;\\n }\\n }\\n }\\n\\n // Methods\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n _settleJobAccountance(_job);\\n _jobLiquidityCredits[_job] += _amount;\\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n emit LiquidityApproval(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\\n delete _liquidityPool[_liquidity];\\n delete _isKP3RToken0[_liquidity];\\n delete _tick[_liquidity];\\n\\n emit LiquidityRevocation(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n\\n _jobLiquidities[_job].add(_liquidity);\\n\\n _settleJobAccountance(_job);\\n\\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\\n liquidityAmount[_job][_liquidity] += _amount;\\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlyJobOwner(_job) {\\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\\n pendingUnbonds[_job][_liquidity] += _amount;\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n\\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit Unbonding(_job, _liquidity, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external override onlyJobOwner(_job) {\\n if (_receiver == address(0)) revert ZeroAddress();\\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[_job]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[_job][_liquidity];\\n\\n delete pendingUnbonds[_job][_liquidity];\\n delete canWithdrawAfter[_job][_liquidity];\\n\\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\\n }\\n\\n // Internal functions\\n\\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\\n if (rewardedAt[_job] < _period(block.timestamp)) {\\n // Will exit function if job has been rewarded in current period\\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\\n // Will reset job to period syncronicity if a full period passed without rewards\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] = _period(block.timestamp);\\n _rewarded = true;\\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will reset job's syncronicity if last reward was more than epoch ago\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] += rewardPeriodTime;\\n _rewarded = true;\\n } else if (workedAt[_job] < _period(block.timestamp)) {\\n // First keeper on period has to update job accountance to current twaps\\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\\n // Updating job accountance does not reward job\\n }\\n }\\n }\\n\\n /// @notice Only called if _jobLiquidityCredits < payment\\n function _rewardJobCredits(address _job) internal {\\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\\n rewardedAt[_job] = block.timestamp;\\n }\\n\\n /// @notice Updates accountance for _jobPeriodCredits\\n function _updateJobPeriod(address _job) internal {\\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\\n }\\n\\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n if (_tick[_liquidity].period != _period(block.timestamp)) {\\n // Updates liquidity cache only if needed\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n }\\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\\n }\\n }\\n }\\n\\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\\n function _unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) internal nonReentrant {\\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\\n\\n // Ensures current twaps in job liquidities\\n _updateJobPeriod(_job);\\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\\n\\n // A liquidity can be revoked causing a job to have 0 periodCredits\\n if (_jobPeriodCredits[_job] > 0) {\\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\\n }\\n\\n liquidityAmount[_job][_liquidity] -= _amount;\\n if (liquidityAmount[_job][_liquidity] == 0) {\\n _jobLiquidities[_job].remove(_liquidity);\\n }\\n }\\n\\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\\n if (_timePassed < rewardPeriodTime) {\\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\\n } else _result = _multiplier;\\n }\\n\\n /// @notice Returns the start of the period of the provided timestamp\\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\\n return _timestamp - (_timestamp % rewardPeriodTime);\\n }\\n\\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\\n }\\n\\n /// @notice Returns underlying KP3R amount for a given liquidity amount\\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\\n if (_tick[_liquidity].period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\\n }\\n }\\n\\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\\n /// @dev Ensures a maximum of 1 period of credits\\n function _settleJobAccountance(address _job) internal virtual {\\n _updateJobCreditsIfNeeded(_job);\\n _rewardJobCredits(_job);\\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n}\\n\",\"keccak256\":\"0xe3b244460364baf1ea293db6f6feba8365fd376320ad77ae6d6813ed65b52929\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @inheritdoc IKeep3rJobManager\\n function addJob(address _job) external override {\\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\\n if (hasBonded[_job]) revert AlreadyAKeeper();\\n _jobs.add(_job);\\n jobOwner[_job] = msg.sender;\\n emit JobAddition(_job, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xf6e1577a6a34b674ca34a6d7530dc81349e3ad13d321281c37e0b25b7325d013\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\n\\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n mapping(address => address) public override pendingJobMigrations;\\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\\n if (_fromJob == _toJob) revert JobMigrationImpossible();\\n\\n pendingJobMigrations[_fromJob] = _toJob;\\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\\n\\n emit JobMigrationRequested(_fromJob, _toJob);\\n }\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\\n\\n // force job credits update for both jobs\\n _settleJobAccountance(_fromJob);\\n _settleJobAccountance(_toJob);\\n\\n // migrate tokens\\n while (_jobTokens[_fromJob].length() > 0) {\\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\\n _jobTokens[_fromJob].remove(_tokenToMigrate);\\n _jobTokens[_toJob].add(_tokenToMigrate);\\n }\\n\\n // migrate liquidities\\n while (_jobLiquidities[_fromJob].length() > 0) {\\n address _liquidity = _jobLiquidities[_fromJob].at(0);\\n\\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\\n delete liquidityAmount[_fromJob][_liquidity];\\n\\n _jobLiquidities[_toJob].add(_liquidity);\\n _jobLiquidities[_fromJob].remove(_liquidity);\\n }\\n\\n // migrate job balances\\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\\n delete _jobPeriodCredits[_fromJob];\\n\\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\\n delete _jobLiquidityCredits[_fromJob];\\n\\n // stop _fromJob from being a job\\n delete rewardedAt[_fromJob];\\n _jobs.remove(_fromJob);\\n\\n // delete unused data slots\\n delete jobOwner[_fromJob];\\n delete jobPendingOwner[_fromJob];\\n delete _migrationCreatedAt[_fromJob][_toJob];\\n delete pendingJobMigrations[_fromJob];\\n\\n emit JobMigrationSuccessful(_fromJob, _toJob);\\n }\\n}\\n\",\"keccak256\":\"0xd46c3c9ce970098d8d75f11966894a341824aceb40583fcfbbc0ebda93d869f9\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobPendingOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\\n jobPendingOwner[_job] = _newOwner;\\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\\n }\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\\n address _previousOwner = jobOwner[_job];\\n\\n jobOwner[_job] = jobPendingOwner[_job];\\n delete jobPendingOwner[_job];\\n\\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\\n }\\n\\n modifier onlyJobOwner(address _job) {\\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\\n _;\\n }\\n\\n modifier onlyPendingJobOwner(address _job) {\\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xa837590ade9cd5d25690e3f2d8b9a63e7202f7179b32e42eab4fa4c4324b9728\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobMigration.sol';\\nimport '../../../interfaces/IKeep3rHelper.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n uint256 internal _initialGas;\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\\n _initialGas = _getGasLeft();\\n if (_keepers.contains(_keeper)) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external override returns (bool _isBondedKeeper) {\\n _initialGas = _getGasLeft();\\n if (\\n _keepers.contains(_keeper) &&\\n bonds[_keeper][_bond] >= _minBond &&\\n workCompleted[_keeper] >= _earned &&\\n block.timestamp - firstSeen[_keeper] >= _age\\n ) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function worked(address _keeper) external virtual override {\\n if (_initialGas == 0) revert GasNotInitialized();\\n address _job = msg.sender;\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\\n\\n uint256 _gasLeft = _getGasLeft();\\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n _gasLeft = _getGasLeft();\\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n delete _initialGas;\\n\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function bondedPayment(address _keeper, uint256 _payment) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (disputes[_keeper]) revert Disputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_keeper, _amount);\\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\\n }\\n\\n function _bondedPayment(\\n address _job,\\n address _keeper,\\n uint256 _payment\\n ) internal {\\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\\n\\n workedAt[_job] = block.timestamp;\\n _jobLiquidityCredits[_job] -= _payment;\\n bonds[_keeper][keep3rV1] += _payment;\\n workCompleted[_keeper] += _payment;\\n totalBonds += _payment;\\n }\\n\\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\\n /// @param _gasLeft Amount of gas left after working the job\\n /// @param _extraGas Amount of expected unaccounted gas\\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\\n /// @return _payment Amount to be payed in KP3R tokens\\n function _calculatePayment(\\n uint256 _gasLeft,\\n uint256 _extraGas,\\n uint256 _oneEthQuote,\\n uint256 _boost\\n ) internal view returns (uint256 _payment) {\\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\\n }\\n\\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\\n _gasLeft = (gasleft() * 64) / 63;\\n }\\n}\\n\",\"keccak256\":\"0x7e113a0815d9125e760ee75c9d9c55fc93192ae2535afccdb8835984d17b510f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobManager.sol';\\nimport './Keep3rJobWorkable.sol';\\nimport './Keep3rJobDisputable.sol';\\n\\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\\n\",\"keccak256\":\"0x882e1a19891795de04c4c891dc58d50034ca0a32c8b61651aaf0f47d0bc321d4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rKeeperFundable.sol';\\nimport '../Keep3rDisputable.sol';\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function revoke(address _keeper) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _keepers.remove(_keeper);\\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\\n emit KeeperRevoke(_keeper, msg.sender);\\n }\\n\\n function _slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) internal {\\n if (_bonded != keep3rV1) {\\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\\n }\\n bonds[_keeper][_bonded] -= _bondAmount;\\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\\n }\\n}\\n\",\"keccak256\":\"0xa15b13218af4331d1fb3e8cfdfa9b69117f291ac9a462ede6b1b4fb5be8967de\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\\n if (disputes[msg.sender]) revert Disputed();\\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\\n\\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\\n\\n hasBonded[msg.sender] = true;\\n pendingBonds[msg.sender][_bonding] += _amount;\\n\\n emit Bonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function activate(address _bonding) external override {\\n address _keeper = msg.sender;\\n if (disputes[_keeper]) revert Disputed();\\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\\n if (_canActivateAfter == 0) revert BondsUnexistent();\\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\\n\\n if (firstSeen[_keeper] == 0) {\\n firstSeen[_keeper] = block.timestamp;\\n }\\n _keepers.add(_keeper);\\n\\n uint256 _amount = pendingBonds[_keeper][_bonding];\\n delete pendingBonds[_keeper][_bonding];\\n\\n // bond provided tokens\\n bonds[_keeper][_bonding] += _amount;\\n if (_bonding == keep3rV1) {\\n totalBonds += _amount;\\n _depositBonds(_amount);\\n }\\n\\n emit Activation(_keeper, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function unbond(address _bonding, uint256 _amount) external override {\\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\\n bonds[msg.sender][_bonding] -= _amount;\\n pendingUnbonds[msg.sender][_bonding] += _amount;\\n\\n emit Unbonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function withdraw(address _bonding) external override nonReentrant {\\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[msg.sender]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\\n\\n delete pendingUnbonds[msg.sender][_bonding];\\n delete canWithdrawAfter[msg.sender][_bonding];\\n\\n if (_bonding == keep3rV1) _mint(_amount);\\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\\n\\n emit Withdrawal(msg.sender, _bonding, _amount);\\n }\\n\\n function _depositBonds(uint256 _amount) internal virtual {\\n IKeep3rV1(keep3rV1).burn(_amount);\\n }\\n}\\n\",\"keccak256\":\"0x121dc11fa555731679912d54da3bb8282d26ad425deffae6d4d7085ef3c9290d\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\nimport './Keep3rKeeperDisputable.sol';\\n\\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\\n\",\"keccak256\":\"0xfc762d9fd6ff478acba446c3ab6fc19c7d49a85de097dc35f02c56e928153c5e\",\"license\":\"MIT\"},\"solidity/contracts/sidechain/Keep3rSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3r.sol';\\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\\n\\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @param _governance Address of governance\\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\\n constructor(\\n address _governance, // governance\\n address _keep3rHelperSidechain, // helper\\n address _wrappedKP3R, // keep3rV1\\n address _keep3rEscrow // keep3rV1Proxy\\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\\n\\n // Keep3rSidechainAccountance\\n\\n /// @inheritdoc IKeep3rSidechainAccountance\\n function virtualReserves() external view override returns (int256 _virtualReserves) {\\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\\n }\\n\\n // Keep3rJobFundableLiquidity\\n\\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\\n /// @param _liquidity Address of the liquidity token being approved\\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n emit LiquidityApproval(_liquidity);\\n }\\n\\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\\n /// @param _liquidity Address of the liquidity token being observed\\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\\n if (_tick[_liquidity].period == _period(block.timestamp)) {\\n // Will return cached twaps if liquidity is updated\\n _tickCache = _tick[_liquidity];\\n } else {\\n bool success;\\n\\n // Will always ask for 2 accumulators in sidechain\\n uint32[] memory _secondsAgo = new uint32[](2);\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\\n\\n int56 _tickCumulative2;\\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - _tickCumulative2;\\n\\n if (success) {\\n _tickCache.period = _period(block.timestamp);\\n } else {\\n delete _tickCache.period;\\n }\\n }\\n }\\n\\n // Keep3rJobsWorkable\\n\\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\\n function worked(address) external pure override {\\n revert Deprecated();\\n }\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Uses a USD per gas unit payment mechanism\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\\n if (_initialGas == 0) revert GasNotInitialized();\\n // Gas used for quote calculations & payment is not rewarded\\n uint256 _gasLeft = _getGasLeft();\\n\\n address _job = msg.sender;\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\\n\\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\\n\\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n _bondedPayment(_job, _keeper, _kp3rPayment);\\n delete _initialGas;\\n\\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\\n }\\n\\n // Keep3rKeeperFundable\\n\\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\\n function _depositBonds(uint256 _amount) internal virtual override {\\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\\n }\\n}\\n\",\"keccak256\":\"0xb4328c0c7e3e22fcc617e6f52bef0f8499abde7f6b4d305a205b92940b72a518\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct TokenOraclePool {\\n address poolAddress;\\n bool isTKNToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0x76f99ca04361c0459fc9e99f0387ddb76da18cc470ec5bc744e7dc3bf6e9d334\",\"license\":\"MIT\"},\"solidity/interfaces/IPairManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n/// @title Pair Manager interface\\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\\ninterface IPairManager is IERC20Metadata {\\n /// @notice Address of the factory from which the pair manager was created\\n /// @return _factory The address of the PairManager Factory\\n function factory() external view returns (address _factory);\\n\\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\\n /// @return _pool The address of the pool\\n function pool() external view returns (address _pool);\\n\\n /// @notice Token0 of the pool\\n /// @return _token0 The address of token0\\n function token0() external view returns (address _token0);\\n\\n /// @notice Token1 of the pool\\n /// @return _token1 The address of token1\\n function token1() external view returns (address _token1);\\n}\\n\",\"keccak256\":\"0x345c312b340c5775fb8f68d89ce851c7f75522940bd9bc64f2301a3f8312636a\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IGovernable.sol';\\n\\ninterface IKeep3rV1Proxy is IGovernable {\\n // Structs\\n struct Recipient {\\n address recipient;\\n uint256 caps;\\n }\\n\\n // Variables\\n function keep3rV1() external view returns (address);\\n\\n function minter() external view returns (address);\\n\\n function next(address) external view returns (uint256);\\n\\n function caps(address) external view returns (uint256);\\n\\n function recipients() external view returns (address[] memory);\\n\\n function recipientsCaps() external view returns (Recipient[] memory);\\n\\n // Errors\\n error Cooldown();\\n error NoDrawableAmount();\\n error ZeroAddress();\\n error OnlyMinter();\\n\\n // Methods\\n function addRecipient(address recipient, uint256 amount) external;\\n\\n function removeRecipient(address recipient) external;\\n\\n function draw() external returns (uint256 _amount);\\n\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n function setMinter(address _minter) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function mint(address _account, uint256 _amount) external;\\n\\n function setKeep3rV1Governance(address _governance) external;\\n\\n function acceptKeep3rV1Governance() external;\\n\\n function dispute(address _keeper) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function addJob(address _job) external;\\n\\n function removeJob(address _job) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n}\\n\",\"keccak256\":\"0xfb2e81fe347b39aabce849ef2d42c6df846b7ef0ed5ae952c85bbb708da99408\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0xf4748c236ddf409e45e7169c735e2fc54e627b2b3ccd189ebb438ad768f1deb1\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IMintable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IGovernable.sol';\\nimport './IBaseErrors.sol';\\n\\n/// @title Mintable contract\\n/// @notice Manages the minter role\\ninterface IMintable is IBaseErrors, IGovernable {\\n // Events\\n\\n /// @notice Emitted when governance sets a new minter\\n /// @param _minter Address of the new minter\\n event MinterSet(address _minter);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not the minter\\n error OnlyMinter();\\n\\n // Variables\\n\\n /// @notice Stores the minter address\\n /// @return _minter The minter addresss\\n function minter() external view returns (address _minter);\\n\\n // Methods\\n\\n /// @notice Sets a new address to be the minter\\n /// @param _minter The address set as the minter\\n function setMinter(address _minter) external;\\n}\\n\",\"keccak256\":\"0x255f4ed4b7c4ddf4fcff9db7524365ef734806583acca7c7912e867f110d9c81\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\nimport '../peripherals/IMintable.sol';\\n\\n/// @title Keep3rEscrow contract\\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\\ninterface IKeep3rEscrow is IMintable {\\n /// @notice Emitted when Keep3rEscrow#deposit function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _sender The address that called the function\\n /// @param _amount The amount of wKP3R the user deposited\\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#mint function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _recipient The address that will received the newly minted wKP3R\\n /// @param _amount The amount of wKP3R minted to the recipient\\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\\n /// @param _newWKP3R The address of the wKP3R contract\\n event wKP3RSet(address _newWKP3R);\\n\\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\\n error InsufficientBalance();\\n\\n /// @notice Lists the address of the wKP3R contract\\n /// @return _wKP3RAddress The address of wKP3R\\n function wKP3R() external view returns (address _wKP3RAddress);\\n\\n /// @notice Deposits wKP3R into the contract\\n /// @param _amount The amount of wKP3R to deposit\\n function deposit(uint256 _amount) external;\\n\\n /// @notice mints wKP3R to the recipient\\n /// @param _amount The amount of wKP3R to mint\\n function mint(uint256 _amount) external;\\n\\n /// @notice sets the wKP3R address\\n /// @param _wKP3R the wKP3R address\\n function setWKP3R(address _wKP3R) external;\\n}\\n\",\"keccak256\":\"0xf4796dde1afba7f50805aeae92ac0a4848525aeca8355d9b1c6b36c15cca4322\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../IKeep3rHelper.sol';\\n\\n/// @title Keep3rHelperSidechain contract\\n/// @notice Contains all the helper functions for sidechain keep3r implementations\\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\\n // Events\\n\\n /// @notice The oracle for a liquidity has been saved\\n /// @param _liquidity The address of the given liquidity\\n /// @param _oraclePool The address of the oracle pool\\n event OracleSet(address _liquidity, address _oraclePool);\\n\\n /// @notice Emitted when the WETH USD pool is changed\\n /// @param _address Address of the new WETH USD pool\\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\\n\\n /// Variables\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n /// @return _weth Address of WETH token\\n // solhint-disable func-name-mixedcase\\n function WETH() external view returns (address _weth);\\n\\n /// @return _oracle The address of the observable pool for given liquidity\\n function oracle(address _liquidity) external view returns (address _oracle);\\n\\n /// @notice WETH-USD pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice Quotes USD to ETH\\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\\n /// @param _usd The amount of USD to quote to ETH\\n /// @return _eth The resulting amount of ETH after quoting the USD\\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\\n\\n /// Methods\\n\\n /// @notice Sets an oracle for a given liquidity\\n /// @param _liquidity The address of the liquidity\\n /// @param _oracle The address of the pool used to quote the liquidity from\\n /// @dev The oracle must contain KP3R as either token0 or token1\\n function setOracle(address _liquidity, address _oracle) external;\\n\\n /// @notice Sets an oracle for querying WETH/USD quote\\n /// @param _poolAddress The address of the pool used as oracle\\n /// @dev The oracle must contain WETH as either token0 or token1\\n function setWethUsdPool(address _poolAddress) external;\\n}\\n\",\"keccak256\":\"0xb6d5459e8a47ab09a052e1acac1c28304f9f0762d20f01819559b4d39729c987\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IKeep3rJobs.sol';\\n\\n/// @title Keep3rJobWorkableRated contract\\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\\n /// @notice Throws when job contract calls deprecated worked(address) function\\n error Deprecated();\\n\\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\\n}\\n\",\"keccak256\":\"0xce2c2721f1df7d944bf3ae20331cb628d38247e667c47bf4a33a90f0b5753884\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title IKeep3rSidechainAccountance interface\\n/// @notice Implements a view to get the amount of credits that can be withdrawn\\ninterface IKeep3rSidechainAccountance {\\n /// @notice The surplus amount of wKP3Rs in escrow contract\\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\\n function virtualReserves() external view returns (int256 _virtualReserves);\\n}\\n\",\"keccak256\":\"0x4c11242f13d72b5db97e89672d09a771abb903e795ff85588d02c8e11fdc435e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040526203f480601f55621275006020556729a2241af62c000060215562069780602255622cd300602355601e6024553480156200003e57600080fd5b50604051620060b1380380620060b183398101604081905262000061916200010e565b60016000558383838382828286806001600160a01b038116620000965760405162b293ed60e81b815260040160405180910390fd5b600380546001600160a01b03199081166001600160a01b0393841617909155601e8054821696831696909617909555601c805486169482169490941790935550601d80549093169116179055506200016b9650505050505050565b80516001600160a01b03811681146200010957600080fd5b919050565b600080600080608085870312156200012557600080fd5b6200013085620000f1565b93506200014060208601620000f1565b92506200015060408601620000f1565b91506200016060608601620000f1565b905092959194509250565b615f36806200017b6000396000f3fe608060405234801561001057600080fd5b50600436106104b75760003560e01c8063966abd0011610278578063c5198abc1161015c578063ec8ca643116100ce578063f263c47011610092578063f263c47014610c1a578063f39c38a014610c23578063f75f9f7b14610c36578063f9d46cf214610c49578063fc253d2b14610c5c578063fe75bc4614610c6557600080fd5b8063ec8ca64314610b98578063f0f346b914610bc1578063f11a1d1a14610bd4578063f136a09d14610be7578063f25e311b14610c0757600080fd5b8063d55995fe11610120578063d55995fe14610b23578063dd2080d614610b36578063ddca3f4314610b49578063e326ac4314610b52578063ebbb619414610b72578063ec00cdfc14610b8557600080fd5b8063c5198abc14610aac578063c7ae40d014610abf578063cb4be2bb14610ad2578063cb54694d14610ae5578063cd22af1b14610af857600080fd5b8063ab033ea9116101f5578063b440027f116101b9578063b440027f14610a12578063b600702a14610a3d578063b70362b914610a50578063b7e7734014610a63578063b87fcbff14610a76578063c20297f014610a9957600080fd5b8063ab033ea9146109ae578063af320e81146109c1578063b0103b1a146109d4578063b0f328f1146109f7578063b2392233146109ff57600080fd5b8063a515366a1161023c578063a515366a1461094c578063a5d059ca1461095f578063a676f9ff14610972578063a7d2e78414610992578063aac6aa9c1461099b57600080fd5b8063966abd00146108bf57806398e90a0f146108d25780639d5c33d8146108fb578063a21458091461090e578063a39744b51461092157600080fd5b80635aa6e6751161039f5780636e2a9ca61161031c578063878c723e116102e0578063878c723e146108325780638bb6dfa81461085b5780638cb22b761461086e5780638fe204dd1461089157806390a4684e146108a4578063951dc22c146108b757600080fd5b80636e2a9ca6146107e857806372da828a146107fb57806374a8f1031461080e578063768b5d90146108215780637c8fce231461082a57600080fd5b806368a9f19c1161036357806368a9f19c14610771578063694798e61461078457806369fe0e2d146107af5780636ba42aaa146107c25780636cf262bc146107d557600080fd5b80635aa6e675146107265780635ebe23f0146107395780635feeb79414610742578063633fb68f1461075557806364bb43ee1461075e57600080fd5b80631c5a9d9c1161043857806351cff8d9116103fc57806351cff8d9146106b457806352a4de29146106c757806355ea6c47146106da578063575288bf146106ed578063594a3a931461070057806359a2255e1461071357600080fd5b80631c5a9d9c146106105780631ef94b911461062357806321040b011461064e578063238efcbc14610679578063274a8db41461068157600080fd5b806311466d721161047f57806311466d721461054a57806315006b821461055d578063165e62e714610588578063168f92e7146105c55780631b44555e146105f057600080fd5b8063034d4c61146104bc57806307b435c2146104e25780630c620bce1461050d5780630d6a1f87146105225780631101eb4114610535575b600080fd5b6104cf6104ca3660046158c4565b610c78565b6040519081526020015b60405180910390f35b6104cf6104f03660046158fe565b601760209081526000928352604080842090915290825290205481565b610515610d7e565b6040516104d99190615c46565b6104cf610530366004615aad565b610d8f565b610548610543366004615982565b610ea2565b005b610548610558366004615aad565b610ffc565b6104cf61056b3660046158fe565b601560209081526000928352604080842090915290825290205481565b61059b6105963660046158c4565b6111a1565b604080518251600690810b825260208085015190910b9082015291810151908201526060016104d9565b6104cf6105d33660046158fe565b600e60209081526000928352604080842090915290825290205481565b6104cf6105fe3660046158c4565b600a6020526000908152604090205481565b61054861061e3660046158c4565b6113ce565b601c54610636906001600160a01b031681565b6040516001600160a01b0390911681526020016104d9565b6104cf61065c3660046158fe565b601860209081526000928352604080842090915290825290205481565b610548611589565b6106a461068f3660046158c4565b60066020526000908152604090205460ff1681565b60405190151581526020016104d9565b6105486106c23660046158c4565b611612565b6105486106d5366004615982565b6117aa565b6105486106e83660046158c4565b6119dd565b6105486106fb366004615982565b611a91565b61054861070e3660046158fe565b611d4c565b6105486107213660046158c4565b611df1565b600354610636906001600160a01b031681565b6104cf601f5481565b6105486107503660046158c4565b611ea3565b6104cf60215481565b61054861076c3660046158c4565b611ebc565b61054861077f3660046158c4565b611f97565b6104cf6107923660046158fe565b602860209081526000928352604080842090915290825290205481565b6105486107bd366004615b6e565b612077565b6106a46107d03660046158c4565b6120d7565b6104cf6107e33660046158c4565b612137565b6105486107f6366004615982565b61227f565b6105486108093660046158c4565b6123cb565b61054861081c3660046158c4565b61246b565b6104cf60225481565b610515612566565b6106366108403660046158c4565b6001602052600090815260409020546001600160a01b031681565b6104cf6108693660046158c4565b612572565b6106a461087c3660046158c4565b60196020526000908152604090205460ff1681565b61054861089f366004615b6e565b612615565b6105486108b23660046158fe565b612673565b61051561275d565b6105486108cd366004615ad9565b612769565b6106366108e03660046158c4565b6002602052600090815260409020546001600160a01b031681565b6105486109093660046158c4565b61287f565b61054861091c366004615937565b61295f565b6104cf61092f3660046158fe565b600d60209081526000928352604080842090915290825290205481565b61054861095a366004615aad565b612b2f565b61054861096d366004615aad565b612d86565b6104cf6109803660046158c4565b60296020526000908152604090205481565b6104cf60205481565b6105486109a93660046158c4565b612e60565b6105486109bc3660046158c4565b612f15565b6105486109cf3660046158fe565b612f8e565b6106a46109e23660046158c4565b600c6020526000908152604090205460ff1681565b6104cf61340b565b610548610a0d366004615b6e565b61349d565b6104cf610a203660046158fe565b602560209081526000928352604080842090915290825290205481565b610548610a4b3660046158c4565b6134fd565b610548610a5e366004615aad565b613762565b610548610a71366004615b6e565b6139fc565b6106a4610a843660046158c4565b60056020526000908152604090205460ff1681565b610548610aa7366004615a16565b613a5c565b610548610aba3660046158c4565b613b15565b601d54610636906001600160a01b031681565b610548610ae03660046158c4565b613bdb565b610548610af3366004615b6e565b613c7b565b6104cf610b063660046158fe565b601660209081526000928352604080842090915290825290205481565b610548610b313660046159c3565b613cff565b610548610b44366004615982565b613f36565b6104cf60245481565b6104cf610b603660046158c4565b600b6020526000908152604090205481565b610548610b80366004615b6e565b6140c5565b610548610b933660046158c4565b614125565b610636610ba63660046158c4565b602c602052600090815260409020546001600160a01b031681565b610548610bcf3660046158c4565b6141d0565b601e54610636906001600160a01b031681565b6104cf610bf53660046158c4565b602a6020526000908152604090205481565b610548610c15366004615982565b614285565b6104cf60095481565b600454610636906001600160a01b031681565b610548610c443660046158c4565b6144cb565b6106a4610c57366004615a5c565b614583565b6104cf60235481565b610548610c73366004615aad565b61466c565b600080610c8483612137565b6022549091504290610c9f90610c9a9083615dd7565b61475c565b6001600160a01b0385166000908152602960205260409020541115610d43576022546001600160a01b038516600090815260296020526040902054610ce49042615dd7565b10610d20576022546001600160a01b038516600090815260296020526040902054610d0f9190615cfd565b610d199082615dd7565b9050610d59565b6001600160a01b038416600090815260296020526040902054610d199082615dd7565b610d4c4261475c565b610d569082615dd7565b90505b610d638183614776565b610d6c85612572565b610d769190615cfd565b949350505050565b6060610d8a60266147a0565b905090565b6000610d9c6026846147b4565b15610e9c576000610dac846111a1565b90508060400151600014610e9a576001600160a01b03841660009081526014602052604081205460ff16610ded578160200151610de890615e49565b610df3565b81602001515b601e5460225460405163a0d2710760e01b815260048101889052600684900b60248201526044810191909152919250610e91916001600160a01b039091169063a0d27107906064015b60206040518083038186803b158015610e5457600080fd5b505afa158015610e68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8c9190615b87565b6147d6565b92505050610e9c565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610ede57604051636efb4f4160e11b815260040160405180910390fd5b602054610eeb9042615cfd565b6001600160a01b03808616600081815260176020908152604080832094891680845294825280832095909555918152601882528381209281529190529081208054849290610f3a908490615cfd565b90915550610f4b90508484846147e7565b6001600160a01b038085166000908152602860209081526040808320938716835292905220548015801590610f8a5750602154610f8882866149f5565b105b15610fa857604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de85604051610fed91815260200190565b60405180910390a35050505050565b336000818152600c602052604090205460ff161561102d5760405163ad2fdf3b60e01b815260040160405180910390fd5b611038601a826147b4565b6110545760405162941a5760e11b815260040160405180910390fd5b61105d81614b1d565b156110ba576001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615ee18339815191529060600160405180910390a25b6001600160a01b0381166000908152600f602052604090205482111561113b576110e381614cf3565b6001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615ee18339815191529060600160405180910390a25b611146818484614d81565b601c546001600160a01b038085169183821691167f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa85611184614e7e565b6040805192835260208301919091520160405180910390a4505050565b60408051606081018252600080825260208201819052918101919091526111c74261475c565b6001600160a01b0383166000908152602b6020526040902060010154141561123d57506001600160a01b03166000908152602b602090815260409182902082516060810184528154600681810b810b810b8352600160381b909104810b810b900b92810192909252600101549181019190915290565b6040805160028082526060820183526000928392919060208301908036833701905050905061126b4261475c565b6112759042615dd7565b8160008151811061128857611288615eb2565b602002602001019063ffffffff16908163ffffffff16815250506022546112ae4261475c565b6112b89042615dd7565b6112c29190615cfd565b816001815181106112d5576112d5615eb2565b63ffffffff909216602092830291909101820152601e546001600160a01b0386811660009081526013909352604080842054905163dc686d9160e01b81529282169263dc686d919261132d9216908690600401615bea565b60606040518083038186803b15801561134557600080fd5b505afa158015611359573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137d9190615b2b565b600692830b90920b8087529194509150611398908290615d87565b600690810b900b602085015282156113bd576113b34261475c565b60408501526113c5565b600060408501525b5050505b919050565b336000818152600c602052604090205460ff16156113ff576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b038082166000908152601660209081526040808320938616835292905220548061144357604051636258f48160e01b815260040160405180910390fd5b42811061146357604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600b602052604090205461149c576001600160a01b0382166000908152600b602052604090204290555b6114a7600783614e98565b506001600160a01b038083166000818152601560209081526040808320948816808452948252808320805490849055938352600d82528083209483529390529182208054919283926114fa908490615cfd565b9091555050601c546001600160a01b03858116911614156115365780600960008282546115279190615cfd565b90915550611536905081614ead565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a758360405161157b91815260200190565b60405180910390a350505050565b6004546001600160a01b031633146115b457604051637ef5703160e11b815260040160405180910390fd5b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69060200160405180910390a1565b6002600054141561163e5760405162461bcd60e51b815260040161163590615cc6565b60405180910390fd5b600260009081553381526018602090815260408083206001600160a01b03851684529091529020546116835760405163184c088160e21b815260040160405180910390fd5b3360009081526017602090815260408083206001600160a01b038516845290915290205442116116c6576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600c602052604090205460ff16156116f7576040516362e6201d60e01b815260040160405180910390fd5b3360008181526018602090815260408083206001600160a01b038681168086529184528285208054908690559585526017845282852082865290935290832092909255601c5416141561174d5761174d81614f98565b6117616001600160a01b0383163383614fe0565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b600260005414156117cd5760405162461bcd60e51b815260040161163590615cc6565b60026000556117dd6026836147b4565b6117fa5760405163e0b6aead60e01b815260040160405180910390fd5b611805601a846147b4565b61182257604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526012602052604090206118449083614e98565b5061184e83615048565b6021546001600160a01b0380851660009081526028602090815260408083209387168352929052205461188c90611886908490615cfd565b846149f5565b10156118ab57604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615ee18339815191529060600160405180910390a26119176001600160a01b0383163330846150a6565b6001600160a01b0380841660009081526028602090815260408083209386168352929052908120805483929061194e908490615cfd565b909155506119619050610e8c82846149f5565b6001600160a01b03841660009081526010602052604081208054909190611989908490615cfd565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff16611a0d57604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16611a46576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b60026000541415611ab45760405162461bcd60e51b815260040161163590615cc6565b6002600055611ac4601a846147b4565b611ae157604051636211d34960e01b815260040160405180910390fd5b601c546001600160a01b0383811691161415611b0f5760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a082319060240160206040518083038186803b158015611b5157600080fd5b505afa158015611b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b899190615b87565b9050611ba06001600160a01b0384163330856150a6565b6040516370a0823160e01b815230600482015260009082906001600160a01b038616906370a082319060240160206040518083038186803b158015611be457600080fd5b505afa158015611bf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1c9190615b87565b611c269190615dd7565b9050600061271060245483611c3b9190615d29565b611c459190615d15565b9050611c518183615dd7565b6001600160a01b038088166000908152600e60209081526040808320938a1683529290529081208054909190611c88908490615cfd565b90915550506001600160a01b0380871660009081526025602090815260408083208985168085529252909120429055600354611cc5921683614fe0565b6001600160a01b0386166000908152601160205260409020611ce79086614e98565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611d3791815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611d8857604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611e2d5760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b6040516331cee75f60e21b815260040160405180910390fd5b6003546001600160a01b03163314611ee7576040516354348f0360e01b815260040160405180910390fd5b611ef26026826150e4565b611f0f57604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600081815260136020908152604080832080546001600160a01b031916905560148252808320805460ff19169055602b825280832080546001600160701b03191681556001019290925590519182527f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e5691015b60405180910390a150565b6003546001600160a01b03163314611fc2576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116611fe95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16156120235760405163546da66560e11b815260040160405180910390fd5b6001600160a01b038116600081815260056020908152604091829020805460ff1916600117905590519182527f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b9101611f8c565b6003546001600160a01b031633146120a2576040516354348f0360e01b815260040160405180910390fd5b60248190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d90602001611f8c565b60006120e1614e7e565b602e556120ef6007836147b4565b156113c9577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e5460405161212791815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b038316600090815260126020526040902061215c906150f9565b811015612279576001600160a01b03831660009081526012602052604081206121859083615103565b90506121926026826147b4565b156122665760006121a2826111a1565b90508060400151600014612264576001600160a01b03821660009081526014602052604081205460ff166121e35781602001516121de90615e49565b6121e9565b81602001515b601e546001600160a01b03888116600090815260286020908152604080832089851684529091529081902054602254915163a0d2710760e01b81526004810191909152600685900b602482015260448101919091529293506122569291169063a0d2710790606401610e3c565b6122609086615cfd565b9450505b505b508061227181615e1a565b91505061213b565b50919050565b3360009081526005602052604090205460ff166122af57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff166122e8576040516310cec38560e21b815260040160405180910390fd5b6122f38383836147e7565b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb90604401602060405180830381600087803b15801561234157600080fd5b505af1925050508015612371575060408051601f3d908101601f1916820190925261236e91810190615b10565b60015b61237a5761237c565b505b604080516001600160a01b038481168252602082018490523392908616917f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e91015b60405180910390a3505050565b6003546001600160a01b031633146123f6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661241d5760405163d92e233d60e01b815260040160405180910390fd5b601e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b090602001611f8c565b3360009081526005602052604090205460ff1661249b57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff166124d4576040516310cec38560e21b815260040160405180910390fd5b6124df6007826150e4565b50601c546001600160a01b038083166000818152600d602090815260408083209490951680835293815284822054928252601881528482208483529052929092205461252d9284929161510f565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610d8a601a6147a0565b60008061257e83612137565b6022546001600160a01b038516600090815260296020526040902054919250906125a89042615dd7565b1015610e9c57600081116125d4576001600160a01b0383166000908152600f602052604090205461260e565b6001600160a01b038316600090815260106020908152604080832054600f90925290912054612604908390615d29565b61260e9190615d15565b9150612279565b6003546001600160a01b03163314612640576040516354348f0360e01b815260040160405180910390fd5b60208181556040518281527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee29101611f8c565b6001600160a01b0382811660009081526001602052604090205483911633146126af57604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156126e25760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602c6020908152604080832080546001600160a01b0319169588169586179055602d8252808320858452825291829020429055905192835290917fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c91015b60405180910390a2505050565b6060610d8a60076147a0565b6003546001600160a01b03163314612794576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166127bb5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561281c576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015612816573d6000803e3d6000fd5b50612830565b6128306001600160a01b0384168284614fe0565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b031633146128aa576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166128d15760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff161561290b5760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b038116600081815260066020908152604091829020805460ff1916600117905590519182527f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f9101611f8c565b6001600160a01b03838116600090815260016020526040902054849116331461299b57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0382166129c25760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03808516600090815260186020908152604080832093871683529290522054612a055760405163184c088160e21b815260040160405180910390fd5b6001600160a01b038085166000908152601760209081526040808320938716835292905220544211612a4a576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff1615612a84576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b0380851660008181526018602090815260408083209488168084529482528083208054908490559383526017825280832085845290915281205590612ad1908483614fe0565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca792886284604051612b2091815260200190565b60405180910390a45050505050565b60026000541415612b525760405162461bcd60e51b815260040161163590615cc6565b60026000908155338152600c602052604090205460ff1615612b87576040516362e6201d60e01b815260040160405180910390fd5b612b92601a336147b4565b15612bb05760405163d7229c4360e01b815260040160405180910390fd5b601f54612bbd9042615cfd565b3360009081526016602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81523060048201529091906370a082319060240160206040518083038186803b158015612c1b57600080fd5b505afa158015612c2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c539190615b87565b9050612c6a6001600160a01b0384163330856150a6565b6040516370a0823160e01b815230600482015281906001600160a01b038516906370a082319060240160206040518083038186803b158015612cab57600080fd5b505afa158015612cbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce39190615b87565b612ced9190615dd7565b336000908152601960209081526040808320805460ff19166001179055601582528083206001600160a01b0388168452909152812080549294508492909190612d37908490615cfd565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b602054612d939042615cfd565b3360008181526017602090815260408083206001600160a01b03881680855290835281842095909555928252600d81528282209382529290925281208054839290612ddf908490615dd7565b90915550503360009081526018602090815260408083206001600160a01b038616845290915281208054839290612e17908490615cfd565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b03163314612e8b576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16612ec4576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b038116600081815260056020908152604091829020805460ff1916905590519182527f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d0259101611f8c565b6003546001600160a01b03163314612f40576040516354348f0360e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90602001611f8c565b6001600160a01b038181166000908152600160205260409020548291163314612fca57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff168061300957506001600160a01b0382166000908152600c602052604090205460ff165b156130275760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602c602052604090205481169083161461306457604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602d602090815260408083209386168352929052205461309690603c90615cfd565b4210156130b6576040516356248e9760e01b815260040160405180910390fd5b6130bf83615048565b6130c882615048565b6001600160a01b03831660009081526011602052604081206130e9906150f9565b11156131cb576001600160a01b03831660009081526011602052604081206131119082615103565b6001600160a01b038086166000908152600e6020818152604080842085871680865290835281852054958a16855292825280842092845291905281208054939450919261315f908490615cfd565b90915550506001600160a01b038085166000818152600e6020908152604080832094861683529381528382208290559181526011909152206131a190826150e4565b506001600160a01b03831660009081526011602052604090206131c49082614e98565b50506130c8565b6001600160a01b03831660009081526012602052604081206131ec906150f9565b11156132ce576001600160a01b03831660009081526012602052604081206132149082615103565b6001600160a01b03808616600090815260286020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613262908490615cfd565b90915550506001600160a01b03808516600090815260286020908152604080832085851684528252808320839055928616825260129052206132a49082614e98565b506001600160a01b03841660009081526012602052604090206132c790826150e4565b50506131cb565b6001600160a01b0380841660009081526010602052604080822054928516825281208054909190613300908490615cfd565b90915550506001600160a01b038084166000908152601060209081526040808320839055600f90915280822054928516825281208054909190613344908490615cfd565b90915550506001600160a01b0383166000908152600f60209081526040808320839055602990915281205561337a601a846150e4565b506001600160a01b03838116600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602d8352818420958816808552958352818420849055848452602c835292819020805490931690925590519182527f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f29101612750565b600954601c54601d546040516370a0823160e01b81526001600160a01b0391821660048201526000939291909116906370a082319060240160206040518083038186803b15801561345b57600080fd5b505afa15801561346f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134939190615b87565b610d8a9190615d48565b6003546001600160a01b031633146134c8576040516354348f0360e01b815260040160405180910390fd5b60238190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb6990602001611f8c565b6003546001600160a01b03163314613528576040516354348f0360e01b815260040160405180910390fd5b613533602682614e98565b6135505760405163f25e6b9f60e01b815260040160405180910390fd5b601e5460405163eb37d34960e01b81526001600160a01b0383811660048301529091169063eb37d3499060240160206040518083038186803b15801561359557600080fd5b505afa1580156135a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135cd91906158e1565b6001600160a01b03828116600090815260136020526040902080546001600160a01b0319169290911691821790556136185760405163d92e233d60e01b815260040160405180910390fd5b601e546001600160a01b038281166000908152601360205260409081902054905163696a437b60e01b8152908216600482015291169063696a437b9060240160206040518083038186803b15801561366f57600080fd5b505afa158015613683573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136a79190615b10565b6001600160a01b0382166000908152601460205260409020805460ff19169115159190911790556136d7816111a1565b6001600160a01b0382166000818152602b60209081526040918290208451815486840151600690810b66ffffffffffffff908116600160381b026001600160701b03199093169390910b169190911717815593820151600190940193909355519081527fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b9101611f8c565b602e5461378257604051630262ab9b60e61b815260040160405180910390fd5b600061378c614e7e565b336000818152600c60205260409020549192509060ff16156137c15760405163ad2fdf3b60e01b815260040160405180910390fd5b6137cc601a826147b4565b6137e85760405162941a5760e11b815260040160405180910390fd5b6137f181614b1d565b1561384e576001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615ee18339815191529060600160405180910390a25b601e546001600160a01b038581166000908152600d60209081526040808320601c548516845290915280822054905163435b21c160e01b8152600481019190915290928392839291169063435b21c19060240160606040518083038186803b1580156138b957600080fd5b505afa1580156138cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f19190615ba0565b91945092509050600061390f86836139098a87615d29565b87615274565b6001600160a01b0386166000908152600f60205260409020549091508111156139935761393b85614cf3565b6001600160a01b038516600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615ee18339815191529060600160405180910390a25b61399e858983614d81565b6000602e55601c5460408051838152602081018990526001600160a01b038b811693898216939116917f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa910160405180910390a45050505050505050565b6003546001600160a01b03163314613a27576040516354348f0360e01b815260040160405180910390fd5b601f8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b4390602001611f8c565b3360009081526005602052604090205460ff16613a8c57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff16613ac5576040516310cec38560e21b815260040160405180910390fd5b613ad18484848461510f565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613b078486615cfd565b60405190815260200161157b565b613b20601a826147b4565b15613b3e57604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526019602052604090205460ff1615613b7857604051632f3d320560e01b815260040160405180910390fd5b613b83601a82614e98565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613c06576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116613c2d5760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383169081179091556040519081527feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae25090602001611f8c565b6003546001600160a01b03163314613ca6576040516354348f0360e01b815260040160405180910390fd5b62015180811015613cca57604051633f384aad60e21b815260040160405180910390fd5b60228190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d990602001611f8c565b60026000541415613d225760405162461bcd60e51b815260040161163590615cc6565b600260009081556001600160a01b03858116825260016020526040909120548591163314613d6357604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260256020908152604080832093881683529290522054613d9590603c90615cfd565b4211613db457604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054831115613dfa5760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600c602052604090205460ff1615613e345760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290529081208054859290613e6b908490615dd7565b90915550613e8590506001600160a01b0385168385614fe0565b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054613ed3576001600160a01b0385166000908152601160205260409020613ed190856150e4565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613f2291815260200190565b60405180910390a450506001600055505050565b336000818152600c602052604090205460ff1615613f675760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1615613fa1576040516362e6201d60e01b815260040160405180910390fd5b613fac601a826147b4565b613fc85760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600e602090815260408083209388168352929052205482111561400e5760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290529081208054849290614045908490615dd7565b9091555061405f90506001600160a01b0385168484614fe0565b826001600160a01b0316816001600160a01b0316856001600160a01b03167f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa856140a7614e7e565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b031633146140f0576040516354348f0360e01b815260040160405180910390fd5b60218190556040518181527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e790602001611f8c565b6003546001600160a01b03163314614150576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166141775760405163d92e233d60e01b815260040160405180910390fd5b614182600954614f98565b601c80546001600160a01b0319166001600160a01b0383169081179091556040519081527f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf90602001611f8c565b6003546001600160a01b031633146141fb576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1661423457604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b038116600081815260066020908152604091829020805460ff1916905590519182527f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e9101611f8c565b3360009081526005602052604090205460ff166142b557604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff166142ee576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b038316600090815260116020526040902061431090836147b4565b61432d57604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600e60209081526040808320938616835292905220548111156143725760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb90604401602060405180830381600087803b1580156143c057600080fd5b505af19250505080156143f0575060408051601f3d908101601f191682019092526143ed91810190615b10565b60015b6143f9576143fb565b505b6001600160a01b038084166000908152600e6020908152604080832093861683529290529081208054839290614432908490615dd7565b90915550506001600160a01b038084166000908152600e6020908152604080832093861683529290522054614485576001600160a01b038316600090815260116020526040902061448390836150e4565b505b604080516001600160a01b038481168252602082018490523392908616917f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d31833310491016123be565b3360009081526006602052604090205460ff166144fb57604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff1615614535576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b600061458d614e7e565b602e5561459b6007876147b4565b80156145cc57506001600160a01b038087166000908152600d60209081526040808320938916835292905220548411155b80156145f057506001600160a01b0386166000908152600a60205260409020548311155b801561461f57506001600160a01b0386166000908152600b6020526040902054829061461c9042615dd7565b10155b15614663577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e5460405161465791815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b03163314614697576040516354348f0360e01b815260040160405180910390fd5b6146a2601a836147b4565b6146bf57604051636211d34960e01b815260040160405180910390fd5b6146c882615048565b6001600160a01b0382166000908152600f6020526040812080548392906146f0908490615cfd565b90915550506001600160a01b038216600081815260296020908152604080832054600f909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d192614750928252602082015260400190565b60405180910390a25050565b60006022548261476c9190615e35565b610e9c9083615dd7565b60006022548310156122795760225461478f8385615d29565b6147999190615d15565b9050610e9c565b606060006147ad836152d1565b9392505050565b6001600160a01b038116600090815260018301602052604081205415156147ad565b6000610e9c8260225460235461532d565b6002600054141561480a5760405162461bcd60e51b815260040161163590615cc6565b600260009081556001600160a01b038416815260126020526040902061483090836147b4565b61484c576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b038084166000908152602860209081526040808320938616835292905220548111156148925760405163435b562560e01b815260040160405180910390fd5b61489b836153db565b60006148aa610e8c83856149f5565b6001600160a01b03851660009081526010602052604090205490915015614960576001600160a01b038416600090815260106020908152604080832054600f909252909120546148fb908390615d29565b6149059190615d15565b6001600160a01b0385166000908152600f60205260408120805490919061492d908490615dd7565b90915550506001600160a01b0384166000908152601060205260408120805483929061495a908490615dd7565b90915550505b6001600160a01b03808516600090815260286020908152604080832093871683529290529081208054849290614997908490615dd7565b90915550506001600160a01b038085166000908152602860209081526040808320938716835292905220546149ea576001600160a01b03841660009081526012602052604090206149e890846150e4565b505b505060016000555050565b6001600160a01b0381166000908152602b602052604081206001015415610e9c576001600160a01b03821660009081526014602052604081205460ff16614a67576001600160a01b0383166000908152602b6020526040902054614a6290600160381b900460060b615e49565b614a8b565b6001600160a01b0383166000908152602b6020526040902054600160381b900460060b5b601e5460225460405163a0d2710760e01b815260048101889052600684900b602482015260448101919091529192506001600160a01b03169063a0d271079060640160206040518083038186803b158015614ae557600080fd5b505afa158015614af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d769190615b87565b6000614b284261475c565b6001600160a01b03831660009081526029602052604090205410156113c957614b5860225442610c9a9190615dd7565b6001600160a01b03831660009081526029602052604090205411614bce57614b7f826153db565b6001600160a01b038216600090815260106020908152604080832054600f90925290912055614bad4261475c565b6001600160a01b038316600090815260296020526040902055506001919050565b6022546001600160a01b038316600090815260296020526040902054614bf49042615dd7565b10614c5057614c02826153db565b6001600160a01b038216600090815260106020908152604080832054600f83528184205560225460299092528220805491929091614c41908490615cfd565b90915550600191506113c99050565b614c594261475c565b6001600160a01b0383166000908152602a602052604090205410156113c9576001600160a01b038216600090815260106020526040902054614c9a836153db565b6001600160a01b038316600090815260106020908152604080832054600f909252909120548291614cca91615d29565b614cd49190615d15565b6001600160a01b0384166000908152600f602052604090205550919050565b6001600160a01b038116600090815260296020526040902054614d3890614d1a9042615dd7565b6001600160a01b038316600090815260106020526040902054614776565b6001600160a01b0382166000908152600f602052604081208054909190614d60908490615cfd565b90915550506001600160a01b03166000908152602960205260409020429055565b6001600160a01b0383166000908152600f6020526040902054811115614dba5760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602a60209081526040808320429055600f90915281208054839290614def908490615dd7565b90915550506001600160a01b038083166000908152600d60209081526040808320601c5490941683529290529081208054839290614e2e908490615cfd565b90915550506001600160a01b0382166000908152600a602052604081208054839290614e5b908490615cfd565b925050819055508060096000828254614e749190615cfd565b9091555050505050565b6000603f5a614e8e906040615d29565b610d8a9190615d15565b60006147ad836001600160a01b038416615400565b601c54601d5460405163095ea7b360e01b81526001600160a01b0391821660048201526024810184905291169063095ea7b390604401602060405180830381600087803b158015614efd57600080fd5b505af1158015614f11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f359190615b10565b50601d5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f25906024015b600060405180830381600087803b158015614f7d57600080fd5b505af1158015614f91573d6000803e3d6000fd5b5050505050565b8060096000828254614faa9190615dd7565b9091555050601d5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401614f63565b6040516001600160a01b03831660248201526044810182905261504390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261544f565b505050565b61505181614b1d565b5061505b81614cf3565b6001600160a01b0381166000908152600f602090815260408083205460109092529091205461508a9190615521565b6001600160a01b039091166000908152600f6020526040902055565b6040516001600160a01b03808516602483015283166044820152606481018290526150de9085906323b872dd60e01b9060840161500c565b50505050565b60006147ad836001600160a01b038416615537565b6000610e9c825490565b60006147ad838361562a565b601c546001600160a01b038481169116146151f6576003546001600160a01b038085169163a9059cbb91166151448486615cfd565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561518a57600080fd5b505af19250505080156151ba575060408051601f3d908101601f191682019092526151b791810190615b10565b60015b6151f4573d8080156151e8576040519150601f19603f3d011682016040523d82523d6000602084013e6151ed565b606091505b50506151f6565b505b6001600160a01b038085166000908152600d602090815260408083209387168352929052908120805484929061522d908490615dd7565b90915550506001600160a01b03808516600090815260186020908152604080832093871683529290529081208054839290615269908490615dd7565b909155505050505050565b6000808486602e546152869190615dd7565b6152909190615cfd565b9050670de0b6b3a7640000846127106152a98685615d29565b6152b39190615d15565b6152bd9190615d29565b6152c79190615d15565b9695505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561532157602002820191906000526020600020905b81548152602001906001019080831161530d575b50505050509050919050565b600080806000198587098587029250828110838203039150508060001415615367576000841161535c57600080fd5b5082900490506147ad565b80841161537357600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6153e481615654565b6001600160a01b03909116600090815260106020526040902055565b600081815260018301602052604081205461544757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e9c565b506000610e9c565b60006154a4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166157979092919063ffffffff16565b80519091501561504357808060200190518101906154c29190615b10565b6150435760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611635565b600081831061553057816147ad565b5090919050565b6000818152600183016020526040812054801561562057600061555b600183615dd7565b855490915060009061556f90600190615dd7565b90508181146155d457600086600001828154811061558f5761558f615eb2565b90600052602060002001549050808760000184815481106155b2576155b2615eb2565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806155e5576155e5615e9c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e9c565b6000915050610e9c565b600082600001828154811061564157615641615eb2565b9060005260206000200154905092915050565b6000805b6001600160a01b0383166000908152601260205260409020615679906150f9565b811015612279576001600160a01b03831660009081526012602052604081206156a29083615103565b90506156af6026826147b4565b15615784576156bd4261475c565b6001600160a01b0382166000908152602b602052604090206001015414615743576156e7816111a1565b6001600160a01b0382166000908152602b60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b16179190911781559101516001909101555b6001600160a01b0380851660009081526028602090815260408083209385168352929052205461577790610e8c90836149f5565b6157819084615cfd565b92505b508061578f81615e1a565b915050615658565b6060610d76848460008585843b6157f05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611635565b600080866001600160a01b0316858760405161580c9190615bce565b60006040518083038185875af1925050503d8060008114615849576040519150601f19603f3d011682016040523d82523d6000602084013e61584e565b606091505b509150915061585e828286615869565b979650505050505050565b606083156158785750816147ad565b8251156158885782518084602001fd5b8160405162461bcd60e51b81526004016116359190615c93565b805180151581146113c957600080fd5b8051600681900b81146113c957600080fd5b6000602082840312156158d657600080fd5b81356147ad81615ec8565b6000602082840312156158f357600080fd5b81516147ad81615ec8565b6000806040838503121561591157600080fd5b823561591c81615ec8565b9150602083013561592c81615ec8565b809150509250929050565b60008060006060848603121561594c57600080fd5b833561595781615ec8565b9250602084013561596781615ec8565b9150604084013561597781615ec8565b809150509250925092565b60008060006060848603121561599757600080fd5b83356159a281615ec8565b925060208401356159b281615ec8565b929592945050506040919091013590565b600080600080608085870312156159d957600080fd5b84356159e481615ec8565b935060208501356159f481615ec8565b9250604085013591506060850135615a0b81615ec8565b939692955090935050565b60008060008060808587031215615a2c57600080fd5b8435615a3781615ec8565b93506020850135615a4781615ec8565b93969395505050506040820135916060013590565b600080600080600060a08688031215615a7457600080fd5b8535615a7f81615ec8565b94506020860135615a8f81615ec8565b94979496505050506040830135926060810135926080909101359150565b60008060408385031215615ac057600080fd5b8235615acb81615ec8565b946020939093013593505050565b600080600060608486031215615aee57600080fd5b8335615af981615ec8565b925060208401359150604084013561597781615ec8565b600060208284031215615b2257600080fd5b6147ad826158a2565b600080600060608486031215615b4057600080fd5b615b49846158b2565b9250615b57602085016158b2565b9150615b65604085016158a2565b90509250925092565b600060208284031215615b8057600080fd5b5035919050565b600060208284031215615b9957600080fd5b5051919050565b600080600060608486031215615bb557600080fd5b8351925060208401519150604084015190509250925092565b60008251615be0818460208701615dee565b9190910192915050565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615c3957845163ffffffff1683529383019391830191600101615c17565b5090979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015615c875783516001600160a01b031683529284019291840191600101615c62565b50909695505050505050565b6020815260008251806020840152615cb2816040850160208701615dee565b601f01601f19169190910160400192915050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60008219821115615d1057615d10615e70565b500190565b600082615d2457615d24615e86565b500490565b6000816000190483118215151615615d4357615d43615e70565b500290565b60008083128015600160ff1b850184121615615d6657615d66615e70565b6001600160ff1b0384018313811615615d8157615d81615e70565b50500390565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615db257615db2615e70565b81667fffffffffffff018313811615615dcd57615dcd615e70565b5090039392505050565b600082821015615de957615de9615e70565b500390565b60005b83811015615e09578181015183820152602001615df1565b838111156150de5750506000910152565b6000600019821415615e2e57615e2e615e70565b5060010190565b600082615e4457615e44615e86565b500690565b60008160060b667fffffffffffff19811415615e6757615e67615e70565b60000392915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114615edd57600080fd5b5056feee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a2646970667358221220c85e5e762d93943252a51aba67aefab144b4c4ef8a256c8d4018762fe8f83ba064736f6c63430008070033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106104b75760003560e01c8063966abd0011610278578063c5198abc1161015c578063ec8ca643116100ce578063f263c47011610092578063f263c47014610c1a578063f39c38a014610c23578063f75f9f7b14610c36578063f9d46cf214610c49578063fc253d2b14610c5c578063fe75bc4614610c6557600080fd5b8063ec8ca64314610b98578063f0f346b914610bc1578063f11a1d1a14610bd4578063f136a09d14610be7578063f25e311b14610c0757600080fd5b8063d55995fe11610120578063d55995fe14610b23578063dd2080d614610b36578063ddca3f4314610b49578063e326ac4314610b52578063ebbb619414610b72578063ec00cdfc14610b8557600080fd5b8063c5198abc14610aac578063c7ae40d014610abf578063cb4be2bb14610ad2578063cb54694d14610ae5578063cd22af1b14610af857600080fd5b8063ab033ea9116101f5578063b440027f116101b9578063b440027f14610a12578063b600702a14610a3d578063b70362b914610a50578063b7e7734014610a63578063b87fcbff14610a76578063c20297f014610a9957600080fd5b8063ab033ea9146109ae578063af320e81146109c1578063b0103b1a146109d4578063b0f328f1146109f7578063b2392233146109ff57600080fd5b8063a515366a1161023c578063a515366a1461094c578063a5d059ca1461095f578063a676f9ff14610972578063a7d2e78414610992578063aac6aa9c1461099b57600080fd5b8063966abd00146108bf57806398e90a0f146108d25780639d5c33d8146108fb578063a21458091461090e578063a39744b51461092157600080fd5b80635aa6e6751161039f5780636e2a9ca61161031c578063878c723e116102e0578063878c723e146108325780638bb6dfa81461085b5780638cb22b761461086e5780638fe204dd1461089157806390a4684e146108a4578063951dc22c146108b757600080fd5b80636e2a9ca6146107e857806372da828a146107fb57806374a8f1031461080e578063768b5d90146108215780637c8fce231461082a57600080fd5b806368a9f19c1161036357806368a9f19c14610771578063694798e61461078457806369fe0e2d146107af5780636ba42aaa146107c25780636cf262bc146107d557600080fd5b80635aa6e675146107265780635ebe23f0146107395780635feeb79414610742578063633fb68f1461075557806364bb43ee1461075e57600080fd5b80631c5a9d9c1161043857806351cff8d9116103fc57806351cff8d9146106b457806352a4de29146106c757806355ea6c47146106da578063575288bf146106ed578063594a3a931461070057806359a2255e1461071357600080fd5b80631c5a9d9c146106105780631ef94b911461062357806321040b011461064e578063238efcbc14610679578063274a8db41461068157600080fd5b806311466d721161047f57806311466d721461054a57806315006b821461055d578063165e62e714610588578063168f92e7146105c55780631b44555e146105f057600080fd5b8063034d4c61146104bc57806307b435c2146104e25780630c620bce1461050d5780630d6a1f87146105225780631101eb4114610535575b600080fd5b6104cf6104ca3660046158c4565b610c78565b6040519081526020015b60405180910390f35b6104cf6104f03660046158fe565b601760209081526000928352604080842090915290825290205481565b610515610d7e565b6040516104d99190615c46565b6104cf610530366004615aad565b610d8f565b610548610543366004615982565b610ea2565b005b610548610558366004615aad565b610ffc565b6104cf61056b3660046158fe565b601560209081526000928352604080842090915290825290205481565b61059b6105963660046158c4565b6111a1565b604080518251600690810b825260208085015190910b9082015291810151908201526060016104d9565b6104cf6105d33660046158fe565b600e60209081526000928352604080842090915290825290205481565b6104cf6105fe3660046158c4565b600a6020526000908152604090205481565b61054861061e3660046158c4565b6113ce565b601c54610636906001600160a01b031681565b6040516001600160a01b0390911681526020016104d9565b6104cf61065c3660046158fe565b601860209081526000928352604080842090915290825290205481565b610548611589565b6106a461068f3660046158c4565b60066020526000908152604090205460ff1681565b60405190151581526020016104d9565b6105486106c23660046158c4565b611612565b6105486106d5366004615982565b6117aa565b6105486106e83660046158c4565b6119dd565b6105486106fb366004615982565b611a91565b61054861070e3660046158fe565b611d4c565b6105486107213660046158c4565b611df1565b600354610636906001600160a01b031681565b6104cf601f5481565b6105486107503660046158c4565b611ea3565b6104cf60215481565b61054861076c3660046158c4565b611ebc565b61054861077f3660046158c4565b611f97565b6104cf6107923660046158fe565b602860209081526000928352604080842090915290825290205481565b6105486107bd366004615b6e565b612077565b6106a46107d03660046158c4565b6120d7565b6104cf6107e33660046158c4565b612137565b6105486107f6366004615982565b61227f565b6105486108093660046158c4565b6123cb565b61054861081c3660046158c4565b61246b565b6104cf60225481565b610515612566565b6106366108403660046158c4565b6001602052600090815260409020546001600160a01b031681565b6104cf6108693660046158c4565b612572565b6106a461087c3660046158c4565b60196020526000908152604090205460ff1681565b61054861089f366004615b6e565b612615565b6105486108b23660046158fe565b612673565b61051561275d565b6105486108cd366004615ad9565b612769565b6106366108e03660046158c4565b6002602052600090815260409020546001600160a01b031681565b6105486109093660046158c4565b61287f565b61054861091c366004615937565b61295f565b6104cf61092f3660046158fe565b600d60209081526000928352604080842090915290825290205481565b61054861095a366004615aad565b612b2f565b61054861096d366004615aad565b612d86565b6104cf6109803660046158c4565b60296020526000908152604090205481565b6104cf60205481565b6105486109a93660046158c4565b612e60565b6105486109bc3660046158c4565b612f15565b6105486109cf3660046158fe565b612f8e565b6106a46109e23660046158c4565b600c6020526000908152604090205460ff1681565b6104cf61340b565b610548610a0d366004615b6e565b61349d565b6104cf610a203660046158fe565b602560209081526000928352604080842090915290825290205481565b610548610a4b3660046158c4565b6134fd565b610548610a5e366004615aad565b613762565b610548610a71366004615b6e565b6139fc565b6106a4610a843660046158c4565b60056020526000908152604090205460ff1681565b610548610aa7366004615a16565b613a5c565b610548610aba3660046158c4565b613b15565b601d54610636906001600160a01b031681565b610548610ae03660046158c4565b613bdb565b610548610af3366004615b6e565b613c7b565b6104cf610b063660046158fe565b601660209081526000928352604080842090915290825290205481565b610548610b313660046159c3565b613cff565b610548610b44366004615982565b613f36565b6104cf60245481565b6104cf610b603660046158c4565b600b6020526000908152604090205481565b610548610b80366004615b6e565b6140c5565b610548610b933660046158c4565b614125565b610636610ba63660046158c4565b602c602052600090815260409020546001600160a01b031681565b610548610bcf3660046158c4565b6141d0565b601e54610636906001600160a01b031681565b6104cf610bf53660046158c4565b602a6020526000908152604090205481565b610548610c15366004615982565b614285565b6104cf60095481565b600454610636906001600160a01b031681565b610548610c443660046158c4565b6144cb565b6106a4610c57366004615a5c565b614583565b6104cf60235481565b610548610c73366004615aad565b61466c565b600080610c8483612137565b6022549091504290610c9f90610c9a9083615dd7565b61475c565b6001600160a01b0385166000908152602960205260409020541115610d43576022546001600160a01b038516600090815260296020526040902054610ce49042615dd7565b10610d20576022546001600160a01b038516600090815260296020526040902054610d0f9190615cfd565b610d199082615dd7565b9050610d59565b6001600160a01b038416600090815260296020526040902054610d199082615dd7565b610d4c4261475c565b610d569082615dd7565b90505b610d638183614776565b610d6c85612572565b610d769190615cfd565b949350505050565b6060610d8a60266147a0565b905090565b6000610d9c6026846147b4565b15610e9c576000610dac846111a1565b90508060400151600014610e9a576001600160a01b03841660009081526014602052604081205460ff16610ded578160200151610de890615e49565b610df3565b81602001515b601e5460225460405163a0d2710760e01b815260048101889052600684900b60248201526044810191909152919250610e91916001600160a01b039091169063a0d27107906064015b60206040518083038186803b158015610e5457600080fd5b505afa158015610e68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8c9190615b87565b6147d6565b92505050610e9c565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610ede57604051636efb4f4160e11b815260040160405180910390fd5b602054610eeb9042615cfd565b6001600160a01b03808616600081815260176020908152604080832094891680845294825280832095909555918152601882528381209281529190529081208054849290610f3a908490615cfd565b90915550610f4b90508484846147e7565b6001600160a01b038085166000908152602860209081526040808320938716835292905220548015801590610f8a5750602154610f8882866149f5565b105b15610fa857604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de85604051610fed91815260200190565b60405180910390a35050505050565b336000818152600c602052604090205460ff161561102d5760405163ad2fdf3b60e01b815260040160405180910390fd5b611038601a826147b4565b6110545760405162941a5760e11b815260040160405180910390fd5b61105d81614b1d565b156110ba576001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615ee18339815191529060600160405180910390a25b6001600160a01b0381166000908152600f602052604090205482111561113b576110e381614cf3565b6001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615ee18339815191529060600160405180910390a25b611146818484614d81565b601c546001600160a01b038085169183821691167f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa85611184614e7e565b6040805192835260208301919091520160405180910390a4505050565b60408051606081018252600080825260208201819052918101919091526111c74261475c565b6001600160a01b0383166000908152602b6020526040902060010154141561123d57506001600160a01b03166000908152602b602090815260409182902082516060810184528154600681810b810b810b8352600160381b909104810b810b900b92810192909252600101549181019190915290565b6040805160028082526060820183526000928392919060208301908036833701905050905061126b4261475c565b6112759042615dd7565b8160008151811061128857611288615eb2565b602002602001019063ffffffff16908163ffffffff16815250506022546112ae4261475c565b6112b89042615dd7565b6112c29190615cfd565b816001815181106112d5576112d5615eb2565b63ffffffff909216602092830291909101820152601e546001600160a01b0386811660009081526013909352604080842054905163dc686d9160e01b81529282169263dc686d919261132d9216908690600401615bea565b60606040518083038186803b15801561134557600080fd5b505afa158015611359573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137d9190615b2b565b600692830b90920b8087529194509150611398908290615d87565b600690810b900b602085015282156113bd576113b34261475c565b60408501526113c5565b600060408501525b5050505b919050565b336000818152600c602052604090205460ff16156113ff576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b038082166000908152601660209081526040808320938616835292905220548061144357604051636258f48160e01b815260040160405180910390fd5b42811061146357604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600b602052604090205461149c576001600160a01b0382166000908152600b602052604090204290555b6114a7600783614e98565b506001600160a01b038083166000818152601560209081526040808320948816808452948252808320805490849055938352600d82528083209483529390529182208054919283926114fa908490615cfd565b9091555050601c546001600160a01b03858116911614156115365780600960008282546115279190615cfd565b90915550611536905081614ead565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a758360405161157b91815260200190565b60405180910390a350505050565b6004546001600160a01b031633146115b457604051637ef5703160e11b815260040160405180910390fd5b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69060200160405180910390a1565b6002600054141561163e5760405162461bcd60e51b815260040161163590615cc6565b60405180910390fd5b600260009081553381526018602090815260408083206001600160a01b03851684529091529020546116835760405163184c088160e21b815260040160405180910390fd5b3360009081526017602090815260408083206001600160a01b038516845290915290205442116116c6576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600c602052604090205460ff16156116f7576040516362e6201d60e01b815260040160405180910390fd5b3360008181526018602090815260408083206001600160a01b038681168086529184528285208054908690559585526017845282852082865290935290832092909255601c5416141561174d5761174d81614f98565b6117616001600160a01b0383163383614fe0565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b600260005414156117cd5760405162461bcd60e51b815260040161163590615cc6565b60026000556117dd6026836147b4565b6117fa5760405163e0b6aead60e01b815260040160405180910390fd5b611805601a846147b4565b61182257604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526012602052604090206118449083614e98565b5061184e83615048565b6021546001600160a01b0380851660009081526028602090815260408083209387168352929052205461188c90611886908490615cfd565b846149f5565b10156118ab57604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615ee18339815191529060600160405180910390a26119176001600160a01b0383163330846150a6565b6001600160a01b0380841660009081526028602090815260408083209386168352929052908120805483929061194e908490615cfd565b909155506119619050610e8c82846149f5565b6001600160a01b03841660009081526010602052604081208054909190611989908490615cfd565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff16611a0d57604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16611a46576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b60026000541415611ab45760405162461bcd60e51b815260040161163590615cc6565b6002600055611ac4601a846147b4565b611ae157604051636211d34960e01b815260040160405180910390fd5b601c546001600160a01b0383811691161415611b0f5760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a082319060240160206040518083038186803b158015611b5157600080fd5b505afa158015611b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b899190615b87565b9050611ba06001600160a01b0384163330856150a6565b6040516370a0823160e01b815230600482015260009082906001600160a01b038616906370a082319060240160206040518083038186803b158015611be457600080fd5b505afa158015611bf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1c9190615b87565b611c269190615dd7565b9050600061271060245483611c3b9190615d29565b611c459190615d15565b9050611c518183615dd7565b6001600160a01b038088166000908152600e60209081526040808320938a1683529290529081208054909190611c88908490615cfd565b90915550506001600160a01b0380871660009081526025602090815260408083208985168085529252909120429055600354611cc5921683614fe0565b6001600160a01b0386166000908152601160205260409020611ce79086614e98565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611d3791815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611d8857604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611e2d5760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b6040516331cee75f60e21b815260040160405180910390fd5b6003546001600160a01b03163314611ee7576040516354348f0360e01b815260040160405180910390fd5b611ef26026826150e4565b611f0f57604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600081815260136020908152604080832080546001600160a01b031916905560148252808320805460ff19169055602b825280832080546001600160701b03191681556001019290925590519182527f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e5691015b60405180910390a150565b6003546001600160a01b03163314611fc2576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116611fe95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16156120235760405163546da66560e11b815260040160405180910390fd5b6001600160a01b038116600081815260056020908152604091829020805460ff1916600117905590519182527f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b9101611f8c565b6003546001600160a01b031633146120a2576040516354348f0360e01b815260040160405180910390fd5b60248190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d90602001611f8c565b60006120e1614e7e565b602e556120ef6007836147b4565b156113c9577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e5460405161212791815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b038316600090815260126020526040902061215c906150f9565b811015612279576001600160a01b03831660009081526012602052604081206121859083615103565b90506121926026826147b4565b156122665760006121a2826111a1565b90508060400151600014612264576001600160a01b03821660009081526014602052604081205460ff166121e35781602001516121de90615e49565b6121e9565b81602001515b601e546001600160a01b03888116600090815260286020908152604080832089851684529091529081902054602254915163a0d2710760e01b81526004810191909152600685900b602482015260448101919091529293506122569291169063a0d2710790606401610e3c565b6122609086615cfd565b9450505b505b508061227181615e1a565b91505061213b565b50919050565b3360009081526005602052604090205460ff166122af57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff166122e8576040516310cec38560e21b815260040160405180910390fd5b6122f38383836147e7565b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb90604401602060405180830381600087803b15801561234157600080fd5b505af1925050508015612371575060408051601f3d908101601f1916820190925261236e91810190615b10565b60015b61237a5761237c565b505b604080516001600160a01b038481168252602082018490523392908616917f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e91015b60405180910390a3505050565b6003546001600160a01b031633146123f6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661241d5760405163d92e233d60e01b815260040160405180910390fd5b601e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b090602001611f8c565b3360009081526005602052604090205460ff1661249b57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff166124d4576040516310cec38560e21b815260040160405180910390fd5b6124df6007826150e4565b50601c546001600160a01b038083166000818152600d602090815260408083209490951680835293815284822054928252601881528482208483529052929092205461252d9284929161510f565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610d8a601a6147a0565b60008061257e83612137565b6022546001600160a01b038516600090815260296020526040902054919250906125a89042615dd7565b1015610e9c57600081116125d4576001600160a01b0383166000908152600f602052604090205461260e565b6001600160a01b038316600090815260106020908152604080832054600f90925290912054612604908390615d29565b61260e9190615d15565b9150612279565b6003546001600160a01b03163314612640576040516354348f0360e01b815260040160405180910390fd5b60208181556040518281527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee29101611f8c565b6001600160a01b0382811660009081526001602052604090205483911633146126af57604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156126e25760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602c6020908152604080832080546001600160a01b0319169588169586179055602d8252808320858452825291829020429055905192835290917fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c91015b60405180910390a2505050565b6060610d8a60076147a0565b6003546001600160a01b03163314612794576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166127bb5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561281c576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015612816573d6000803e3d6000fd5b50612830565b6128306001600160a01b0384168284614fe0565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b031633146128aa576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166128d15760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff161561290b5760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b038116600081815260066020908152604091829020805460ff1916600117905590519182527f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f9101611f8c565b6001600160a01b03838116600090815260016020526040902054849116331461299b57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0382166129c25760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03808516600090815260186020908152604080832093871683529290522054612a055760405163184c088160e21b815260040160405180910390fd5b6001600160a01b038085166000908152601760209081526040808320938716835292905220544211612a4a576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff1615612a84576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b0380851660008181526018602090815260408083209488168084529482528083208054908490559383526017825280832085845290915281205590612ad1908483614fe0565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca792886284604051612b2091815260200190565b60405180910390a45050505050565b60026000541415612b525760405162461bcd60e51b815260040161163590615cc6565b60026000908155338152600c602052604090205460ff1615612b87576040516362e6201d60e01b815260040160405180910390fd5b612b92601a336147b4565b15612bb05760405163d7229c4360e01b815260040160405180910390fd5b601f54612bbd9042615cfd565b3360009081526016602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81523060048201529091906370a082319060240160206040518083038186803b158015612c1b57600080fd5b505afa158015612c2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c539190615b87565b9050612c6a6001600160a01b0384163330856150a6565b6040516370a0823160e01b815230600482015281906001600160a01b038516906370a082319060240160206040518083038186803b158015612cab57600080fd5b505afa158015612cbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce39190615b87565b612ced9190615dd7565b336000908152601960209081526040808320805460ff19166001179055601582528083206001600160a01b0388168452909152812080549294508492909190612d37908490615cfd565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b602054612d939042615cfd565b3360008181526017602090815260408083206001600160a01b03881680855290835281842095909555928252600d81528282209382529290925281208054839290612ddf908490615dd7565b90915550503360009081526018602090815260408083206001600160a01b038616845290915281208054839290612e17908490615cfd565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b03163314612e8b576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16612ec4576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b038116600081815260056020908152604091829020805460ff1916905590519182527f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d0259101611f8c565b6003546001600160a01b03163314612f40576040516354348f0360e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90602001611f8c565b6001600160a01b038181166000908152600160205260409020548291163314612fca57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff168061300957506001600160a01b0382166000908152600c602052604090205460ff165b156130275760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602c602052604090205481169083161461306457604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602d602090815260408083209386168352929052205461309690603c90615cfd565b4210156130b6576040516356248e9760e01b815260040160405180910390fd5b6130bf83615048565b6130c882615048565b6001600160a01b03831660009081526011602052604081206130e9906150f9565b11156131cb576001600160a01b03831660009081526011602052604081206131119082615103565b6001600160a01b038086166000908152600e6020818152604080842085871680865290835281852054958a16855292825280842092845291905281208054939450919261315f908490615cfd565b90915550506001600160a01b038085166000818152600e6020908152604080832094861683529381528382208290559181526011909152206131a190826150e4565b506001600160a01b03831660009081526011602052604090206131c49082614e98565b50506130c8565b6001600160a01b03831660009081526012602052604081206131ec906150f9565b11156132ce576001600160a01b03831660009081526012602052604081206132149082615103565b6001600160a01b03808616600090815260286020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613262908490615cfd565b90915550506001600160a01b03808516600090815260286020908152604080832085851684528252808320839055928616825260129052206132a49082614e98565b506001600160a01b03841660009081526012602052604090206132c790826150e4565b50506131cb565b6001600160a01b0380841660009081526010602052604080822054928516825281208054909190613300908490615cfd565b90915550506001600160a01b038084166000908152601060209081526040808320839055600f90915280822054928516825281208054909190613344908490615cfd565b90915550506001600160a01b0383166000908152600f60209081526040808320839055602990915281205561337a601a846150e4565b506001600160a01b03838116600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602d8352818420958816808552958352818420849055848452602c835292819020805490931690925590519182527f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f29101612750565b600954601c54601d546040516370a0823160e01b81526001600160a01b0391821660048201526000939291909116906370a082319060240160206040518083038186803b15801561345b57600080fd5b505afa15801561346f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134939190615b87565b610d8a9190615d48565b6003546001600160a01b031633146134c8576040516354348f0360e01b815260040160405180910390fd5b60238190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb6990602001611f8c565b6003546001600160a01b03163314613528576040516354348f0360e01b815260040160405180910390fd5b613533602682614e98565b6135505760405163f25e6b9f60e01b815260040160405180910390fd5b601e5460405163eb37d34960e01b81526001600160a01b0383811660048301529091169063eb37d3499060240160206040518083038186803b15801561359557600080fd5b505afa1580156135a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135cd91906158e1565b6001600160a01b03828116600090815260136020526040902080546001600160a01b0319169290911691821790556136185760405163d92e233d60e01b815260040160405180910390fd5b601e546001600160a01b038281166000908152601360205260409081902054905163696a437b60e01b8152908216600482015291169063696a437b9060240160206040518083038186803b15801561366f57600080fd5b505afa158015613683573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136a79190615b10565b6001600160a01b0382166000908152601460205260409020805460ff19169115159190911790556136d7816111a1565b6001600160a01b0382166000818152602b60209081526040918290208451815486840151600690810b66ffffffffffffff908116600160381b026001600160701b03199093169390910b169190911717815593820151600190940193909355519081527fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b9101611f8c565b602e5461378257604051630262ab9b60e61b815260040160405180910390fd5b600061378c614e7e565b336000818152600c60205260409020549192509060ff16156137c15760405163ad2fdf3b60e01b815260040160405180910390fd5b6137cc601a826147b4565b6137e85760405162941a5760e11b815260040160405180910390fd5b6137f181614b1d565b1561384e576001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615ee18339815191529060600160405180910390a25b601e546001600160a01b038581166000908152600d60209081526040808320601c548516845290915280822054905163435b21c160e01b8152600481019190915290928392839291169063435b21c19060240160606040518083038186803b1580156138b957600080fd5b505afa1580156138cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f19190615ba0565b91945092509050600061390f86836139098a87615d29565b87615274565b6001600160a01b0386166000908152600f60205260409020549091508111156139935761393b85614cf3565b6001600160a01b038516600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615ee18339815191529060600160405180910390a25b61399e858983614d81565b6000602e55601c5460408051838152602081018990526001600160a01b038b811693898216939116917f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa910160405180910390a45050505050505050565b6003546001600160a01b03163314613a27576040516354348f0360e01b815260040160405180910390fd5b601f8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b4390602001611f8c565b3360009081526005602052604090205460ff16613a8c57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff16613ac5576040516310cec38560e21b815260040160405180910390fd5b613ad18484848461510f565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613b078486615cfd565b60405190815260200161157b565b613b20601a826147b4565b15613b3e57604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526019602052604090205460ff1615613b7857604051632f3d320560e01b815260040160405180910390fd5b613b83601a82614e98565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613c06576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116613c2d5760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383169081179091556040519081527feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae25090602001611f8c565b6003546001600160a01b03163314613ca6576040516354348f0360e01b815260040160405180910390fd5b62015180811015613cca57604051633f384aad60e21b815260040160405180910390fd5b60228190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d990602001611f8c565b60026000541415613d225760405162461bcd60e51b815260040161163590615cc6565b600260009081556001600160a01b03858116825260016020526040909120548591163314613d6357604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260256020908152604080832093881683529290522054613d9590603c90615cfd565b4211613db457604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054831115613dfa5760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600c602052604090205460ff1615613e345760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290529081208054859290613e6b908490615dd7565b90915550613e8590506001600160a01b0385168385614fe0565b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054613ed3576001600160a01b0385166000908152601160205260409020613ed190856150e4565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613f2291815260200190565b60405180910390a450506001600055505050565b336000818152600c602052604090205460ff1615613f675760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1615613fa1576040516362e6201d60e01b815260040160405180910390fd5b613fac601a826147b4565b613fc85760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600e602090815260408083209388168352929052205482111561400e5760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290529081208054849290614045908490615dd7565b9091555061405f90506001600160a01b0385168484614fe0565b826001600160a01b0316816001600160a01b0316856001600160a01b03167f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa856140a7614e7e565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b031633146140f0576040516354348f0360e01b815260040160405180910390fd5b60218190556040518181527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e790602001611f8c565b6003546001600160a01b03163314614150576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166141775760405163d92e233d60e01b815260040160405180910390fd5b614182600954614f98565b601c80546001600160a01b0319166001600160a01b0383169081179091556040519081527f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf90602001611f8c565b6003546001600160a01b031633146141fb576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1661423457604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b038116600081815260066020908152604091829020805460ff1916905590519182527f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e9101611f8c565b3360009081526005602052604090205460ff166142b557604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff166142ee576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b038316600090815260116020526040902061431090836147b4565b61432d57604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600e60209081526040808320938616835292905220548111156143725760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb90604401602060405180830381600087803b1580156143c057600080fd5b505af19250505080156143f0575060408051601f3d908101601f191682019092526143ed91810190615b10565b60015b6143f9576143fb565b505b6001600160a01b038084166000908152600e6020908152604080832093861683529290529081208054839290614432908490615dd7565b90915550506001600160a01b038084166000908152600e6020908152604080832093861683529290522054614485576001600160a01b038316600090815260116020526040902061448390836150e4565b505b604080516001600160a01b038481168252602082018490523392908616917f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d31833310491016123be565b3360009081526006602052604090205460ff166144fb57604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff1615614535576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b600061458d614e7e565b602e5561459b6007876147b4565b80156145cc57506001600160a01b038087166000908152600d60209081526040808320938916835292905220548411155b80156145f057506001600160a01b0386166000908152600a60205260409020548311155b801561461f57506001600160a01b0386166000908152600b6020526040902054829061461c9042615dd7565b10155b15614663577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e5460405161465791815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b03163314614697576040516354348f0360e01b815260040160405180910390fd5b6146a2601a836147b4565b6146bf57604051636211d34960e01b815260040160405180910390fd5b6146c882615048565b6001600160a01b0382166000908152600f6020526040812080548392906146f0908490615cfd565b90915550506001600160a01b038216600081815260296020908152604080832054600f909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d192614750928252602082015260400190565b60405180910390a25050565b60006022548261476c9190615e35565b610e9c9083615dd7565b60006022548310156122795760225461478f8385615d29565b6147999190615d15565b9050610e9c565b606060006147ad836152d1565b9392505050565b6001600160a01b038116600090815260018301602052604081205415156147ad565b6000610e9c8260225460235461532d565b6002600054141561480a5760405162461bcd60e51b815260040161163590615cc6565b600260009081556001600160a01b038416815260126020526040902061483090836147b4565b61484c576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b038084166000908152602860209081526040808320938616835292905220548111156148925760405163435b562560e01b815260040160405180910390fd5b61489b836153db565b60006148aa610e8c83856149f5565b6001600160a01b03851660009081526010602052604090205490915015614960576001600160a01b038416600090815260106020908152604080832054600f909252909120546148fb908390615d29565b6149059190615d15565b6001600160a01b0385166000908152600f60205260408120805490919061492d908490615dd7565b90915550506001600160a01b0384166000908152601060205260408120805483929061495a908490615dd7565b90915550505b6001600160a01b03808516600090815260286020908152604080832093871683529290529081208054849290614997908490615dd7565b90915550506001600160a01b038085166000908152602860209081526040808320938716835292905220546149ea576001600160a01b03841660009081526012602052604090206149e890846150e4565b505b505060016000555050565b6001600160a01b0381166000908152602b602052604081206001015415610e9c576001600160a01b03821660009081526014602052604081205460ff16614a67576001600160a01b0383166000908152602b6020526040902054614a6290600160381b900460060b615e49565b614a8b565b6001600160a01b0383166000908152602b6020526040902054600160381b900460060b5b601e5460225460405163a0d2710760e01b815260048101889052600684900b602482015260448101919091529192506001600160a01b03169063a0d271079060640160206040518083038186803b158015614ae557600080fd5b505afa158015614af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d769190615b87565b6000614b284261475c565b6001600160a01b03831660009081526029602052604090205410156113c957614b5860225442610c9a9190615dd7565b6001600160a01b03831660009081526029602052604090205411614bce57614b7f826153db565b6001600160a01b038216600090815260106020908152604080832054600f90925290912055614bad4261475c565b6001600160a01b038316600090815260296020526040902055506001919050565b6022546001600160a01b038316600090815260296020526040902054614bf49042615dd7565b10614c5057614c02826153db565b6001600160a01b038216600090815260106020908152604080832054600f83528184205560225460299092528220805491929091614c41908490615cfd565b90915550600191506113c99050565b614c594261475c565b6001600160a01b0383166000908152602a602052604090205410156113c9576001600160a01b038216600090815260106020526040902054614c9a836153db565b6001600160a01b038316600090815260106020908152604080832054600f909252909120548291614cca91615d29565b614cd49190615d15565b6001600160a01b0384166000908152600f602052604090205550919050565b6001600160a01b038116600090815260296020526040902054614d3890614d1a9042615dd7565b6001600160a01b038316600090815260106020526040902054614776565b6001600160a01b0382166000908152600f602052604081208054909190614d60908490615cfd565b90915550506001600160a01b03166000908152602960205260409020429055565b6001600160a01b0383166000908152600f6020526040902054811115614dba5760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602a60209081526040808320429055600f90915281208054839290614def908490615dd7565b90915550506001600160a01b038083166000908152600d60209081526040808320601c5490941683529290529081208054839290614e2e908490615cfd565b90915550506001600160a01b0382166000908152600a602052604081208054839290614e5b908490615cfd565b925050819055508060096000828254614e749190615cfd565b9091555050505050565b6000603f5a614e8e906040615d29565b610d8a9190615d15565b60006147ad836001600160a01b038416615400565b601c54601d5460405163095ea7b360e01b81526001600160a01b0391821660048201526024810184905291169063095ea7b390604401602060405180830381600087803b158015614efd57600080fd5b505af1158015614f11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f359190615b10565b50601d5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f25906024015b600060405180830381600087803b158015614f7d57600080fd5b505af1158015614f91573d6000803e3d6000fd5b5050505050565b8060096000828254614faa9190615dd7565b9091555050601d5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401614f63565b6040516001600160a01b03831660248201526044810182905261504390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261544f565b505050565b61505181614b1d565b5061505b81614cf3565b6001600160a01b0381166000908152600f602090815260408083205460109092529091205461508a9190615521565b6001600160a01b039091166000908152600f6020526040902055565b6040516001600160a01b03808516602483015283166044820152606481018290526150de9085906323b872dd60e01b9060840161500c565b50505050565b60006147ad836001600160a01b038416615537565b6000610e9c825490565b60006147ad838361562a565b601c546001600160a01b038481169116146151f6576003546001600160a01b038085169163a9059cbb91166151448486615cfd565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561518a57600080fd5b505af19250505080156151ba575060408051601f3d908101601f191682019092526151b791810190615b10565b60015b6151f4573d8080156151e8576040519150601f19603f3d011682016040523d82523d6000602084013e6151ed565b606091505b50506151f6565b505b6001600160a01b038085166000908152600d602090815260408083209387168352929052908120805484929061522d908490615dd7565b90915550506001600160a01b03808516600090815260186020908152604080832093871683529290529081208054839290615269908490615dd7565b909155505050505050565b6000808486602e546152869190615dd7565b6152909190615cfd565b9050670de0b6b3a7640000846127106152a98685615d29565b6152b39190615d15565b6152bd9190615d29565b6152c79190615d15565b9695505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561532157602002820191906000526020600020905b81548152602001906001019080831161530d575b50505050509050919050565b600080806000198587098587029250828110838203039150508060001415615367576000841161535c57600080fd5b5082900490506147ad565b80841161537357600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6153e481615654565b6001600160a01b03909116600090815260106020526040902055565b600081815260018301602052604081205461544757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e9c565b506000610e9c565b60006154a4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166157979092919063ffffffff16565b80519091501561504357808060200190518101906154c29190615b10565b6150435760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611635565b600081831061553057816147ad565b5090919050565b6000818152600183016020526040812054801561562057600061555b600183615dd7565b855490915060009061556f90600190615dd7565b90508181146155d457600086600001828154811061558f5761558f615eb2565b90600052602060002001549050808760000184815481106155b2576155b2615eb2565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806155e5576155e5615e9c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e9c565b6000915050610e9c565b600082600001828154811061564157615641615eb2565b9060005260206000200154905092915050565b6000805b6001600160a01b0383166000908152601260205260409020615679906150f9565b811015612279576001600160a01b03831660009081526012602052604081206156a29083615103565b90506156af6026826147b4565b15615784576156bd4261475c565b6001600160a01b0382166000908152602b602052604090206001015414615743576156e7816111a1565b6001600160a01b0382166000908152602b60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b16179190911781559101516001909101555b6001600160a01b0380851660009081526028602090815260408083209385168352929052205461577790610e8c90836149f5565b6157819084615cfd565b92505b508061578f81615e1a565b915050615658565b6060610d76848460008585843b6157f05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611635565b600080866001600160a01b0316858760405161580c9190615bce565b60006040518083038185875af1925050503d8060008114615849576040519150601f19603f3d011682016040523d82523d6000602084013e61584e565b606091505b509150915061585e828286615869565b979650505050505050565b606083156158785750816147ad565b8251156158885782518084602001fd5b8160405162461bcd60e51b81526004016116359190615c93565b805180151581146113c957600080fd5b8051600681900b81146113c957600080fd5b6000602082840312156158d657600080fd5b81356147ad81615ec8565b6000602082840312156158f357600080fd5b81516147ad81615ec8565b6000806040838503121561591157600080fd5b823561591c81615ec8565b9150602083013561592c81615ec8565b809150509250929050565b60008060006060848603121561594c57600080fd5b833561595781615ec8565b9250602084013561596781615ec8565b9150604084013561597781615ec8565b809150509250925092565b60008060006060848603121561599757600080fd5b83356159a281615ec8565b925060208401356159b281615ec8565b929592945050506040919091013590565b600080600080608085870312156159d957600080fd5b84356159e481615ec8565b935060208501356159f481615ec8565b9250604085013591506060850135615a0b81615ec8565b939692955090935050565b60008060008060808587031215615a2c57600080fd5b8435615a3781615ec8565b93506020850135615a4781615ec8565b93969395505050506040820135916060013590565b600080600080600060a08688031215615a7457600080fd5b8535615a7f81615ec8565b94506020860135615a8f81615ec8565b94979496505050506040830135926060810135926080909101359150565b60008060408385031215615ac057600080fd5b8235615acb81615ec8565b946020939093013593505050565b600080600060608486031215615aee57600080fd5b8335615af981615ec8565b925060208401359150604084013561597781615ec8565b600060208284031215615b2257600080fd5b6147ad826158a2565b600080600060608486031215615b4057600080fd5b615b49846158b2565b9250615b57602085016158b2565b9150615b65604085016158a2565b90509250925092565b600060208284031215615b8057600080fd5b5035919050565b600060208284031215615b9957600080fd5b5051919050565b600080600060608486031215615bb557600080fd5b8351925060208401519150604084015190509250925092565b60008251615be0818460208701615dee565b9190910192915050565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615c3957845163ffffffff1683529383019391830191600101615c17565b5090979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015615c875783516001600160a01b031683529284019291840191600101615c62565b50909695505050505050565b6020815260008251806020840152615cb2816040850160208701615dee565b601f01601f19169190910160400192915050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60008219821115615d1057615d10615e70565b500190565b600082615d2457615d24615e86565b500490565b6000816000190483118215151615615d4357615d43615e70565b500290565b60008083128015600160ff1b850184121615615d6657615d66615e70565b6001600160ff1b0384018313811615615d8157615d81615e70565b50500390565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615db257615db2615e70565b81667fffffffffffff018313811615615dcd57615dcd615e70565b5090039392505050565b600082821015615de957615de9615e70565b500390565b60005b83811015615e09578181015183820152602001615df1565b838111156150de5750506000910152565b6000600019821415615e2e57615e2e615e70565b5060010190565b600082615e4457615e44615e86565b500690565b60008160060b667fffffffffffff19811415615e6757615e67615e70565b60000392915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114615edd57600080fd5b5056feee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a2646970667358221220c85e5e762d93943252a51aba67aefab144b4c4ef8a256c8d4018762fe8f83ba064736f6c63430008070033", + "devdoc": { + "kind": "dev", + "methods": { + "acceptJobMigration(address,address)": { + "details": "Unbond/withdraw process doesn't get migrated", + "params": { + "_fromJob": "The address of the job that requested to migrate", + "_toJob": "The address to which the job wants to migrate to" + } + }, + "acceptJobOwnership(address)": { + "params": { + "_job": "The address of the job" + } + }, + "activate(address)": { + "params": { + "_bonding": "The asset being activated as bond collateral" + } + }, + "addJob(address)": { + "params": { + "_job": "Address of the contract for which work should be performed" + } + }, + "addLiquidityToJob(address,address,uint256)": { + "params": { + "_amount": "The amount of liquidity tokens to add", + "_job": "The address of the job to assign liquidity to", + "_liquidity": "The liquidity being added" + } + }, + "addTokenCreditsToJob(address,address,uint256)": { + "params": { + "_amount": "The amount of credit being added", + "_job": "The address of the job being credited", + "_token": "The address of the token being credited" + } + }, + "approveLiquidity(address)": { + "details": "Function should be called after setting an oracle in Keep3rHelperSidechain", + "params": { + "_liquidity": "Address of the liquidity token being approved" + } + }, + "approvedLiquidities()": { + "returns": { + "_list": "An array of addresses with all the approved liquidity pairs" + } + }, + "bond(address,uint256)": { + "params": { + "_amount": "The amount of bonding asset being bonded", + "_bonding": "The asset being bonded" + } + }, + "bondedPayment(address,uint256)": { + "details": "Pays the keeper that performs the work with KP3R", + "params": { + "_keeper": "Address of the keeper that performed the work", + "_payment": "The reward that should be allocated for the job" + } + }, + "changeJobOwnership(address,address)": { + "params": { + "_job": "The address of the job", + "_newOwner": "The address of the proposed new owner" + } + }, + "constructor": { + "params": { + "_governance": "Address of governance", + "_keep3rEscrow": "Address of sidechain Keep3rEscrow", + "_keep3rHelperSidechain": "Address of sidechain Keep3rHelper", + "_wrappedKP3R": "Address of wrapped KP3R implementation" + } + }, + "directTokenPayment(address,address,uint256)": { + "details": "Pays the keeper that performs the work with a specific token", + "params": { + "_amount": "The reward that should be allocated", + "_keeper": "Address of the keeper that performed the work", + "_token": "The asset being awarded to the keeper" + } + }, + "dispute(address)": { + "params": { + "_jobOrKeeper": "The address in dispute" + } + }, + "forceLiquidityCreditsToJob(address,uint256)": { + "params": { + "_amount": "The amount of liquidity credits to gift", + "_job": "The address of the job being credited" + } + }, + "isBondedKeeper(address,address,uint256,uint256,uint256)": { + "details": "Should be used for protected functions", + "params": { + "_age": "The minimum keeper age required", + "_bond": "The bond token being evaluated", + "_earned": "The minimum funds earned in the keepers lifetime", + "_keeper": "The keeper to check", + "_minBond": "The minimum amount of bonded tokens" + }, + "returns": { + "_isBondedKeeper": "Whether the `_keeper` meets the given requirements" + } + }, + "isKeeper(address)": { + "details": "Can be used for general (non critical) functions", + "params": { + "_keeper": "The keeper being investigated" + }, + "returns": { + "_isKeeper": "Whether the address passed as a parameter is a keeper or not" + } + }, + "jobLiquidityCredits(address)": { + "params": { + "_job": "The address of the job of which we want to know the liquidity credits" + }, + "returns": { + "_liquidityCredits": "The liquidity credits of a given job" + } + }, + "jobPeriodCredits(address)": { + "params": { + "_job": "The address of the job of which we want to know the period credits" + }, + "returns": { + "_periodCredits": "The credits the given job has at the current period" + } + }, + "jobs()": { + "returns": { + "_list": "Array with all the jobs in _jobs" + } + }, + "keepers()": { + "returns": { + "_list": "Array with all the keepers in _keepers" + } + }, + "migrateJob(address,address)": { + "params": { + "_fromJob": "The address of the job that is requesting to migrate", + "_toJob": "The address at which the job is requesting to migrate" + } + }, + "observeLiquidity(address)": { + "params": { + "_liquidity": "Address of the liquidity token being observed" + } + }, + "quoteLiquidity(address,uint256)": { + "details": "_periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod", + "params": { + "_amount": "The amount of liquidity to provide", + "_liquidity": "The address of the liquidity to provide" + }, + "returns": { + "_periodCredits": "The amount of KP3R periodically minted for the given liquidity" + } + }, + "resolve(address)": { + "params": { + "_jobOrKeeper": "The address cleared" + } + }, + "revoke(address)": { + "params": { + "_keeper": "The address being slashed" + } + }, + "revokeLiquidity(address)": { + "params": { + "_liquidity": "The liquidity no longer accepted" + } + }, + "sendDust(address,uint256,address)": { + "params": { + "_amount": "The amount of the token that will be transferred", + "_to": "The address that will receive the idle funds", + "_token": "The token that will be transferred" + } + }, + "setBondTime(uint256)": { + "params": { + "_bond": "The new bond time" + } + }, + "setFee(uint256)": { + "params": { + "_fee": "The new fee" + } + }, + "setGovernance(address)": { + "params": { + "_governance": "The address being proposed as the new governance" + } + }, + "setInflationPeriod(uint256)": { + "params": { + "_inflationPeriod": "The new inflation period" + } + }, + "setKeep3rHelper(address)": { + "params": { + "_keep3rHelper": "The Keep3rHelper address" + } + }, + "setKeep3rV1(address)": { + "params": { + "_keep3rV1": "The Keep3rV1 address" + } + }, + "setKeep3rV1Proxy(address)": { + "params": { + "_keep3rV1Proxy": "The Keep3rV1Proxy address" + } + }, + "setLiquidityMinimum(uint256)": { + "params": { + "_liquidityMinimum": "The new minimum amount of liquidity" + } + }, + "setRewardPeriodTime(uint256)": { + "params": { + "_rewardPeriodTime": "The new amount of time required to pass between rewards" + } + }, + "setUnbondTime(uint256)": { + "params": { + "_unbond": "The new unbond time" + } + }, + "slash(address,address,uint256,uint256)": { + "params": { + "_bondAmount": "The bonded amount being slashed", + "_bonded": "The asset being slashed", + "_keeper": "The address being slashed", + "_unbondAmount": "The pending unbond amount being slashed" + } + }, + "slashLiquidityFromJob(address,address,uint256)": { + "params": { + "_amount": "The amount of liquidity that will be slashed", + "_job": "The address being slashed", + "_liquidity": "The address of the liquidity that will be slashed" + } + }, + "slashTokenFromJob(address,address,uint256)": { + "params": { + "_amount": "The amount of the token that will be slashed", + "_job": "The address of the job from which the token will be slashed", + "_token": "The address of the token that will be slashed" + } + }, + "totalJobCredits(address)": { + "params": { + "_job": "The address of the job of which we want to know the total credits" + }, + "returns": { + "_credits": "The total credits of the given job" + } + }, + "unbond(address,uint256)": { + "params": { + "_amount": "Allows for partial unbonding", + "_bonding": "The asset being unbonded" + } + }, + "unbondLiquidityFromJob(address,address,uint256)": { + "details": "Can only be called by the job's owner", + "params": { + "_amount": "The amount of liquidity being removed", + "_job": "The address of the job being unbonded from", + "_liquidity": "The liquidity being unbonded" + } + }, + "virtualReserves()": { + "returns": { + "_virtualReserves": "The surplus amount of wKP3Rs in escrow contract" + } + }, + "withdraw(address)": { + "params": { + "_bonding": "The asset to withdraw from the bonding pool" + } + }, + "withdrawLiquidityFromJob(address,address,address)": { + "params": { + "_job": "The address of the job being withdrawn from", + "_liquidity": "The liquidity being withdrawn", + "_receiver": "The address that will receive the withdrawn liquidity" + } + }, + "withdrawTokenCreditsFromJob(address,address,uint256,address)": { + "params": { + "_amount": "The amount of token to be withdrawn", + "_job": "The address of the job from which the credits are withdrawn", + "_receiver": "The user that will receive tokens", + "_token": "The address of the token being withdrawn" + } + }, + "worked(address)": { + "details": "Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter" + }, + "worked(address,uint256)": { + "details": "Uses a USD per gas unit payment mechanism", + "params": { + "_keeper": "Address of the keeper that performed the work", + "_usdPerGasUnit": "Units of USD (in wei) per gas unit that should be rewarded to the keeper" + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "AlreadyAJob()": [ + { + "notice": "Throws when the address that is trying to register as a job is already a job" + } + ], + "AlreadyAKeeper()": [ + { + "notice": "Throws when the address that is trying to register as a keeper is already a keeper" + } + ], + "AlreadyDisputed()": [ + { + "notice": "Throws when a job or keeper is already disputed" + } + ], + "BondsLocked()": [ + { + "notice": "Throws if the time required to bond an asset has not passed yet" + } + ], + "BondsUnexistent()": [ + { + "notice": "Throws if there are no bonded assets" + } + ], + "Deprecated()": [ + { + "notice": "Throws when job contract calls deprecated worked(address) function" + } + ], + "Disputed()": [ + { + "notice": "Throws if either a job or a keeper is disputed" + } + ], + "DisputerExistent()": [ + { + "notice": "Throws if the address is already a registered disputer" + } + ], + "DisputerUnexistent()": [ + { + "notice": "Throws if caller is not a registered disputer" + } + ], + "GasNotInitialized()": [ + { + "notice": "Throws if work method was called without calling isKeeper or isBondedKeeper" + } + ], + "InsufficientFunds()": [ + { + "notice": "Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job" + } + ], + "InsufficientJobTokenCredits()": [ + { + "notice": "Throws when the user tries to withdraw more tokens than it has" + } + ], + "JobAlreadyAdded()": [ + { + "notice": "Throws when trying to add a job that has already been added" + } + ], + "JobDisputed()": [ + { + "notice": "Throws when an action that requires an undisputed job is applied on a disputed job" + } + ], + "JobLiquidityInsufficient()": [ + { + "notice": "Throws when trying to remove more liquidity than the job has" + } + ], + "JobLiquidityLessThanMin()": [ + { + "notice": "Throws when trying to add less liquidity than the minimum liquidity required" + } + ], + "JobLiquidityUnexistent()": [ + { + "notice": "Throws when the job doesn't have the requested liquidity" + } + ], + "JobMigrationImpossible()": [ + { + "notice": "Throws when the address of the job that requests to migrate wants to migrate to its same address" + } + ], + "JobMigrationLocked()": [ + { + "notice": "Throws when cooldown between migrations has not yet passed" + } + ], + "JobMigrationUnavailable()": [ + { + "notice": "Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping" + } + ], + "JobTokenCreditsLocked()": [ + { + "notice": "Throws when the token withdraw cooldown has not yet passed" + } + ], + "JobTokenInsufficient()": [ + { + "notice": "Throws when someone tries to slash more tokens than the job has" + } + ], + "JobTokenUnexistent()": [ + { + "notice": "Throws when the token trying to be slashed doesn't exist" + } + ], + "JobUnapproved()": [ + { + "notice": "Throws if the address claiming to be a job is not in the list of approved jobs" + } + ], + "JobUnavailable()": [ + { + "notice": "Throws when an address is passed as a job, but that address is not a job" + } + ], + "LiquidityPairApproved()": [ + { + "notice": "Throws when the liquidity being approved has already been approved" + } + ], + "LiquidityPairUnapproved()": [ + { + "notice": "Throws when trying to add liquidity to an unapproved pool" + } + ], + "LiquidityPairUnexistent()": [ + { + "notice": "Throws when the liquidity being removed has not been approved" + } + ], + "MinRewardPeriod()": [ + { + "notice": "Throws if the reward period is less than the minimum reward period time" + } + ], + "NoGovernanceZeroAddress()": [ + { + "notice": "Throws if trying to set governance to zero address" + } + ], + "NotDisputed()": [ + { + "notice": "Throws when a job or keeper is not disputed and someone tries to resolve the dispute" + } + ], + "OnlyDisputer()": [ + { + "notice": "Throws if the msg.sender is not a disputer or is not a part of governance" + } + ], + "OnlyGovernance()": [ + { + "notice": "Throws if the caller of the function is not governance" + } + ], + "OnlyJobOwner()": [ + { + "notice": "Throws when the caller of the function is not the job owner" + } + ], + "OnlyPendingGovernance()": [ + { + "notice": "Throws if the caller of the function is not pendingGovernance" + } + ], + "OnlyPendingJobOwner()": [ + { + "notice": "Throws when the caller of the function is not the pending job owner" + } + ], + "OnlySlasher()": [ + { + "notice": "Throws if the msg.sender is not a slasher or is not a part of governance" + } + ], + "SlasherExistent()": [ + { + "notice": "Throws if the address is already a registered slasher" + } + ], + "SlasherUnexistent()": [ + { + "notice": "Throws if caller is not a registered slasher" + } + ], + "TokenUnallowed()": [ + { + "notice": "Throws when the token is KP3R, as it should not be used for direct token payments" + } + ], + "UnbondsLocked()": [ + { + "notice": "Throws if the time required to withdraw the bonds has not passed yet" + } + ], + "UnbondsUnexistent()": [ + { + "notice": "Throws if there are no bonds to withdraw" + } + ], + "ZeroAddress()": [ + { + "notice": "Throws if a variable is assigned to the zero address" + } + ] + }, + "events": { + "Activation(address,address,uint256)": { + "notice": "Emitted when Keep3rKeeperFundable#activate is called" + }, + "BondTimeChange(uint256)": { + "notice": "Emitted when bondTime is changed" + }, + "Bonding(address,address,uint256)": { + "notice": "Emitted when the bonding process of a new keeper begins" + }, + "Dispute(address,address)": { + "notice": "Emitted when a keeper or a job is disputed" + }, + "DisputerAdded(address)": { + "notice": "Emitted when a disputer is added" + }, + "DisputerRemoved(address)": { + "notice": "Emitted when a disputer is removed" + }, + "DustSent(address,uint256,address)": { + "notice": "Emitted when dust is sent" + }, + "FeeChange(uint256)": { + "notice": "Emitted when the fee is changed" + }, + "GovernanceProposal(address)": { + "notice": "Emitted when a new governance is proposed" + }, + "GovernanceSet(address)": { + "notice": "Emitted when pendingGovernance accepts to be governance" + }, + "InflationPeriodChange(uint256)": { + "notice": "Emitted when the inflationPeriod is changed" + }, + "JobAddition(address,address)": { + "notice": "Emitted when Keep3rJobManager#addJob is called" + }, + "JobMigrationRequested(address,address)": { + "notice": "Emitted when Keep3rJobMigration#migrateJob function is called" + }, + "JobMigrationSuccessful(address,address)": { + "notice": "Emitted when Keep3rJobMigration#acceptJobMigration function is called" + }, + "JobOwnershipAssent(address,address,address)": { + "notice": "Emitted when Keep3rJobOwnership#JobOwnershipAssent is called" + }, + "JobOwnershipChange(address,address,address)": { + "notice": "Emitted when Keep3rJobOwnership#changeJobOwnership is called" + }, + "JobSlashLiquidity(address,address,address,uint256)": { + "notice": "Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called" + }, + "JobSlashToken(address,address,address,uint256)": { + "notice": "Emitted when Keep3rJobDisputable#slashTokenFromJob is called" + }, + "Keep3rHelperChange(address)": { + "notice": "Emitted when the Keep3rHelper address is changed" + }, + "Keep3rV1Change(address)": { + "notice": "Emitted when the Keep3rV1 address is changed" + }, + "Keep3rV1ProxyChange(address)": { + "notice": "Emitted when the Keep3rV1Proxy address is changed" + }, + "KeeperRevoke(address,address)": { + "notice": "Emitted when Keep3rKeeperDisputable#revoke is called" + }, + "KeeperSlash(address,address,uint256)": { + "notice": "Emitted when Keep3rKeeperDisputable#slash is called" + }, + "KeeperValidation(uint256)": { + "notice": "Emitted when a keeper is validated before a job" + }, + "KeeperWork(address,address,address,uint256,uint256)": { + "notice": "Emitted when a keeper works a job" + }, + "LiquidityAddition(address,address,address,uint256)": { + "notice": "Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called" + }, + "LiquidityApproval(address)": { + "notice": "Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called" + }, + "LiquidityCreditsForced(address,uint256,uint256)": { + "notice": "Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called" + }, + "LiquidityCreditsReward(address,uint256,uint256,uint256)": { + "notice": "Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called" + }, + "LiquidityMinimumChange(uint256)": { + "notice": "Emitted when _liquidityMinimum is changed" + }, + "LiquidityRevocation(address)": { + "notice": "Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called" + }, + "LiquidityWithdrawal(address,address,address,uint256)": { + "notice": "Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called" + }, + "Resolve(address,address)": { + "notice": "Emitted when a dispute is resolved" + }, + "RewardPeriodTimeChange(uint256)": { + "notice": "Emitted when _rewardPeriodTime is changed" + }, + "SlasherAdded(address)": { + "notice": "Emitted when a slasher is added" + }, + "SlasherRemoved(address)": { + "notice": "Emitted when a slasher is removed" + }, + "TokenCreditAddition(address,address,address,uint256)": { + "notice": "Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called" + }, + "TokenCreditWithdrawal(address,address,address,uint256)": { + "notice": "Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called" + }, + "UnbondTimeChange(uint256)": { + "notice": "Emitted when _unbondTime is changed" + }, + "Unbonding(address,address,uint256)": { + "notice": "Emitted when a keeper or job begins the unbonding process to withdraw the funds" + }, + "Withdrawal(address,address,uint256)": { + "notice": "Emitted when Keep3rKeeperFundable#withdraw is called" + } + }, + "kind": "user", + "methods": { + "acceptGovernance()": { + "notice": "Changes the governance from the current governance to the previously proposed address" + }, + "acceptJobMigration(address,address)": { + "notice": "Completes the migration process for a job" + }, + "acceptJobOwnership(address)": { + "notice": "The proposed address accepts to be the owner of the job" + }, + "activate(address)": { + "notice": "End of the bonding process after bonding time has passed" + }, + "addDisputer(address)": { + "notice": "Registers a disputer by updating the disputers mapping" + }, + "addJob(address)": { + "notice": "Allows any caller to add a new job" + }, + "addLiquidityToJob(address,address,uint256)": { + "notice": "Allows anyone to fund a job with liquidity" + }, + "addSlasher(address)": { + "notice": "Registers a slasher by updating the slashers mapping" + }, + "addTokenCreditsToJob(address,address,uint256)": { + "notice": "Add credit to a job to be paid out for work" + }, + "approveLiquidity(address)": { + "notice": "Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20" + }, + "approvedLiquidities()": { + "notice": "Lists liquidity pairs" + }, + "bond(address,uint256)": { + "notice": "Beginning of the bonding process" + }, + "bondTime()": { + "notice": "The amount of time required to pass after a keeper has bonded assets for it to be able to activate" + }, + "bondedPayment(address,uint256)": { + "notice": "Implemented by jobs to show that a keeper performed work" + }, + "bonds(address,address)": { + "notice": "Mapping (job => bonding => amount)" + }, + "canActivateAfter(address,address)": { + "notice": "Tracks when a bonding for a keeper can be activated" + }, + "canWithdrawAfter(address,address)": { + "notice": "Tracks when keeper bonds are ready to be withdrawn" + }, + "changeJobOwnership(address,address)": { + "notice": "Proposes a new address to be the owner of the job" + }, + "directTokenPayment(address,address,uint256)": { + "notice": "Implemented by jobs to show that a keeper performed work" + }, + "dispute(address)": { + "notice": "Allows governance to create a dispute for a given keeper/job" + }, + "disputers(address)": { + "notice": "Tracks whether the address is a disputer or not" + }, + "disputes(address)": { + "notice": "Tracks if a keeper or job has a pending dispute" + }, + "fee()": { + "notice": "The fee to be sent to governance when a user adds liquidity to a job" + }, + "firstSeen(address)": { + "notice": "Tracks when a keeper was first registered" + }, + "forceLiquidityCreditsToJob(address,uint256)": { + "notice": "Gifts liquidity credits to the specified job" + }, + "governance()": { + "notice": "Stores the governance address" + }, + "hasBonded(address)": { + "notice": "Checks whether the address has ever bonded an asset" + }, + "inflationPeriod()": { + "notice": "The inflation period is the denominator used to regulate the emission of KP3R" + }, + "isBondedKeeper(address,address,uint256,uint256,uint256)": { + "notice": "Confirms if the current keeper is registered and has a minimum bond of any asset." + }, + "isKeeper(address)": { + "notice": "Confirms if the current keeper is registered" + }, + "jobLiquidityCredits(address)": { + "notice": "Returns the liquidity credits of a given job" + }, + "jobOwner(address)": { + "notice": "Maps the job to the owner of the job" + }, + "jobPendingOwner(address)": { + "notice": "Maps the job to its pending owner" + }, + "jobPeriodCredits(address)": { + "notice": "Returns the credits of a given job for the current period" + }, + "jobTokenCredits(address,address)": { + "notice": "The current token credits available for a job" + }, + "jobTokenCreditsAddedAt(address,address)": { + "notice": "Last block where tokens were added to the job" + }, + "jobs()": { + "notice": "Lists all jobs" + }, + "keep3rHelper()": { + "notice": "Address of Keep3rHelper's contract" + }, + "keep3rV1()": { + "notice": "Address of Keep3rV1's contract" + }, + "keep3rV1Proxy()": { + "notice": "Address of Keep3rV1Proxy's contract" + }, + "keepers()": { + "notice": "Lists all keepers" + }, + "liquidityAmount(address,address)": { + "notice": "Amount of liquidity in a specified job" + }, + "liquidityMinimum()": { + "notice": "The minimum amount of liquidity required to fund a job per liquidity" + }, + "migrateJob(address,address)": { + "notice": "Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping" + }, + "observeLiquidity(address)": { + "notice": "Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing" + }, + "pendingBonds(address,address)": { + "notice": "Tracks the amount of assets deposited in pending bonds" + }, + "pendingGovernance()": { + "notice": "Stores the pendingGovernance address" + }, + "pendingJobMigrations(address)": { + "notice": "Maps the jobs that have requested a migration to the address they have requested to migrate to" + }, + "pendingUnbonds(address,address)": { + "notice": "Tracks how much keeper bonds are to be withdrawn" + }, + "quoteLiquidity(address,uint256)": { + "notice": "Calculates how many credits should be rewarded periodically for a given liquidity amount" + }, + "removeDisputer(address)": { + "notice": "Removes a disputer by updating the disputers mapping" + }, + "removeSlasher(address)": { + "notice": "Removes a slasher by updating the slashers mapping" + }, + "resolve(address)": { + "notice": "Allows governance to resolve a dispute on a keeper/job" + }, + "revoke(address)": { + "notice": "Blacklists a keeper from participating in the network" + }, + "revokeLiquidity(address)": { + "notice": "Revoke a liquidity pair from being accepted in future" + }, + "rewardPeriodTime()": { + "notice": "The amount of time between each scheduled credits reward given to a job" + }, + "rewardedAt(address)": { + "notice": "Last time the job was rewarded liquidity credits" + }, + "sendDust(address,uint256,address)": { + "notice": "Allows an authorized user to transfer the tokens or eth that may have been left in a contract" + }, + "setBondTime(uint256)": { + "notice": "Sets the bond time required to activate as a keeper" + }, + "setFee(uint256)": { + "notice": "Sets the new fee" + }, + "setGovernance(address)": { + "notice": "Proposes a new address to be governance" + }, + "setInflationPeriod(uint256)": { + "notice": "Sets the new inflation period" + }, + "setKeep3rHelper(address)": { + "notice": "Sets the Keep3rHelper address" + }, + "setKeep3rV1(address)": { + "notice": "Sets the Keep3rV1 address" + }, + "setKeep3rV1Proxy(address)": { + "notice": "Sets the Keep3rV1Proxy address" + }, + "setLiquidityMinimum(uint256)": { + "notice": "Sets the minimum amount of liquidity required to fund a job" + }, + "setRewardPeriodTime(uint256)": { + "notice": "Sets the time required to pass between rewards for jobs" + }, + "setUnbondTime(uint256)": { + "notice": "Sets the unbond time required unbond what has been bonded" + }, + "slash(address,address,uint256,uint256)": { + "notice": "Allows governance to slash a keeper based on a dispute" + }, + "slashLiquidityFromJob(address,address,uint256)": { + "notice": "Allows governance or a slasher to slash liquidity from a job" + }, + "slashTokenFromJob(address,address,uint256)": { + "notice": "Allows governance or slasher to slash a job specific token" + }, + "slashers(address)": { + "notice": "Tracks whether the address is a slasher or not" + }, + "totalBonds()": { + "notice": "Tracks the total amount of bonded KP3Rs in the contract" + }, + "totalJobCredits(address)": { + "notice": "Calculates the total credits of a given job" + }, + "unbond(address,uint256)": { + "notice": "Beginning of the unbonding process" + }, + "unbondLiquidityFromJob(address,address,uint256)": { + "notice": "Unbond liquidity for a job" + }, + "unbondTime()": { + "notice": "The amount of time required to pass before a keeper can unbond what he has bonded" + }, + "virtualReserves()": { + "notice": "The surplus amount of wKP3Rs in escrow contract" + }, + "withdraw(address)": { + "notice": "Withdraw funds after unbonding has finished" + }, + "withdrawLiquidityFromJob(address,address,address)": { + "notice": "Withdraw liquidity from a job" + }, + "withdrawTokenCreditsFromJob(address,address,uint256,address)": { + "notice": "Withdraw credit from a job" + }, + "workCompleted(address)": { + "notice": "Tracks the total KP3R earnings of a keeper since it started working" + }, + "worked(address,uint256)": { + "notice": "Implemented by jobs to show that a keeper performed work" + }, + "workedAt(address)": { + "notice": "Last time the job was worked" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 10, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_status", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 8431, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "jobOwner", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 8437, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "jobPendingOwner", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 5362, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "governance", + "offset": 0, + "slot": "3", + "type": "t_address" + }, + { + "astId": 5366, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "pendingGovernance", + "offset": 0, + "slot": "4", + "type": "t_address" + }, + { + "astId": 5999, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "slashers", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 6005, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "disputers", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 5467, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_keepers", + "offset": 0, + "slot": "7", + "type": "t_struct(AddressSet)1631_storage" + }, + { + "astId": 5471, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "totalBonds", + "offset": 0, + "slot": "9", + "type": "t_uint256" + }, + { + "astId": 5477, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "workCompleted", + "offset": 0, + "slot": "10", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 5483, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "firstSeen", + "offset": 0, + "slot": "11", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 5489, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "disputes", + "offset": 0, + "slot": "12", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 5497, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "bonds", + "offset": 0, + "slot": "13", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5505, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "jobTokenCredits", + "offset": 0, + "slot": "14", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5510, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_jobLiquidityCredits", + "offset": 0, + "slot": "15", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 5515, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_jobPeriodCredits", + "offset": 0, + "slot": "16", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 5521, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_jobTokens", + "offset": 0, + "slot": "17", + "type": "t_mapping(t_address,t_struct(AddressSet)1631_storage)" + }, + { + "astId": 5527, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_jobLiquidities", + "offset": 0, + "slot": "18", + "type": "t_mapping(t_address,t_struct(AddressSet)1631_storage)" + }, + { + "astId": 5532, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_liquidityPool", + "offset": 0, + "slot": "19", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 5537, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_isKP3RToken0", + "offset": 0, + "slot": "20", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 5545, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "pendingBonds", + "offset": 0, + "slot": "21", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5553, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "canActivateAfter", + "offset": 0, + "slot": "22", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5561, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "canWithdrawAfter", + "offset": 0, + "slot": "23", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5569, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "pendingUnbonds", + "offset": 0, + "slot": "24", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5575, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "hasBonded", + "offset": 0, + "slot": "25", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 5579, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_jobs", + "offset": 0, + "slot": "26", + "type": "t_struct(AddressSet)1631_storage" + }, + { + "astId": 5692, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "keep3rV1", + "offset": 0, + "slot": "28", + "type": "t_address" + }, + { + "astId": 5696, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "keep3rV1Proxy", + "offset": 0, + "slot": "29", + "type": "t_address" + }, + { + "astId": 5700, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "keep3rHelper", + "offset": 0, + "slot": "30", + "type": "t_address" + }, + { + "astId": 5705, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "bondTime", + "offset": 0, + "slot": "31", + "type": "t_uint256" + }, + { + "astId": 5710, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "unbondTime", + "offset": 0, + "slot": "32", + "type": "t_uint256" + }, + { + "astId": 5715, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "liquidityMinimum", + "offset": 0, + "slot": "33", + "type": "t_uint256" + }, + { + "astId": 5720, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "rewardPeriodTime", + "offset": 0, + "slot": "34", + "type": "t_uint256" + }, + { + "astId": 5725, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "inflationPeriod", + "offset": 0, + "slot": "35", + "type": "t_uint256" + }, + { + "astId": 5730, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "fee", + "offset": 0, + "slot": "36", + "type": "t_uint256" + }, + { + "astId": 6432, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "jobTokenCreditsAddedAt", + "offset": 0, + "slot": "37", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 6675, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_approvedLiquidities", + "offset": 0, + "slot": "38", + "type": "t_struct(AddressSet)1631_storage" + }, + { + "astId": 6683, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "liquidityAmount", + "offset": 0, + "slot": "40", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 6689, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "rewardedAt", + "offset": 0, + "slot": "41", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 6695, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "workedAt", + "offset": 0, + "slot": "42", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 6701, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_tick", + "offset": 0, + "slot": "43", + "type": "t_mapping(t_address,t_struct(TickCache)14589_storage)" + }, + { + "astId": 8152, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "pendingJobMigrations", + "offset": 0, + "slot": "44", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 8158, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_migrationCreatedAt", + "offset": 0, + "slot": "45", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 8555, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_initialGas", + "offset": 0, + "slot": "46", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_int56": { + "encoding": "inplace", + "label": "int56", + "numberOfBytes": "7" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1631_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1631_storage" + }, + "t_mapping(t_address,t_struct(TickCache)14589_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct IKeep3rJobFundableLiquidity.TickCache)", + "numberOfBytes": "32", + "value": "t_struct(TickCache)14589_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1631_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1630, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1330_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1330_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1325, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1329, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(TickCache)14589_storage": { + "encoding": "inplace", + "label": "struct IKeep3rJobFundableLiquidity.TickCache", + "members": [ + { + "astId": 14584, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "current", + "offset": 0, + "slot": "0", + "type": "t_int56" + }, + { + "astId": 14586, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "difference", + "offset": 7, + "slot": "0", + "type": "t_int56" + }, + { + "astId": 14588, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "period", + "offset": 0, + "slot": "1", + "type": "t_uint256" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimisticEthereum/Kp3rWethOracle.json b/deployments/optimisticEthereum/Kp3rWethOracle.json new file mode 100644 index 0000000..f321698 --- /dev/null +++ b/deployments/optimisticEthereum/Kp3rWethOracle.json @@ -0,0 +1,987 @@ +{ + "address": "0x4Ab2c969C64302e5d931e5cEf4755392DC005604", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint32", + "name": "blockTimestamp", + "type": "uint32" + }, + { + "internalType": "int56", + "name": "tickCumulative", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "secondsAgos", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint128", + "name": "_liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { + "internalType": "uint128", + "name": "token0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "token1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "feeProtocol0", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "feeProtocol1", + "type": "uint8" + } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "feeProtocol", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "unlocked", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsInside", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + }, + { + "internalType": "int256", + "name": "amountSpecified", + "type": "int256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int16", + "name": "wordPosition", + "type": "int16" + } + ], + "name": "tickBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsOutside", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/optimisticEthereum/WethUsdOracle.json b/deployments/optimisticEthereum/WethUsdOracle.json new file mode 100644 index 0000000..5113ee1 --- /dev/null +++ b/deployments/optimisticEthereum/WethUsdOracle.json @@ -0,0 +1,987 @@ +{ + "address": "0x03aF20bDAaFfB4cC0A521796a223f7D85e2aAc31", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint32", + "name": "blockTimestamp", + "type": "uint32" + }, + { + "internalType": "int56", + "name": "tickCumulative", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "secondsAgos", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint128", + "name": "_liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { + "internalType": "uint128", + "name": "token0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "token1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "feeProtocol0", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "feeProtocol1", + "type": "uint8" + } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "feeProtocol", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "unlocked", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsInside", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + }, + { + "internalType": "int256", + "name": "amountSpecified", + "type": "int256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int16", + "name": "wordPosition", + "type": "int16" + } + ], + "name": "tickBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsOutside", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/optimisticEthereum/solcInputs/aa1ee30f4d8e78611039940e35c6db8b.json b/deployments/optimisticEthereum/solcInputs/aa1ee30f4d8e78611039940e35c6db8b.json new file mode 100644 index 0000000..64ef992 --- /dev/null +++ b/deployments/optimisticEthereum/solcInputs/aa1ee30f4d8e78611039940e35c6db8b.json @@ -0,0 +1,331 @@ +{ + "language": "Solidity", + "sources": { + "solidity/contracts/Keep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport './peripherals/jobs/Keep3rJobs.sol';\nimport './peripherals/keepers/Keep3rKeepers.sol';\nimport './peripherals/DustCollector.sol';\n\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\n}\n" + }, + "solidity/interfaces/IKeep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobManager.sol';\nimport './Keep3rJobWorkable.sol';\nimport './Keep3rJobDisputable.sol';\n\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\nimport './Keep3rKeeperDisputable.sol';\n\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\n" + }, + "solidity/contracts/peripherals/DustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '../../contracts/peripherals/Governable.sol';\nimport '../../interfaces/peripherals/IDustCollector.sol';\n\nabstract contract DustCollector is IDustCollector, Governable {\n using SafeERC20 for IERC20;\n\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external override onlyGovernance {\n if (_to == address(0)) revert ZeroAddress();\n if (_token == _ETH_ADDRESS) {\n payable(_to).transfer(_amount);\n } else {\n IERC20(_token).safeTransfer(_to, _amount);\n }\n emit DustSent(_token, _amount, _to);\n }\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" + }, + "solidity/interfaces/peripherals/IBaseErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" + }, + "solidity/interfaces/peripherals/IGovernable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" + }, + "solidity/interfaces/peripherals/IDustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @inheritdoc IKeep3rJobManager\n function addJob(address _job) external override {\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\n if (hasBonded[_job]) revert AlreadyAKeeper();\n _jobs.add(_job);\n jobOwner[_job] = msg.sender;\n emit JobAddition(_job, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobMigration.sol';\nimport '../../../interfaces/IKeep3rHelper.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 internal _initialGas;\n\n /// @inheritdoc IKeep3rJobWorkable\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\n _initialGas = _getGasLeft();\n if (_keepers.contains(_keeper)) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external override returns (bool _isBondedKeeper) {\n _initialGas = _getGasLeft();\n if (\n _keepers.contains(_keeper) &&\n bonds[_keeper][_bond] >= _minBond &&\n workCompleted[_keeper] >= _earned &&\n block.timestamp - firstSeen[_keeper] >= _age\n ) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function worked(address _keeper) external virtual override {\n if (_initialGas == 0) revert GasNotInitialized();\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _gasLeft = _getGasLeft();\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n _gasLeft = _getGasLeft();\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function bondedPayment(address _keeper, uint256 _payment) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (disputes[_keeper]) revert Disputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_keeper, _amount);\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\n }\n\n function _bondedPayment(\n address _job,\n address _keeper,\n uint256 _payment\n ) internal {\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\n\n workedAt[_job] = block.timestamp;\n _jobLiquidityCredits[_job] -= _payment;\n bonds[_keeper][keep3rV1] += _payment;\n workCompleted[_keeper] += _payment;\n totalBonds += _payment;\n }\n\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\n /// @param _gasLeft Amount of gas left after working the job\n /// @param _extraGas Amount of expected unaccounted gas\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\n /// @return _payment Amount to be payed in KP3R tokens\n function _calculatePayment(\n uint256 _gasLeft,\n uint256 _extraGas,\n uint256 _oneEthQuote,\n uint256 _boost\n ) internal view returns (uint256 _payment) {\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\n }\n\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\n _gasLeft = (gasleft() * 64) / 63;\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\nimport '../Keep3rDisputable.sol';\n\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\n\n try IERC20(_token).transfer(governance, _amount) {} catch {}\n jobTokenCredits[_job][_token] -= _amount;\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit JobSlashToken(_job, _token, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobPendingOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\n jobPendingOwner[_job] = _newOwner;\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\n }\n\n /// @inheritdoc IKeep3rJobOwnership\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\n address _previousOwner = jobOwner[_job];\n\n jobOwner[_job] = jobPendingOwner[_job];\n delete jobPendingOwner[_job];\n\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\n }\n\n modifier onlyJobOwner(address _job) {\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\n _;\n }\n\n modifier onlyPendingJobOwner(address _job) {\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\nimport './Keep3rRoles.sol';\n\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @notice List of all enabled keepers\n EnumerableSet.AddressSet internal _keepers;\n\n /// @inheritdoc IKeep3rAccountance\n uint256 public override totalBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override workCompleted;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override firstSeen;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override disputes;\n\n /// @inheritdoc IKeep3rAccountance\n /// @notice Mapping (job => bonding => amount)\n mapping(address => mapping(address => uint256)) public override bonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\n\n /// @notice The current liquidity credits available for a job\n mapping(address => uint256) internal _jobLiquidityCredits;\n\n /// @notice Map the address of a job to its correspondent periodCredits\n mapping(address => uint256) internal _jobPeriodCredits;\n\n /// @notice Enumerable array of Job Tokens for Credits\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\n\n /// @notice List of liquidities that a job has (job => liquidities)\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\n\n /// @notice Liquidity pool to observe\n mapping(address => address) internal _liquidityPool;\n\n /// @notice Tracks if a pool has KP3R as token0\n mapping(address => bool) internal _isKP3RToken0;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override hasBonded;\n\n /// @notice List of all enabled jobs\n EnumerableSet.AddressSet internal _jobs;\n\n /// @inheritdoc IKeep3rAccountance\n function jobs() external view override returns (address[] memory _list) {\n _list = _jobs.values();\n }\n\n /// @inheritdoc IKeep3rAccountance\n function keepers() external view override returns (address[] memory _list) {\n _list = _keepers.values();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport './DustCollector.sol';\nimport './Governable.sol';\n\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override slashers;\n\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override disputers;\n\n constructor(address _governance) Governable(_governance) DustCollector() {}\n\n /// @inheritdoc IKeep3rRoles\n function addSlasher(address _slasher) external override onlyGovernance {\n if (_slasher == address(0)) revert ZeroAddress();\n if (slashers[_slasher]) revert SlasherExistent();\n slashers[_slasher] = true;\n emit SlasherAdded(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeSlasher(address _slasher) external override onlyGovernance {\n if (!slashers[_slasher]) revert SlasherUnexistent();\n delete slashers[_slasher];\n emit SlasherRemoved(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function addDisputer(address _disputer) external override onlyGovernance {\n if (_disputer == address(0)) revert ZeroAddress();\n if (disputers[_disputer]) revert DisputerExistent();\n disputers[_disputer] = true;\n emit DisputerAdded(_disputer);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeDisputer(address _disputer) external override onlyGovernance {\n if (!disputers[_disputer]) revert DisputerUnexistent();\n delete disputers[_disputer];\n emit DisputerRemoved(_disputer);\n }\n\n /// @notice Functions with this modifier can only be called by either a slasher or governance\n modifier onlySlasher {\n if (!slashers[msg.sender]) revert OnlySlasher();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by either a disputer or governance\n modifier onlyDisputer {\n if (!disputers[msg.sender]) revert OnlyDisputer();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Governable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public override governance;\n\n /// @inheritdoc IGovernable\n address public override pendingGovernance;\n\n constructor(address _governance) {\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\n governance = _governance;\n }\n\n /// @inheritdoc IGovernable\n function setGovernance(address _governance) external override onlyGovernance {\n pendingGovernance = _governance;\n emit GovernanceProposal(_governance);\n }\n\n /// @inheritdoc IGovernable\n function acceptGovernance() external override onlyPendingGovernance {\n governance = pendingGovernance;\n delete pendingGovernance;\n emit GovernanceSet(governance);\n }\n\n /// @notice Functions with this modifier can only be called by governance\n modifier onlyGovernance {\n if (msg.sender != governance) revert OnlyGovernance();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernance\n modifier onlyPendingGovernance {\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\n _;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\n\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobMigration\n mapping(address => address) public override pendingJobMigrations;\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\n\n /// @inheritdoc IKeep3rJobMigration\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\n if (_fromJob == _toJob) revert JobMigrationImpossible();\n\n pendingJobMigrations[_fromJob] = _toJob;\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\n\n emit JobMigrationRequested(_fromJob, _toJob);\n }\n\n /// @inheritdoc IKeep3rJobMigration\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\n\n // force job credits update for both jobs\n _settleJobAccountance(_fromJob);\n _settleJobAccountance(_toJob);\n\n // migrate tokens\n while (_jobTokens[_fromJob].length() > 0) {\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\n _jobTokens[_fromJob].remove(_tokenToMigrate);\n _jobTokens[_toJob].add(_tokenToMigrate);\n }\n\n // migrate liquidities\n while (_jobLiquidities[_fromJob].length() > 0) {\n address _liquidity = _jobLiquidities[_fromJob].at(0);\n\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\n delete liquidityAmount[_fromJob][_liquidity];\n\n _jobLiquidities[_toJob].add(_liquidity);\n _jobLiquidities[_fromJob].remove(_liquidity);\n }\n\n // migrate job balances\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\n delete _jobPeriodCredits[_fromJob];\n\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\n delete _jobLiquidityCredits[_fromJob];\n\n // stop _fromJob from being a job\n delete rewardedAt[_fromJob];\n _jobs.remove(_fromJob);\n\n // delete unused data slots\n delete jobOwner[_fromJob];\n delete jobPendingOwner[_fromJob];\n delete _migrationCreatedAt[_fromJob][_toJob];\n delete pendingJobMigrations[_fromJob];\n\n emit JobMigrationSuccessful(_fromJob, _toJob);\n }\n}\n" + }, + "solidity/interfaces/IKeep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rHelperParameters.sol';\n\n/// @title Keep3rHelper contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelper is IKeep3rHelperParameters {\n // Errors\n\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\n error LiquidityPairInvalid();\n\n // Methods\n // solhint-enable func-name-mixedcase\n\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\n /// @param _eth The amount of ETH\n /// @return _amountOut The amount of KP3R\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\n\n /// @notice Returns the amount of KP3R the keeper has bonded\n /// @param _keeper The address of the keeper to check\n /// @return _amountBonded The amount of KP3R the keeper has bonded\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\n /// @param _keeper The address of the keeper to check\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\n\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\n /// @return _rewardBoost The reward boost that corresponds to the keeper\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\n\n /// @notice Given a pool address, returns the underlying tokens of the pair\n /// @param _pool Address of the correspondant pool\n /// @return _token0 Address of the first token of the pair\n /// @return _token1 Address of the second token of the pair\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\n\n /// @notice Defines the order of the tokens in the pair for twap calculations\n /// @param _pool Address of the correspondant pool\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\n\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\n /// @param _pool Address of the pool to observe\n /// @param _secondsAgo Array with time references to observe\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\n /// @return _success Boolean indicating if the observe call was succesfull\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n );\n\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\n /// @param _bonds Amount of bonded KP3R owned by the keeper\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\n /// @return _extra Amount of extra gas that should be added to the gas spent\n function getPaymentParams(uint256 _bonds)\n external\n view\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n );\n\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\n /// @param _liquidityAmount Amount of liquidity to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _kp3rAmount);\n\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\n /// @param _baseAmount Amount of token to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _quoteAmount);\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice Cooldown between withdrawals\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override nonReentrant {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n // KP3R shouldn't be used for direct token payments\n if (_token == keep3rV1) revert TokenUnallowed();\n uint256 _before = IERC20(_token).balanceOf(address(this));\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\n uint256 _tokenFee = (_received * fee) / _BASE;\n jobTokenCredits[_job][_token] += _received - _tokenFee;\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\n IERC20(_token).safeTransfer(governance, _tokenFee);\n _jobTokens[_job].add(_token);\n\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\n }\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external override nonReentrant onlyJobOwner(_job) {\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\n if (disputes[_job]) revert JobDisputed();\n\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_receiver, _amount);\n\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/IPairManager.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '../../libraries/FullMath.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice List of liquidities that are accepted in the system\n EnumerableSet.AddressSet internal _approvedLiquidities;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override rewardedAt;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override workedAt;\n\n /// @notice Tracks an address and returns its TickCache\n mapping(address => TickCache) internal _tick;\n\n // Views\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approvedLiquidities() external view override returns (address[] memory _list) {\n _list = _approvedLiquidities.values();\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n _periodCredits += _getReward(\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\n );\n }\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n\n // If the job was rewarded in the past 1 period time\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\n // If the job has period credits, update minted job credits to new twap\n _liquidityCredits = _periodCredits > 0\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\n } else {\n // Else return a full period worth of credits if current credits have expired\n _liquidityCredits = _periodCredits;\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n uint256 _cooldown = block.timestamp;\n\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\n // Will calculate cooldown if it outdated\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will calculate cooldown from last reward reference in this period\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\n } else {\n // Will calculate cooldown from last reward timestamp\n _cooldown -= rewardedAt[_job];\n }\n } else {\n // Will calculate cooldown from period start if expired\n _cooldown -= _period(block.timestamp);\n }\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\n\n if (_tick[_liquidity].period == lastPeriod) {\n // Will only ask for current period accumulator if liquidity is outdated\n uint32[] memory _secondsAgo = new uint32[](1);\n int56 previousTick = _tick[_liquidity].current;\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - previousTick;\n } else if (_tick[_liquidity].period < lastPeriod) {\n // Will ask for 2 accumulators if liquidity is expired\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n }\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Methods\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n _settleJobAccountance(_job);\n _jobLiquidityCredits[_job] += _amount;\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\n delete _liquidityPool[_liquidity];\n delete _isKP3RToken0[_liquidity];\n delete _tick[_liquidity];\n\n emit LiquidityRevocation(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override nonReentrant {\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\n if (!_jobs.contains(_job)) revert JobUnavailable();\n\n _jobLiquidities[_job].add(_liquidity);\n\n _settleJobAccountance(_job);\n\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\n liquidityAmount[_job][_liquidity] += _amount;\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlyJobOwner(_job) {\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\n pendingUnbonds[_job][_liquidity] += _amount;\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit Unbonding(_job, _liquidity, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external override onlyJobOwner(_job) {\n if (_receiver == address(0)) revert ZeroAddress();\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\n if (disputes[_job]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[_job][_liquidity];\n\n delete pendingUnbonds[_job][_liquidity];\n delete canWithdrawAfter[_job][_liquidity];\n\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\n }\n\n // Internal functions\n\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\n if (rewardedAt[_job] < _period(block.timestamp)) {\n // Will exit function if job has been rewarded in current period\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\n // Will reset job to period syncronicity if a full period passed without rewards\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] = _period(block.timestamp);\n _rewarded = true;\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will reset job's syncronicity if last reward was more than epoch ago\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] += rewardPeriodTime;\n _rewarded = true;\n } else if (workedAt[_job] < _period(block.timestamp)) {\n // First keeper on period has to update job accountance to current twaps\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\n // Updating job accountance does not reward job\n }\n }\n }\n\n /// @notice Only called if _jobLiquidityCredits < payment\n function _rewardJobCredits(address _job) internal {\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\n rewardedAt[_job] = block.timestamp;\n }\n\n /// @notice Updates accountance for _jobPeriodCredits\n function _updateJobPeriod(address _job) internal {\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\n }\n\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n if (_tick[_liquidity].period != _period(block.timestamp)) {\n // Updates liquidity cache only if needed\n _tick[_liquidity] = observeLiquidity(_liquidity);\n }\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\n }\n }\n }\n\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\n function _unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) internal nonReentrant {\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\n\n // Ensures current twaps in job liquidities\n _updateJobPeriod(_job);\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\n\n // A liquidity can be revoked causing a job to have 0 periodCredits\n if (_jobPeriodCredits[_job] > 0) {\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\n }\n\n liquidityAmount[_job][_liquidity] -= _amount;\n if (liquidityAmount[_job][_liquidity] == 0) {\n _jobLiquidities[_job].remove(_liquidity);\n }\n }\n\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\n if (_timePassed < rewardPeriodTime) {\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\n } else _result = _multiplier;\n }\n\n /// @notice Returns the start of the period of the provided timestamp\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\n return _timestamp - (_timestamp % rewardPeriodTime);\n }\n\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\n }\n\n /// @notice Returns underlying KP3R amount for a given liquidity amount\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\n if (_tick[_liquidity].period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\n }\n }\n\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\n /// @dev Ensures a maximum of 1 period of credits\n function _settleJobAccountance(address _job) internal virtual {\n _updateJobCreditsIfNeeded(_job);\n _rewardJobCredits(_job);\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/IKeep3rHelper.sol';\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\nimport './Keep3rAccountance.sol';\n\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1Proxy;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rHelper;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override bondTime = 3 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override unbondTime = 14 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override liquidityMinimum = 3 ether;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override rewardPeriodTime = 5 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override inflationPeriod = 34 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override fee = 30;\n\n /// @notice The base that will be used to calculate the fee\n uint256 internal constant _BASE = 10_000;\n\n /// @notice The minimum reward period\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) {\n keep3rHelper = _keep3rHelper;\n keep3rV1 = _keep3rV1;\n keep3rV1Proxy = _keep3rV1Proxy;\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\n if (_keep3rHelper == address(0)) revert ZeroAddress();\n keep3rHelper = _keep3rHelper;\n emit Keep3rHelperChange(_keep3rHelper);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\n if (_keep3rV1 == address(0)) revert ZeroAddress();\n _mint(totalBonds);\n\n keep3rV1 = _keep3rV1;\n emit Keep3rV1Change(_keep3rV1);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\n keep3rV1Proxy = _keep3rV1Proxy;\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\n bondTime = _bondTime;\n emit BondTimeChange(_bondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\n unbondTime = _unbondTime;\n emit UnbondTimeChange(_unbondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\n liquidityMinimum = _liquidityMinimum;\n emit LiquidityMinimumChange(_liquidityMinimum);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\n rewardPeriodTime = _rewardPeriodTime;\n emit RewardPeriodTimeChange(_rewardPeriodTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\n inflationPeriod = _inflationPeriod;\n emit InflationPeriodChange(_inflationPeriod);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setFee(uint256 _fee) external override onlyGovernance {\n fee = _fee;\n emit FeeChange(_fee);\n }\n\n function _mint(uint256 _amount) internal {\n totalBonds -= _amount;\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IGovernable.sol';\n\ninterface IKeep3rV1Proxy is IGovernable {\n // Structs\n struct Recipient {\n address recipient;\n uint256 caps;\n }\n\n // Variables\n function keep3rV1() external view returns (address);\n\n function minter() external view returns (address);\n\n function next(address) external view returns (uint256);\n\n function caps(address) external view returns (uint256);\n\n function recipients() external view returns (address[] memory);\n\n function recipientsCaps() external view returns (Recipient[] memory);\n\n // Errors\n error Cooldown();\n error NoDrawableAmount();\n error ZeroAddress();\n error OnlyMinter();\n\n // Methods\n function addRecipient(address recipient, uint256 amount) external;\n\n function removeRecipient(address recipient) external;\n\n function draw() external returns (uint256 _amount);\n\n function setKeep3rV1(address _keep3rV1) external;\n\n function setMinter(address _minter) external;\n\n function mint(uint256 _amount) external;\n\n function mint(address _account, uint256 _amount) external;\n\n function setKeep3rV1Governance(address _governance) external;\n\n function acceptKeep3rV1Governance() external;\n\n function dispute(address _keeper) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function addJob(address _job) external;\n\n function removeJob(address _job) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n}\n" + }, + "solidity/interfaces/IKeep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rHelperParameters contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelperParameters {\n // Structs\n\n /// @dev KP3R-WETH Pool address and isKP3RToken0\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\n struct TokenOraclePool {\n address poolAddress;\n bool isTKNToken0;\n }\n\n // Errors\n\n /// @notice Throws when pool does not have KP3R as token0 nor token1\n error InvalidOraclePool();\n\n // Events\n\n /// @notice Emitted when the kp3r weth pool is changed\n /// @param _address Address of the new kp3r weth pool\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\n\n /// @notice Emitted when the minimum boost multiplier is changed\n /// @param _minBoost The minimum boost multiplier\n event MinBoostChange(uint256 _minBoost);\n\n /// @notice Emitted when the maximum boost multiplier is changed\n /// @param _maxBoost The maximum boost multiplier\n event MaxBoostChange(uint256 _maxBoost);\n\n /// @notice Emitted when the target bond amount is changed\n /// @param _targetBond The target bond amount\n event TargetBondChange(uint256 _targetBond);\n\n /// @notice Emitted when the Keep3r V2 address is changed\n /// @param _keep3rV2 The address of Keep3r V2\n event Keep3rV2Change(address _keep3rV2);\n\n /// @notice Emitted when the work extra gas amount is changed\n /// @param _workExtraGas The work extra gas\n event WorkExtraGasChange(uint256 _workExtraGas);\n\n /// @notice Emitted when the quote twap time is changed\n /// @param _quoteTwapTime The twap time for quoting\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\n\n /// @notice Emitted when minimum rewarded gas fee is changed\n /// @param _minBaseFee The minimum rewarded gas fee\n event MinBaseFeeChange(uint256 _minBaseFee);\n\n /// @notice Emitted when minimum rewarded priority fee is changed\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\n event MinPriorityFeeChange(uint256 _minPriorityFee);\n\n // Variables\n\n /// @notice Address of KP3R token\n /// @return _kp3r Address of KP3R token\n // solhint-disable func-name-mixedcase\n function KP3R() external view returns (address _kp3r);\n\n /// @notice The boost base used to calculate the boost rewards for the keeper\n /// @return _base The boost base number\n function BOOST_BASE() external view returns (uint256 _base);\n\n /// @notice KP3R-WETH pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\n /// @return _multiplier The minimum boost multiplier\n function minBoost() external view returns (uint256 _multiplier);\n\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\n /// @return _multiplier The maximum boost multiplier\n function maxBoost() external view returns (uint256 _multiplier);\n\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\n /// @return _target The amount of KP3R that comforms the targetBond\n function targetBond() external view returns (uint256 _target);\n\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\n /// @return _workExtraGas The work unaccounted gas amount\n function workExtraGas() external view returns (uint256 _workExtraGas);\n\n /// @notice The twap time for quoting\n /// @return _quoteTwapTime The twap time\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\n\n /// @notice The minimum base fee that is used to calculate keeper rewards\n /// @return _minBaseFee The minimum rewarded gas fee\n function minBaseFee() external view returns (uint256 _minBaseFee);\n\n /// @notice The minimum priority fee that is also rewarded for keepers\n /// @return _minPriorityFee The minimum rewarded priority fee\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\n\n /// @notice Address of Keep3r V2\n /// @return _keep3rV2 Address of Keep3r V2\n function keep3rV2() external view returns (address _keep3rV2);\n\n // Methods\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function setKp3rWethPool(address _poolAddress) external;\n\n /// @notice Sets the minimum boost multiplier\n /// @param _minBoost The minimum boost multiplier\n function setMinBoost(uint256 _minBoost) external;\n\n /// @notice Sets the maximum boost multiplier\n /// @param _maxBoost The maximum boost multiplier\n function setMaxBoost(uint256 _maxBoost) external;\n\n /// @notice Sets the target bond amount\n /// @param _targetBond The target bond amount\n function setTargetBond(uint256 _targetBond) external;\n\n /// @notice Sets the Keep3r V2 address\n /// @param _keep3rV2 The address of Keep3r V2\n function setKeep3rV2(address _keep3rV2) external;\n\n /// @notice Sets the work extra gas amount\n /// @param _workExtraGas The work extra gas\n function setWorkExtraGas(uint256 _workExtraGas) external;\n\n /// @notice Sets the quote twap time\n /// @param _quoteTwapTime The twap time for quoting\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\n\n /// @notice Sets the minimum rewarded gas fee\n /// @param _minBaseFee The minimum rewarded gas fee\n function setMinBaseFee(uint256 _minBaseFee) external;\n\n /// @notice Sets the minimum rewarded gas priority fee\n /// @param _minPriorityFee The minimum rewarded priority fee\n function setMinPriorityFee(uint256 _minPriorityFee) external;\n}\n" + }, + "solidity/interfaces/IPairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n/// @title Pair Manager interface\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\ninterface IPairManager is IERC20Metadata {\n /// @notice Address of the factory from which the pair manager was created\n /// @return _factory The address of the PairManager Factory\n function factory() external view returns (address _factory);\n\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\n /// @return _pool The address of the pool\n function pool() external view returns (address _pool);\n\n /// @notice Token0 of the pool\n /// @return _token0 The address of token0\n function token0() external view returns (address _token0);\n\n /// @notice Token1 of the pool\n /// @return _token1 The address of token1\n function token1() external view returns (address _token1);\n}\n" + }, + "solidity/contracts/libraries/FullMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (~denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "solidity/contracts/peripherals/Keep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rParameters.sol';\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\n\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\n /// @inheritdoc IKeep3rDisputable\n function dispute(address _jobOrKeeper) external override onlyDisputer {\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\n disputes[_jobOrKeeper] = true;\n emit Dispute(_jobOrKeeper, msg.sender);\n }\n\n /// @inheritdoc IKeep3rDisputable\n function resolve(address _jobOrKeeper) external override onlyDisputer {\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\n disputes[_jobOrKeeper] = false;\n emit Resolve(_jobOrKeeper, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rKeeperFundable.sol';\nimport '../Keep3rDisputable.sol';\nimport '../../../interfaces/external/IKeep3rV1.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\n }\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function revoke(address _keeper) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _keepers.remove(_keeper);\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\n emit KeeperRevoke(_keeper, msg.sender);\n }\n\n function _slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) internal {\n if (_bonded != keep3rV1) {\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\n }\n bonds[_keeper][_bonded] -= _bondAmount;\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nimport '../../../interfaces/external/IKeep3rV1.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperFundable\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\n if (disputes[msg.sender]) revert Disputed();\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\n\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\n\n hasBonded[msg.sender] = true;\n pendingBonds[msg.sender][_bonding] += _amount;\n\n emit Bonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function activate(address _bonding) external override {\n address _keeper = msg.sender;\n if (disputes[_keeper]) revert Disputed();\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\n if (_canActivateAfter == 0) revert BondsUnexistent();\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\n\n if (firstSeen[_keeper] == 0) {\n firstSeen[_keeper] = block.timestamp;\n }\n _keepers.add(_keeper);\n\n uint256 _amount = pendingBonds[_keeper][_bonding];\n delete pendingBonds[_keeper][_bonding];\n\n // bond provided tokens\n bonds[_keeper][_bonding] += _amount;\n if (_bonding == keep3rV1) {\n totalBonds += _amount;\n _depositBonds(_amount);\n }\n\n emit Activation(_keeper, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function unbond(address _bonding, uint256 _amount) external override {\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\n bonds[msg.sender][_bonding] -= _amount;\n pendingUnbonds[msg.sender][_bonding] += _amount;\n\n emit Unbonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function withdraw(address _bonding) external override nonReentrant {\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\n if (disputes[msg.sender]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\n\n delete pendingUnbonds[msg.sender][_bonding];\n delete canWithdrawAfter[msg.sender][_bonding];\n\n if (_bonding == keep3rV1) _mint(_amount);\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(msg.sender, _bonding, _amount);\n }\n\n function _depositBonds(uint256 _amount) internal virtual {\n IKeep3rV1(keep3rV1).burn(_amount);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n// solhint-disable func-name-mixedcase\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\n // Structs\n struct Checkpoint {\n uint32 fromBlock;\n uint256 votes;\n }\n\n // Events\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event JobAdded(address indexed _job, uint256 _block, address _governance);\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\n event KeeperDispute(address indexed _keeper, uint256 _block);\n event KeeperResolved(address indexed _keeper, uint256 _block);\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\n\n // Variables\n function KPRH() external returns (address);\n\n function delegates(address _delegator) external view returns (address);\n\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\n\n function numCheckpoints(address _account) external view returns (uint32);\n\n function DOMAIN_TYPEHASH() external returns (bytes32);\n\n function DOMAINSEPARATOR() external returns (bytes32);\n\n function DELEGATION_TYPEHASH() external returns (bytes32);\n\n function PERMIT_TYPEHASH() external returns (bytes32);\n\n function nonces(address _user) external view returns (uint256);\n\n function BOND() external returns (uint256);\n\n function UNBOND() external returns (uint256);\n\n function LIQUIDITYBOND() external returns (uint256);\n\n function FEE() external returns (uint256);\n\n function BASE() external returns (uint256);\n\n function ETH() external returns (address);\n\n function bondings(address _user, address _bonding) external view returns (uint256);\n\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\n\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function bonds(address _keeper, address _bonding) external view returns (uint256);\n\n function votes(address _delegator) external view returns (uint256);\n\n function firstSeen(address _keeper) external view returns (uint256);\n\n function disputes(address _keeper) external view returns (bool);\n\n function lastJob(address _keeper) external view returns (uint256);\n\n function workCompleted(address _keeper) external view returns (uint256);\n\n function jobs(address _job) external view returns (bool);\n\n function credits(address _job, address _credit) external view returns (uint256);\n\n function liquidityProvided(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmountsUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function jobProposalDelay(address _job) external view returns (uint256);\n\n function liquidityApplied(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmount(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function keepers(address _keeper) external view returns (bool);\n\n function blacklist(address _keeper) external view returns (bool);\n\n function keeperList(uint256 _index) external view returns (address);\n\n function jobList(uint256 _index) external view returns (address);\n\n function governance() external returns (address);\n\n function pendingGovernance() external returns (address);\n\n function liquidityAccepted(address _liquidity) external view returns (bool);\n\n function liquidityPairs(uint256 _index) external view returns (address);\n\n // Methods\n function getCurrentVotes(address _account) external view returns (uint256);\n\n function addCreditETH(address _job) external payable;\n\n function addCredit(\n address _credit,\n address _job,\n uint256 _amount\n ) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function pairs() external view returns (address[] memory);\n\n function addLiquidityToJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function applyCreditToJob(\n address _provider,\n address _liquidity,\n address _job\n ) external;\n\n function unbondLiquidityFromJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function removeLiquidityFromJob(address _liquidity, address _job) external;\n\n function mint(uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n\n function worked(address _keeper) external;\n\n function receipt(\n address _credit,\n address _keeper,\n uint256 _amount\n ) external;\n\n function receiptETH(address _keeper, uint256 _amount) external;\n\n function addJob(address _job) external;\n\n function getJobs() external view returns (address[] memory);\n\n function removeJob(address _job) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function isKeeper(address _keeper) external returns (bool);\n\n function isMinKeeper(\n address _keeper,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function bond(address _bonding, uint256 _amount) external;\n\n function getKeepers() external view returns (address[] memory);\n\n function activate(address _bonding) external;\n\n function unbond(address _bonding, uint256 _amount) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function withdraw(address _bonding) external;\n\n function dispute(address _keeper) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function permit(\n address _owner,\n address _spender,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3r.sol';\n\ncontract Keep3rForTestnet is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3r.sol';\n\ncontract Keep3rForTest is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3r.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\n\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @param _governance Address of governance\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\n constructor(\n address _governance, // governance\n address _keep3rHelperSidechain, // helper\n address _wrappedKP3R, // keep3rV1\n address _keep3rEscrow // keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\n\n // Keep3rSidechainAccountance\n\n /// @inheritdoc IKeep3rSidechainAccountance\n function virtualReserves() external view override returns (int256 _virtualReserves) {\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\n }\n\n // Keep3rJobFundableLiquidity\n\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\n /// @param _liquidity Address of the liquidity token being approved\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\n /// @param _liquidity Address of the liquidity token being observed\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n\n // Will always ask for 2 accumulators in sidechain\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Keep3rJobsWorkable\n\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\n function worked(address) external pure override {\n revert Deprecated();\n }\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Uses a USD per gas unit payment mechanism\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\n if (_initialGas == 0) revert GasNotInitialized();\n // Gas used for quote calculations & payment is not rewarded\n uint256 _gasLeft = _getGasLeft();\n\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\n\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _kp3rPayment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\n }\n\n // Keep3rKeeperFundable\n\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\n function _depositBonds(uint256 _amount) internal virtual override {\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\n }\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// solhint-disable-next-line no-empty-blocks\n\nimport '../peripherals/IMintable.sol';\n\n/// @title Keep3rEscrow contract\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\ninterface IKeep3rEscrow is IMintable {\n /// @notice Emitted when Keep3rEscrow#deposit function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _sender The address that called the function\n /// @param _amount The amount of wKP3R the user deposited\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#mint function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _recipient The address that will received the newly minted wKP3R\n /// @param _amount The amount of wKP3R minted to the recipient\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\n /// @param _newWKP3R The address of the wKP3R contract\n event wKP3RSet(address _newWKP3R);\n\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\n error InsufficientBalance();\n\n /// @notice Lists the address of the wKP3R contract\n /// @return _wKP3RAddress The address of wKP3R\n function wKP3R() external view returns (address _wKP3RAddress);\n\n /// @notice Deposits wKP3R into the contract\n /// @param _amount The amount of wKP3R to deposit\n function deposit(uint256 _amount) external;\n\n /// @notice mints wKP3R to the recipient\n /// @param _amount The amount of wKP3R to mint\n function mint(uint256 _amount) external;\n\n /// @notice sets the wKP3R address\n /// @param _wKP3R the wKP3R address\n function setWKP3R(address _wKP3R) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../IKeep3rHelper.sol';\n\n/// @title Keep3rHelperSidechain contract\n/// @notice Contains all the helper functions for sidechain keep3r implementations\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\n // Events\n\n /// @notice The oracle for a liquidity has been saved\n /// @param _liquidity The address of the given liquidity\n /// @param _oraclePool The address of the oracle pool\n event OracleSet(address _liquidity, address _oraclePool);\n\n /// @notice Emitted when the WETH USD pool is changed\n /// @param _address Address of the new WETH USD pool\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\n\n /// Variables\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n /// @return _weth Address of WETH token\n // solhint-disable func-name-mixedcase\n function WETH() external view returns (address _weth);\n\n /// @return _oracle The address of the observable pool for given liquidity\n function oracle(address _liquidity) external view returns (address _oracle);\n\n /// @notice WETH-USD pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice Quotes USD to ETH\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\n /// @param _usd The amount of USD to quote to ETH\n /// @return _eth The resulting amount of ETH after quoting the USD\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\n\n /// Methods\n\n /// @notice Sets an oracle for a given liquidity\n /// @param _liquidity The address of the liquidity\n /// @param _oracle The address of the pool used to quote the liquidity from\n /// @dev The oracle must contain KP3R as either token0 or token1\n function setOracle(address _liquidity, address _oracle) external;\n\n /// @notice Sets an oracle for querying WETH/USD quote\n /// @param _poolAddress The address of the pool used as oracle\n /// @dev The oracle must contain WETH as either token0 or token1\n function setWethUsdPool(address _poolAddress) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IKeep3rJobs.sol';\n\n/// @title Keep3rJobWorkableRated contract\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\n /// @notice Throws when job contract calls deprecated worked(address) function\n error Deprecated();\n\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title IKeep3rSidechainAccountance interface\n/// @notice Implements a view to get the amount of credits that can be withdrawn\ninterface IKeep3rSidechainAccountance {\n /// @notice The surplus amount of wKP3Rs in escrow contract\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\n function virtualReserves() external view returns (int256 _virtualReserves);\n}\n" + }, + "solidity/interfaces/peripherals/IMintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IGovernable.sol';\nimport './IBaseErrors.sol';\n\n/// @title Mintable contract\n/// @notice Manages the minter role\ninterface IMintable is IBaseErrors, IGovernable {\n // Events\n\n /// @notice Emitted when governance sets a new minter\n /// @param _minter Address of the new minter\n event MinterSet(address _minter);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not the minter\n error OnlyMinter();\n\n // Variables\n\n /// @notice Stores the minter address\n /// @return _minter The minter addresss\n function minter() external view returns (address _minter);\n\n // Methods\n\n /// @notice Sets a new address to be the minter\n /// @param _minter The address set as the minter\n function setMinter(address _minter) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rSidechainForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTest is Keep3rSidechain {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _governance,\n address _keep3rHelper,\n address _wrappedKP3R,\n address _keep3rEscrow\n ) Keep3rSidechain(_governance, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n}\n" + }, + "solidity/for-test/JobRatedForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\n\ncontract JobRatedForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n uint256 public usdPerGasUnit = 1;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n}\n" + }, + "solidity/for-test/JobForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract JobForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/for-test/BasicJob.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract BasicJob {\n error KeeperNotValid();\n\n address public keep3r;\n uint256 public nonce;\n uint256[] public array;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external upkeep {}\n\n function workHard(uint256 _howHard) external upkeep {\n for (uint256 i = nonce; i < _howHard; i++) {\n nonce++;\n }\n }\n\n function workRefund(uint256 _howHard) external upkeep {\n for (uint256 i; i < _howHard; i++) {\n array.push(i);\n }\n\n while (array.length > 0) {\n array.pop();\n }\n }\n\n modifier upkeep() {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\n _;\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/peripherals/IBaseErrors.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/external/IKeep3rV1.sol';\nimport '../interfaces/IKeep3rHelperParameters.sol';\nimport './peripherals/Governable.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\n /// @inheritdoc IKeep3rHelperParameters\n address public immutable override KP3R;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public constant override BOOST_BASE = 10_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBoost = 11_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override maxBoost = 12_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override targetBond = 200 ether;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override workExtraGas = 34_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint32 public override quoteTwapTime = 10 minutes;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBaseFee = 15e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minPriorityFee = 2e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n address public override keep3rV2;\n\n /// @inheritdoc IKeep3rHelperParameters\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Governable(_governance) {\n KP3R = _kp3r;\n keep3rV2 = _keep3rV2;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setKp3rWethPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\n minBoost = _minBoost;\n emit MinBoostChange(minBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\n maxBoost = _maxBoost;\n emit MaxBoostChange(maxBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\n targetBond = _targetBond;\n emit TargetBondChange(targetBond);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\n if (_keep3rV2 == address(0)) revert ZeroAddress();\n keep3rV2 = _keep3rV2;\n emit Keep3rV2Change(keep3rV2);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\n workExtraGas = _workExtraGas;\n emit WorkExtraGasChange(workExtraGas);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\n _setQuoteTwapTime(_quoteTwapTime);\n }\n\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\n quoteTwapTime = _quoteTwapTime;\n emit QuoteTwapTimeChange(quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\n minBaseFee = _minBaseFee;\n emit MinBaseFeeChange(minBaseFee);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\n minPriorityFee = _minPriorityFee;\n emit MinPriorityFeeChange(minPriorityFee);\n }\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function _setKp3rWethPool(address _poolAddress) internal {\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\n\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\n\n return TokenOraclePool(_poolAddress, _isTKNToken0);\n }\n}\n" + }, + "solidity/contracts/libraries/TickMath.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n// solhint-disable\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n // Second inequality must be < because the price can never reach the price at the max tick\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport './pool/IUniswapV3PoolImmutables.sol';\nimport './pool/IUniswapV3PoolState.sol';\nimport './pool/IUniswapV3PoolDerivedState.sol';\nimport './pool/IUniswapV3PoolActions.sol';\nimport './pool/IUniswapV3PoolOwnerActions.sol';\nimport './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolEvents\n{\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// observationIndex The index of the last oracle observation that was written,\n /// observationCardinality The current maximum number of observations stored in the pool,\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper,\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return _liquidity The amount of liquidity in the position,\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 _liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// Returns initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" + }, + "solidity/for-test/UniV3PairManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport '../contracts/libraries/LiquidityAmounts.sol';\nimport '../contracts/libraries/FixedPoint96.sol';\nimport '../contracts/libraries/FullMath.sol';\nimport '../contracts/libraries/TickMath.sol';\nimport '../contracts/UniV3PairManager.sol';\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManagerForTest is UniV3PairManager {\n constructor(address _pool, address _governance) UniV3PairManager(_pool, _governance) {}\n\n function internalAddLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n external\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n return _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n }\n\n function internalPay(\n address token,\n address payer,\n address recipient,\n uint256 value\n ) external {\n return _pay(token, payer, recipient, value);\n }\n\n function internalMint(address dst, uint256 amount) external {\n return _mint(dst, amount);\n }\n\n function internalBurn(address dst, uint256 amount) external {\n return _burn(dst, amount);\n }\n\n function internalTransferTokens(\n address src,\n address dst,\n uint256 amount\n ) external {\n _transferTokens(src, dst, amount);\n }\n\n function internalSafeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) external {\n _safeTransferFrom(token, from, to, value);\n }\n\n receive() external payable {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "solidity/contracts/libraries/LiquidityAmounts.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport './FullMath.sol';\nimport './FixedPoint96.sol';\n\n// solhint-disable\nlibrary LiquidityAmounts {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/contracts/libraries/FixedPoint96.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nlibrary FixedPoint96 {\n // solhint-disable\n uint8 internal constant RESOLUTION = 96;\n uint256 internal constant Q96 = 0x1000000000000000000000000;\n}\n" + }, + "solidity/contracts/UniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport './libraries/LiquidityAmounts.sol';\nimport './libraries/FixedPoint96.sol';\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\n\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\nimport './peripherals/Governable.sol';\n\ncontract UniV3PairManager is IUniV3PairManager, Governable {\n /// @inheritdoc IERC20Metadata\n string public override name;\n\n /// @inheritdoc IERC20Metadata\n string public override symbol;\n\n /// @inheritdoc IERC20\n uint256 public override totalSupply;\n\n /// @inheritdoc IPairManager\n address public immutable override factory;\n\n /// @inheritdoc IPairManager\n address public immutable override token0;\n\n /// @inheritdoc IPairManager\n address public immutable override token1;\n\n /// @inheritdoc IPairManager\n address public immutable override pool;\n\n /// @inheritdoc IUniV3PairManager\n uint24 public immutable override fee;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioAX96;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioBX96;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickLower;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickUpper;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickSpacing;\n\n /// @notice Uniswap's maximum tick\n /// @dev Due to tick spacing, pools with different fees may have differences between _MAX_TICK and tickUpper. Use tickUpper to find the max tick of the pool.\n int24 private constant _MAX_TICK = 887272;\n\n /// @inheritdoc IERC20Metadata\n //solhint-disable-next-line const-name-snakecase\n uint8 public constant override decimals = 18;\n\n /// @inheritdoc IERC20\n mapping(address => mapping(address => uint256)) public override allowance;\n\n /// @inheritdoc IERC20\n mapping(address => uint256) public override balanceOf;\n\n /// @notice Struct that contains token0, token1, and fee of the Uniswap pool\n PoolKey private _poolKey;\n\n constructor(address _pool, address _governance) Governable(_governance) {\n uint24 _fee = IUniswapV3Pool(_pool).fee();\n address _token0 = IUniswapV3Pool(_pool).token0();\n address _token1 = IUniswapV3Pool(_pool).token1();\n int24 _tickSpacing = IUniswapV3Pool(_pool).tickSpacing();\n int24 _tickUpper = _MAX_TICK - (_MAX_TICK % _tickSpacing);\n int24 _tickLower = -_tickUpper;\n\n factory = msg.sender;\n pool = _pool;\n fee = _fee;\n tickSpacing = _tickSpacing;\n tickUpper = _tickUpper;\n tickLower = _tickLower;\n token0 = _token0;\n token1 = _token1;\n name = string(abi.encodePacked('Keep3rLP - ', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n symbol = string(abi.encodePacked('kLP-', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n\n sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(_tickLower);\n sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(_tickUpper);\n _poolKey = PoolKey({token0: _token0, token1: _token1, fee: _fee});\n }\n\n // This low-level function should be called from a contract which performs important safety checks\n /// @inheritdoc IUniV3PairManager\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint128 liquidity) {\n (liquidity, , ) = _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n _mint(to, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external override {\n MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));\n if (msg.sender != pool) revert OnlyPool();\n if (amount0Owed > 0) _pay(decoded._poolKey.token0, decoded.payer, pool, amount0Owed);\n if (amount1Owed > 0) _pay(decoded._poolKey.token1, decoded.payer, pool, amount1Owed);\n }\n\n /// @inheritdoc IUniV3PairManager\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint256 amount0, uint256 amount1) {\n (amount0, amount1) = IUniswapV3Pool(pool).burn(tickLower, tickUpper, liquidity);\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n\n IUniswapV3Pool(pool).collect(to, tickLower, tickUpper, uint128(amount0), uint128(amount1));\n _burn(msg.sender, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function collect() external override onlyGovernance returns (uint256 amount0, uint256 amount1) {\n (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n (amount0, amount1) = IUniswapV3Pool(pool).collect(governance, tickLower, tickUpper, tokensOwed0, tokensOwed1);\n }\n\n /// @inheritdoc IUniV3PairManager\n function position()\n external\n view\n override\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n )\n {\n (liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128, tokensOwed0, tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n }\n\n /// @inheritdoc IERC20\n function approve(address spender, uint256 amount) external override returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transfer(address to, uint256 amount) external override returns (bool) {\n _transferTokens(msg.sender, to, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool) {\n address spender = msg.sender;\n uint256 spenderAllowance = allowance[from][spender];\n\n if (spender != from && spenderAllowance != type(uint256).max) {\n uint256 newAllowance = spenderAllowance - amount;\n allowance[from][spender] = newAllowance;\n\n emit Approval(from, spender, newAllowance);\n }\n\n _transferTokens(from, to, amount);\n return true;\n }\n\n /// @notice Adds liquidity to an initialized pool\n /// @dev Reverts if the returned amount0 is less than amount0Min or if amount1 is less than amount1Min\n /// @dev This function calls the mint function of the corresponding Uniswap pool, which in turn calls UniswapV3Callback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @return liquidity The calculated liquidity we get for the token amounts we provided\n /// @return amount0 The amount of token0 we ended up providing\n /// @return amount1 The amount of token1 we ended up providing\n function _addLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n internal\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(pool).slot0();\n\n liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, amount0Desired, amount1Desired);\n\n (amount0, amount1) = IUniswapV3Pool(pool).mint(\n address(this),\n tickLower,\n tickUpper,\n liquidity,\n abi.encode(MintCallbackData({_poolKey: _poolKey, payer: msg.sender}))\n );\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n }\n\n /// @notice Transfers the passed-in token from the payer to the recipient for the corresponding value\n /// @param token The token to be transferred to the recipient\n /// @param from The address of the payer\n /// @param to The address of the passed-in tokens recipient\n /// @param value How much of that token to be transferred from payer to the recipient\n function _pay(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n _safeTransferFrom(token, from, to, value);\n }\n\n /// @notice Mints Keep3r credits to the passed-in address of recipient and increases total supply of Keep3r credits by the corresponding amount\n /// @param to The recipient of the Keep3r credits\n /// @param amount The amount Keep3r credits to be minted to the recipient\n function _mint(address to, uint256 amount) internal {\n totalSupply += amount;\n balanceOf[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @notice Burns Keep3r credits to the passed-in address of recipient and reduces total supply of Keep3r credits by the corresponding amount\n /// @param to The address that will get its Keep3r credits burned\n /// @param amount The amount Keep3r credits to be burned from the recipient/recipient\n function _burn(address to, uint256 amount) internal {\n totalSupply -= amount;\n balanceOf[to] -= amount;\n emit Transfer(to, address(0), amount);\n }\n\n /// @notice Transfers amount of Keep3r credits between two addresses\n /// @param from The user that transfers the Keep3r credits\n /// @param to The user that receives the Keep3r credits\n /// @param amount The amount of Keep3r credits to be transferred\n function _transferTokens(\n address from,\n address to,\n uint256 amount\n ) internal {\n balanceOf[from] -= amount;\n balanceOf[to] += amount;\n\n emit Transfer(from, to, amount);\n }\n\n /// @notice Transfers the passed-in token from the specified \"from\" to the specified \"to\" for the corresponding value\n /// @dev Reverts with IUniV3PairManager#UnsuccessfulTransfer if the transfer was not successful,\n /// or if the passed data length is different than 0 and the decoded data is not a boolean\n /// @param token The token to be transferred to the specified \"to\"\n /// @param from The address which is going to transfer the tokens\n /// @param value How much of that token to be transferred from \"from\" to \"to\"\n function _safeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert UnsuccessfulTransfer();\n }\n}\n" + }, + "solidity/interfaces/external/IWeth9.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IWeth9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256) external;\n}\n" + }, + "solidity/interfaces/IUniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IPairManager.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\nimport './peripherals/IGovernable.sol';\n\n/// @title Pair Manager contract\n/// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner\n/// so that the user can use it as liquidity for a Keep3rJob\ninterface IUniV3PairManager is IGovernable, IPairManager {\n // Structs\n struct PoolKey {\n address token0;\n address token1;\n uint24 fee;\n }\n\n /// @notice The data to be decoded by the UniswapV3MintCallback function\n struct MintCallbackData {\n PoolKey _poolKey; // Struct that contains token0, token1, and fee of the pool passed into the constructor\n address payer; // The address of the payer, which will be the msg.sender of the mint function\n }\n\n // Variables\n\n /// @notice The fee of the Uniswap pool passed into the constructor\n /// @return _fee The fee of the Uniswap pool passed into the constructor\n function fee() external view returns (uint24 _fee);\n\n /// @notice Highest tick in the Uniswap's curve\n /// @return _tickUpper The highest tick in the Uniswap's curve\n function tickUpper() external view returns (int24 _tickUpper);\n\n /// @notice Lowest tick in the Uniswap's curve\n /// @return _tickLower The lower tick in the Uniswap's curve\n function tickLower() external view returns (int24 _tickLower);\n\n /// @notice The pair tick spacing\n /// @return _tickSpacing The pair tick spacing\n function tickSpacing() external view returns (int24 _tickSpacing);\n\n /// @notice The sqrtRatioAX96 at the lowest tick (-887200) of the Uniswap pool\n /// @return _sqrtPriceA96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the lowest tick\n function sqrtRatioAX96() external view returns (uint160 _sqrtPriceA96);\n\n /// @notice The sqrtRatioBX96 at the highest tick (887200) of the Uniswap pool\n /// @return _sqrtPriceBX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the highest tick\n function sqrtRatioBX96() external view returns (uint160 _sqrtPriceBX96);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the pool\n error OnlyPool();\n\n /// @notice Throws when the slippage exceeds what the user is comfortable with\n error ExcessiveSlippage();\n\n /// @notice Throws when a transfer is unsuccessful\n error UnsuccessfulTransfer();\n\n // Methods\n\n /// @notice This function is called after a user calls IUniV3PairManager#mint function\n /// It ensures that any tokens owed to the pool are paid by the msg.sender of IUniV3PairManager#mint function\n /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity\n /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity\n /// @param data The encoded token0, token1, fee (_poolKey) and the payer (msg.sender) of the IUniV3PairManager#mint function\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external;\n\n /// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool\n /// @dev Triggers UniV3PairManager#uniswapV3MintCallback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @param to The address to which the kLP tokens are going to be minted to\n /// @return liquidity kLP tokens sent in exchange for the provision of tokens\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint128 liquidity);\n\n /// @notice Returns the pair manager's position in the corresponding UniswapV3 pool\n /// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager\n /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position\n /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position\n /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation\n /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation\n function position()\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees\n // owed to a specific position to the recipient, in this case, that recipient is the pair manager\n /// @dev The collected fees will be sent to governance\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect() external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity\n // in the entire range\n /// @param liquidity The amount of liquidity to be burned\n /// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)\n /// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)\n /// @param to The address that will receive the due fees\n /// @return amount0 The calculated amount of token0 that will be sent to the recipient\n /// @return amount1 The calculated amount of token1 that will be sent to the recipient\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint256 amount0, uint256 amount1);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "solidity/interfaces/IPairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IGovernable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ninterface IPairManagerFactory is IGovernable {\n // Variables\n\n /// @notice Maps the address of a Uniswap pool, to the address of the corresponding PairManager\n /// For example, the uniswap address of DAI-WETH, will return the Keep3r/DAI-WETH pair manager address\n /// @param _pool The address of the Uniswap pool\n /// @return _pairManager The address of the corresponding pair manager\n function pairManagers(address _pool) external view returns (address _pairManager);\n\n // Events\n\n /// @notice Emitted when a new pair manager is created\n /// @param _pool The address of the corresponding Uniswap pool\n /// @param _pairManager The address of the just-created pair manager\n event PairCreated(address _pool, address _pairManager);\n\n // Errors\n\n /// @notice Throws an error if the pair manager is already initialized\n error AlreadyInitialized();\n\n /// @notice Throws an error if the caller is not the owner\n error OnlyOwner();\n\n // Methods\n\n /// @notice Creates a new pair manager based on the address of a Uniswap pool\n /// For example, the uniswap address of DAI-WETH, will create the Keep3r/DAI-WETH pool\n /// @param _pool The address of the Uniswap pool the pair manager will be based of\n /// @return _pairManager The address of the just-created pair manager\n function createPairManager(address _pool) external returns (address _pairManager);\n}\n" + }, + "solidity/contracts/UniV3PairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IPairManagerFactory.sol';\nimport './UniV3PairManager.sol';\nimport './peripherals/Governable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ncontract UniV3PairManagerFactory is IPairManagerFactory, Governable {\n mapping(address => address) public override pairManagers;\n\n constructor(address _governance) Governable(_governance) {}\n\n ///@inheritdoc IPairManagerFactory\n function createPairManager(address _pool) external override returns (address _pairManager) {\n if (pairManagers[_pool] != address(0)) revert AlreadyInitialized();\n _pairManager = address(new UniV3PairManager(_pool, governance));\n pairManagers[_pool] = _pairManager;\n emit PairCreated(_pool, _pairManager);\n }\n}\n" + }, + "solidity/for-test/peripherals/GovernableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" + }, + "solidity/for-test/BridgeForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ncontract BridgeForTest is ERC20 {\n address public immutable kp3r;\n\n constructor(address _kp3r) ERC20('Wrapped KP3R', 'wKP3R') {\n kp3r = _kp3r;\n }\n\n function bridge(uint256 _amount) external {\n IERC20(kp3r).transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n }\n\n function bridgeBack(uint256 _amount) external {\n _burn(msg.sender, _amount);\n IERC20(kp3r).transfer(msg.sender, _amount);\n }\n}\n" + }, + "solidity/for-test/ERC20ForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(uint256 _amount) public {\n _mint(msg.sender, _amount);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(uint256 _amount) public {\n _burn(msg.sender, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n function deposit() external payable {\n // Function added for compatibility with WETH\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperFundableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperFundable.sol';\n\ncontract Keep3rKeeperFundableForTest is Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function isKeeper(address _keeper) external view returns (bool) {\n return _keepers.contains(_keeper);\n }\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/Mintable.sol';\nimport '../peripherals/DustCollector.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rEscrow\n address public override wKP3R;\n\n /// @param _governance Address of governance\n /// @param _wKP3R Address of wrapped KP3R implementation\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\n wKP3R = _wKP3R;\n }\n\n /// @inheritdoc IKeep3rEscrow\n function deposit(uint256 _amount) external override {\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function mint(uint256 _amount) external override onlyMinter {\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function setWKP3R(address _wKP3R) external override onlyGovernance {\n if (_wKP3R == address(0)) revert ZeroAddress();\n wKP3R = _wKP3R;\n emit wKP3RSet(wKP3R);\n }\n}\n" + }, + "solidity/contracts/peripherals/Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IMintable.sol';\nimport './Governable.sol';\n\nabstract contract Mintable is Governable, IMintable {\n /// @inheritdoc IMintable\n address public override minter;\n\n constructor(address _governance) Governable(_governance) {}\n\n /// @inheritdoc IMintable\n function setMinter(address _minter) external override onlyGovernance {\n if (_minter == address(0)) revert ZeroAddress();\n minter = _minter;\n emit MinterSet(_minter);\n }\n\n /// @notice Functions with this modifier can only be called by the minter;\n modifier onlyMinter() {\n if (msg.sender != minter) revert OnlyMinter();\n _;\n }\n}\n" + }, + "solidity/for-test/peripherals/DustCollectorForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/DustCollector.sol';\n\ncontract DustCollectorForTest is DustCollector {\n constructor() DustCollector() Governable(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rAccountanceForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rAccountance.sol';\n\ncontract Keep3rAccountanceForTest is Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor() Keep3rRoles(msg.sender) {}\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n\n function setKeeper(address keeper) external {\n _keepers.add(keeper);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableLiquidityForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol';\n\ncontract Keep3rJobFundableLiquidityForTest is Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external returns (bool) {\n return _jobLiquidities[_job].add(_liquidity);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewTickOrder(address _liquidity) external view returns (bool) {\n return _isKP3RToken0[_liquidity];\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function internalSettleJobAccountance(address _job) external {\n _settleJobAccountance(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobDisputable.sol';\n\ncontract Keep3rJobDisputableForTest is Keep3rJobDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function internalJobLiquidityCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobLiquidityCredits[_job];\n }\n\n function internalJobPeriodCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobPeriodCredits[_job];\n }\n\n function internalJobTokens(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobTokens[_job].length());\n for (uint256 i; i < _jobTokens[_job].length(); i++) {\n _tokens[i] = _jobTokens[_job].at(i);\n }\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobLiquidities[_job].length());\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n _tokens[i] = _jobLiquidities[_job].at(i);\n }\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rDisputable.sol';\n\ncontract Keep3rDisputableForTest is Keep3rDisputable {\n constructor() Keep3rParameters(address(0), address(0), address(0)) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperDisputable.sol';\n\ncontract Keep3rKeeperDisputableForTest is Keep3rKeeperDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function internalSlash(\n address _bonded,\n address _keeper,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external {\n _slash(_bonded, _keeper, _bondAmount, _unbondAmount);\n }\n\n function isKeeper(address _address) external view returns (bool _isKeeper) {\n _isKeeper = _keepers.contains(_address);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableCreditsForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableCredits.sol';\n\ncontract Keep3rJobFundableCreditsForTest is Keep3rJobFundableCredits {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job, address _jobOwner) external {\n _jobs.add(_job);\n jobOwner[_job] = _jobOwner;\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function isJobToken(address _job, address _token) external view returns (bool _contains) {\n _contains = _jobTokens[_job].contains(_token);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/IKeep3rHelper.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n /// @inheritdoc IKeep3rHelper\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelper\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\n // solhint-disable-next-line avoid-tx-origin\n return getRewardAmountFor(tx.origin, _gasUsed);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\n _bonds = Math.min(_bonds, targetBond);\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\n _rewardBoost = _cap * _getBasefee();\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\n }\n\n /// @inheritdoc IKeep3rHelper\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\n address _token0;\n address _token1;\n (_token0, _token1) = getPoolTokens(_pool);\n if (_token0 == KP3R) {\n return true;\n } else if (_token1 != KP3R) {\n revert LiquidityPairInvalid();\n }\n }\n\n /// @inheritdoc IKeep3rHelper\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n override\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n )\n {\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\n _tickCumulative1 = _uniswapResponse[0];\n if (_uniswapResponse.length > 1) {\n _tickCumulative2 = _uniswapResponse[1];\n }\n _success = true;\n } catch (bytes memory) {}\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n )\n {\n _oneEthQuote = quote(1 ether);\n _boost = getRewardBoostFor(_bonds);\n _extra = workExtraGas;\n }\n\n /// @inheritdoc IKeep3rHelper\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure override returns (uint256 _kp3rAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) public pure override returns (uint256 _quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\n }\n }\n\n /// @notice Gets the gas basefee cost to calculate keeper rewards\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTestnet is Keep3rHelper {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal pure override returns (uint256) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/Keep3rHelperForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTest is Keep3rHelper {\n uint256 public basefee;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal view override returns (uint256) {\n return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee();\n }\n\n function setBaseFee(uint256 _baseFee) external {\n basefee = _baseFee;\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rHelper.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\n /// @inheritdoc IKeep3rHelperSidechain\n mapping(address => address) public override oracle;\n /// @inheritdoc IKeep3rHelperSidechain\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n address public immutable override WETH;\n\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\n /// @param _governance Address of governance\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\n /// @dev Oracle pools should use 18 decimals tokens\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\n WETH = _weth;\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\n _setQuoteTwapTime(1 days);\n workExtraGas = 0;\n }\n\n /// @inheritdoc IKeep3rHelper\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\n oracle[_liquidity] = _oracle;\n emit OracleSet(_liquidity, _oracle);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n /// @dev Oracle is compatible with IUniswapV3Pool\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setWethUsdPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override(Keep3rHelper, IKeep3rHelper)\n returns (\n uint256 _boost,\n uint256 _oneUsdQuote,\n uint256 _extraGas\n )\n {\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\n _boost = getRewardBoostFor(_bonds);\n _extraGas = workExtraGas;\n }\n\n function _setWethUsdPool(address _poolAddress) internal {\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\n }\n\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rParametersForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rParameters.sol';\n\ncontract Keep3rParametersForTest is Keep3rParameters {\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobWorkableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobWorkable.sol';\n\ncontract Keep3rJobWorkableForTest is Keep3rJobWorkable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewGas() external view returns (uint256) {\n return _initialGas;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobMigrationForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobMigration.sol';\n\ncontract Keep3rJobMigrationForTest is Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(address => uint256) public settleJobAccountanceCallCount;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobTokenListLength(address _job) external view returns (uint256) {\n return _jobTokens[_job].length();\n }\n\n function viewJobLiquidityList(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewMigrationCreatedAt(address _fromJob, address _toJob) external view returns (uint256) {\n return _migrationCreatedAt[_fromJob][_toJob];\n }\n\n function isJob(address _job) external view returns (bool) {\n return _jobs.contains(_job);\n }\n\n function _settleJobAccountance(address _job) internal override {\n settleJobAccountanceCallCount[_job]++;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobManager.sol';\n\ncontract Keep3rJobManagerForTest is Keep3rJobManager {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rRoles(msg.sender) {}\n\n function isJob(address _job) external view returns (bool _isJob) {\n _isJob = _jobs.contains(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobOwnershipForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobOwnership.sol';\n\ncontract Keep3rJobOwnershipForTest is Keep3rJobOwnership {}\n" + }, + "solidity/for-test/libraries/LiquidityAmountsForTest.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/libraries/FullMath.sol';\nimport '../../contracts/libraries/FixedPoint96.sol';\n\n/// @dev Made this library into a contract to be able to calculate liquidity more precisely for tests\n\n// solhint-disable\ncontract LiquidityAmountsForTest {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) external pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) external pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/for-test/IUniswapV3PoolForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n// solhint-disable-next-line no-empty-blocks\ninterface IUniswapV3PoolForTest is IERC20Minimal, IUniswapV3Pool {\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Minimal ERC20 interface for Uniswap\n/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3\ninterface IERC20Minimal {\n /// @notice Returns the balance of a token\n /// @param account The account for which to look up the number of tokens it has, i.e. its balance\n /// @return The number of tokens held by the account\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Transfers the amount of token from the `msg.sender` to the recipient\n /// @param recipient The account that will receive the amount transferred\n /// @param amount The number of tokens to send from the sender to the recipient\n /// @return Returns true for a successful transfer, false for an unsuccessful transfer\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /// @notice Returns the current allowance given to a spender by an owner\n /// @param owner The account of the token owner\n /// @param spender The account of the token spender\n /// @return The current allowance granted by `owner` to `spender`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`\n /// @param spender The account which will be allowed to spend a given amount of the owners tokens\n /// @param amount The amount of tokens allowed to be used by `spender`\n /// @return Returns true for a successful approval, false for unsuccessful\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`\n /// @param sender The account from which the transfer will be initiated\n /// @param recipient The recipient of the transfer\n /// @param amount The amount of the transfer\n /// @return Returns true for a successful transfer, false for unsuccessful\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.\n /// @param from The account from which the tokens were sent, i.e. the balance decreased\n /// @param to The account to which the tokens were sent, i.e. the balance increased\n /// @param value The amount of tokens that were transferred\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.\n /// @param owner The account that approved spending of its tokens\n /// @param spender The account for which the spending allowance was modified\n /// @param value The new allowance from the owner to the spender\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimisticGoerli/BasicJob.json b/deployments/optimisticGoerli/BasicJob.json index c58669b..8705da1 100644 --- a/deployments/optimisticGoerli/BasicJob.json +++ b/deployments/optimisticGoerli/BasicJob.json @@ -1,5 +1,5 @@ { - "address": "0x8276688087b581A9e9d18FD88FbB5E66bAa43682", + "address": "0x9abB5cfF47b9F604351a6f0730d9fe39Fb620B2b", "abi": [ { "inputs": [ @@ -77,30 +77,30 @@ "type": "function" } ], - "transactionHash": "0xb0a6c4e7e192a86dc62a906e92a2d41128fde200a6b10664d391c44174b1a867", + "transactionHash": "0xfdc0a295f18e45d3c4c3ec32762d2aa0fdf2c7f2beda4eef821040aca53ce133", "receipt": { "to": null, "from": "0x258b180E741157763236F5277619D71ECf00B906", - "contractAddress": "0x8276688087b581A9e9d18FD88FbB5E66bAa43682", + "contractAddress": "0x9abB5cfF47b9F604351a6f0730d9fe39Fb620B2b", "transactionIndex": 0, - "gasUsed": "333592", + "gasUsed": "333540", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5d397e494997438c06ad177cfd57240baae25e9f97d9464db15d13d38753d55c", - "transactionHash": "0xb0a6c4e7e192a86dc62a906e92a2d41128fde200a6b10664d391c44174b1a867", + "blockHash": "0x8bb06121b60b56f2b67c5ec7f2a67e691cb6de533ac8f99c326374c7e6f89e08", + "transactionHash": "0xfdc0a295f18e45d3c4c3ec32762d2aa0fdf2c7f2beda4eef821040aca53ce133", "logs": [], - "blockNumber": 3073821, - "cumulativeGasUsed": "333592", + "blockNumber": 3238239, + "cumulativeGasUsed": "333540", "status": 1, "byzantium": true }, "args": [ - "0x3C9636ab56aced6C845d6D13805901A0a0B13b51" + "0x85063437C02Ba7F4f82F898859e4992380DEd3bb" ], - "numDeployments": 1, - "solcInputHash": "a2dd8c00aab95ba5d841446478d867fa", - "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3r\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidKeeper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"keep3r\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"usdPerGasUnit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"work\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_factor\",\"type\":\"uint256\"}],\"name\":\"workHard\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/JobRatedForTest.sol\":\"JobRatedForTest\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"solidity/for-test/JobRatedForTest.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\\n\\ncontract JobRatedForTest {\\n error InvalidKeeper();\\n address public keep3r;\\n uint256 public nonce;\\n uint256 public usdPerGasUnit = 1_000e9;\\n\\n constructor(address _keep3r) {\\n keep3r = _keep3r;\\n }\\n\\n function work() external {\\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\\n\\n for (uint256 i = 0; i < 1000; i++) {\\n nonce++;\\n }\\n\\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\\n }\\n\\n function workHard(uint256 _factor) external {\\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\\n\\n for (uint256 i = 0; i < 1000 * _factor; i++) {\\n nonce++;\\n }\\n\\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\\n }\\n}\\n\",\"keccak256\":\"0xd11e0b720651173330b0b9629586ceb7d0fd88e6babf25b4071f9b432aebcc8b\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0x060f701c6991d323bcf360738568714956013b17b3e3443ea21d825a70c3947c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IKeep3rJobs.sol';\\n\\n/// @title Keep3rJobWorkableRated contract\\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\\n /// @notice Throws when job contract calls deprecated worked(address) function\\n error Deprecated();\\n\\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\\n}\\n\",\"keccak256\":\"0xce2c2721f1df7d944bf3ae20331cb628d38247e667c47bf4a33a90f0b5753884\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405264e8d4a5100060025534801561001957600080fd5b506040516104d73803806104d78339810160408190526100389161005d565b600080546001600160a01b0319166001600160a01b039290921691909117905561008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b61043b8061009c6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063322e9f041461005c5780633bb39c3314610066578063634c7bb5146100795780639ecc0b95146100a2578063affed0e0146100b9575b600080fd5b6100646100c2565b005b61006461007436600461036f565b6101ff565b60005461008c906001600160a01b031681565b6040516100999190610388565b60405180910390f35b6100ab60025481565b604051908152602001610099565b6100ab60015481565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa906100f2903390600401610388565b602060405180830381600087803b15801561010c57600080fd5b505af1158015610120573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101449190610346565b61016157604051637671ff4960e11b815260040160405180910390fd5b60005b6103e8811015610196576001805490600061017e836103d4565b9190505550808061018e906103d4565b915050610164565b5060005460025460405163b70362b960e01b81526001600160a01b039092169163b70362b9916101cb9133919060040161039c565b600060405180830381600087803b1580156101e557600080fd5b505af11580156101f9573d6000803e3d6000fd5b50505050565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa9061022f903390600401610388565b602060405180830381600087803b15801561024957600080fd5b505af115801561025d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102819190610346565b61029e57604051637671ff4960e11b815260040160405180910390fd5b60005b6102ad826103e86103b5565b8110156102dc57600180549060006102c4836103d4565b919050555080806102d4906103d4565b9150506102a1565b5060005460025460405163b70362b960e01b81526001600160a01b039092169163b70362b9916103119133919060040161039c565b600060405180830381600087803b15801561032b57600080fd5b505af115801561033f573d6000803e3d6000fd5b5050505050565b60006020828403121561035857600080fd5b8151801515811461036857600080fd5b9392505050565b60006020828403121561038157600080fd5b5035919050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b60008160001904831182151516156103cf576103cf6103ef565b500290565b60006000198214156103e8576103e86103ef565b5060010190565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220f18ae7a410659fe88554754a2b5bfc836f9c0766aea4c91bb389b9970940838d64736f6c63430008070033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c8063322e9f041461005c5780633bb39c3314610066578063634c7bb5146100795780639ecc0b95146100a2578063affed0e0146100b9575b600080fd5b6100646100c2565b005b61006461007436600461036f565b6101ff565b60005461008c906001600160a01b031681565b6040516100999190610388565b60405180910390f35b6100ab60025481565b604051908152602001610099565b6100ab60015481565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa906100f2903390600401610388565b602060405180830381600087803b15801561010c57600080fd5b505af1158015610120573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101449190610346565b61016157604051637671ff4960e11b815260040160405180910390fd5b60005b6103e8811015610196576001805490600061017e836103d4565b9190505550808061018e906103d4565b915050610164565b5060005460025460405163b70362b960e01b81526001600160a01b039092169163b70362b9916101cb9133919060040161039c565b600060405180830381600087803b1580156101e557600080fd5b505af11580156101f9573d6000803e3d6000fd5b50505050565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa9061022f903390600401610388565b602060405180830381600087803b15801561024957600080fd5b505af115801561025d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102819190610346565b61029e57604051637671ff4960e11b815260040160405180910390fd5b60005b6102ad826103e86103b5565b8110156102dc57600180549060006102c4836103d4565b919050555080806102d4906103d4565b9150506102a1565b5060005460025460405163b70362b960e01b81526001600160a01b039092169163b70362b9916103119133919060040161039c565b600060405180830381600087803b15801561032b57600080fd5b505af115801561033f573d6000803e3d6000fd5b5050505050565b60006020828403121561035857600080fd5b8151801515811461036857600080fd5b9392505050565b60006020828403121561038157600080fd5b5035919050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b60008160001904831182151516156103cf576103cf6103ef565b500290565b60006000198214156103e8576103e86103ef565b5060010190565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220f18ae7a410659fe88554754a2b5bfc836f9c0766aea4c91bb389b9970940838d64736f6c63430008070033", + "numDeployments": 2, + "solcInputHash": "f7e3e740337524d02345ab2e7585c15c", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3r\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidKeeper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"keep3r\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"usdPerGasUnit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"work\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_factor\",\"type\":\"uint256\"}],\"name\":\"workHard\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/JobRatedForTest.sol\":\"JobRatedForTest\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"solidity/for-test/JobRatedForTest.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\\n\\ncontract JobRatedForTest {\\n error InvalidKeeper();\\n address public keep3r;\\n uint256 public nonce;\\n uint256 public usdPerGasUnit = 1;\\n\\n constructor(address _keep3r) {\\n keep3r = _keep3r;\\n }\\n\\n function work() external {\\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\\n\\n for (uint256 i = 0; i < 1000; i++) {\\n nonce++;\\n }\\n\\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\\n }\\n\\n function workHard(uint256 _factor) external {\\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\\n\\n for (uint256 i = 0; i < 1000 * _factor; i++) {\\n nonce++;\\n }\\n\\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\\n }\\n}\\n\",\"keccak256\":\"0x235a0959e11d21a0d729be34f808b1648d0654c5d6f3893806cba610a1f8473a\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0xf4748c236ddf409e45e7169c735e2fc54e627b2b3ccd189ebb438ad768f1deb1\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IKeep3rJobs.sol';\\n\\n/// @title Keep3rJobWorkableRated contract\\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\\n /// @notice Throws when job contract calls deprecated worked(address) function\\n error Deprecated();\\n\\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\\n}\\n\",\"keccak256\":\"0xce2c2721f1df7d944bf3ae20331cb628d38247e667c47bf4a33a90f0b5753884\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052600160025534801561001557600080fd5b506040516104d33803806104d383398101604081905261003491610059565b600080546001600160a01b0319166001600160a01b0392909216919091179055610089565b60006020828403121561006b57600080fd5b81516001600160a01b038116811461008257600080fd5b9392505050565b61043b806100986000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063322e9f041461005c5780633bb39c3314610066578063634c7bb5146100795780639ecc0b95146100a2578063affed0e0146100b9575b600080fd5b6100646100c2565b005b61006461007436600461036f565b6101ff565b60005461008c906001600160a01b031681565b6040516100999190610388565b60405180910390f35b6100ab60025481565b604051908152602001610099565b6100ab60015481565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa906100f2903390600401610388565b602060405180830381600087803b15801561010c57600080fd5b505af1158015610120573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101449190610346565b61016157604051637671ff4960e11b815260040160405180910390fd5b60005b6103e8811015610196576001805490600061017e836103d4565b9190505550808061018e906103d4565b915050610164565b5060005460025460405163b70362b960e01b81526001600160a01b039092169163b70362b9916101cb9133919060040161039c565b600060405180830381600087803b1580156101e557600080fd5b505af11580156101f9573d6000803e3d6000fd5b50505050565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa9061022f903390600401610388565b602060405180830381600087803b15801561024957600080fd5b505af115801561025d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102819190610346565b61029e57604051637671ff4960e11b815260040160405180910390fd5b60005b6102ad826103e86103b5565b8110156102dc57600180549060006102c4836103d4565b919050555080806102d4906103d4565b9150506102a1565b5060005460025460405163b70362b960e01b81526001600160a01b039092169163b70362b9916103119133919060040161039c565b600060405180830381600087803b15801561032b57600080fd5b505af115801561033f573d6000803e3d6000fd5b5050505050565b60006020828403121561035857600080fd5b8151801515811461036857600080fd5b9392505050565b60006020828403121561038157600080fd5b5035919050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b60008160001904831182151516156103cf576103cf6103ef565b500290565b60006000198214156103e8576103e86103ef565b5060010190565b634e487b7160e01b600052601160045260246000fdfea26469706673582212202e08507f46886e2b4b905e75ba7caed9cd3428ceb92934589b747ae6092aa66064736f6c63430008070033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c8063322e9f041461005c5780633bb39c3314610066578063634c7bb5146100795780639ecc0b95146100a2578063affed0e0146100b9575b600080fd5b6100646100c2565b005b61006461007436600461036f565b6101ff565b60005461008c906001600160a01b031681565b6040516100999190610388565b60405180910390f35b6100ab60025481565b604051908152602001610099565b6100ab60015481565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa906100f2903390600401610388565b602060405180830381600087803b15801561010c57600080fd5b505af1158015610120573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101449190610346565b61016157604051637671ff4960e11b815260040160405180910390fd5b60005b6103e8811015610196576001805490600061017e836103d4565b9190505550808061018e906103d4565b915050610164565b5060005460025460405163b70362b960e01b81526001600160a01b039092169163b70362b9916101cb9133919060040161039c565b600060405180830381600087803b1580156101e557600080fd5b505af11580156101f9573d6000803e3d6000fd5b50505050565b6000546040516335d2155560e11b81526001600160a01b0390911690636ba42aaa9061022f903390600401610388565b602060405180830381600087803b15801561024957600080fd5b505af115801561025d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102819190610346565b61029e57604051637671ff4960e11b815260040160405180910390fd5b60005b6102ad826103e86103b5565b8110156102dc57600180549060006102c4836103d4565b919050555080806102d4906103d4565b9150506102a1565b5060005460025460405163b70362b960e01b81526001600160a01b039092169163b70362b9916103119133919060040161039c565b600060405180830381600087803b15801561032b57600080fd5b505af115801561033f573d6000803e3d6000fd5b5050505050565b60006020828403121561035857600080fd5b8151801515811461036857600080fd5b9392505050565b60006020828403121561038157600080fd5b5035919050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b60008160001904831182151516156103cf576103cf6103ef565b500290565b60006000198214156103e8576103e86103ef565b5060010190565b634e487b7160e01b600052601160045260246000fdfea26469706673582212202e08507f46886e2b4b905e75ba7caed9cd3428ceb92934589b747ae6092aa66064736f6c63430008070033", "devdoc": { "kind": "dev", "methods": {}, @@ -114,7 +114,7 @@ "storageLayout": { "storage": [ { - "astId": 10865, + "astId": 10848, "contract": "solidity/for-test/JobRatedForTest.sol:JobRatedForTest", "label": "keep3r", "offset": 0, @@ -122,7 +122,7 @@ "type": "t_address" }, { - "astId": 10867, + "astId": 10850, "contract": "solidity/for-test/JobRatedForTest.sol:JobRatedForTest", "label": "nonce", "offset": 0, @@ -130,7 +130,7 @@ "type": "t_uint256" }, { - "astId": 10870, + "astId": 10853, "contract": "solidity/for-test/JobRatedForTest.sol:JobRatedForTest", "label": "usdPerGasUnit", "offset": 0, @@ -151,4 +151,4 @@ } } } -} +} \ No newline at end of file diff --git a/deployments/optimisticGoerli/KP3Rv1.json b/deployments/optimisticGoerli/KP3Rv1.json index 6c1d51b..043d796 100644 --- a/deployments/optimisticGoerli/KP3Rv1.json +++ b/deployments/optimisticGoerli/KP3Rv1.json @@ -185,5 +185,5 @@ "type": "function" } ], - "numDeployments": 3 + "numDeployments": 5 } \ No newline at end of file diff --git a/deployments/optimisticGoerli/Keep3rEscrow.json b/deployments/optimisticGoerli/Keep3rEscrow.json index 62d8d2c..e7050de 100644 --- a/deployments/optimisticGoerli/Keep3rEscrow.json +++ b/deployments/optimisticGoerli/Keep3rEscrow.json @@ -1,5 +1,5 @@ { - "address": "0xb4A7137B024d4C0531b0164fCb6E8fc20e6777Ae", + "address": "0xBa4A759E41cCA14980bE4106792cdAC5F7BeDF83", "abi": [ { "inputs": [ @@ -322,28 +322,28 @@ "type": "function" } ], - "transactionHash": "0x13931e2dae3a7a4cf3acfd902276f17808a977bacd1bff089ace0e93c1841cf0", + "transactionHash": "0x04ac7849ec511257a2b9e76962ae793898ae91cafaf363eaaa25c091ac6445b0", "receipt": { "to": null, "from": "0x258b180E741157763236F5277619D71ECf00B906", - "contractAddress": "0xb4A7137B024d4C0531b0164fCb6E8fc20e6777Ae", + "contractAddress": "0xBa4A759E41cCA14980bE4106792cdAC5F7BeDF83", "transactionIndex": 0, "gasUsed": "664456", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x3d49840965dc35a171d947b4e21d34e1b5c816de43f8c923f99c3ccdbdda79fa", - "transactionHash": "0x13931e2dae3a7a4cf3acfd902276f17808a977bacd1bff089ace0e93c1841cf0", + "blockHash": "0x2d0df5213d866412602cf7fdff0ad56093b22150e5f8ef9c910270247bb12562", + "transactionHash": "0x04ac7849ec511257a2b9e76962ae793898ae91cafaf363eaaa25c091ac6445b0", "logs": [], - "blockNumber": 3073034, + "blockNumber": 3232893, "cumulativeGasUsed": "664456", "status": 1, "byzantium": true }, "args": [ "0x258b180E741157763236F5277619D71ECf00B906", - "0x68Db1c8d85C09d546097C65ec7DCBFF4D6497CbF" + "0x3Db593146464816F10d4eBA4743C76A5A4D08425" ], - "numDeployments": 1, - "solcInputHash": "a2dd8c00aab95ba5d841446478d867fa", + "numDeployments": 2, + "solcInputHash": "8c968687fa7312972c014a5aac38beba", "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"DustSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_minter\",\"type\":\"address\"}],\"name\":\"MinterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"wKP3RDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"wKP3RMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newWKP3R\",\"type\":\"address\"}],\"name\":\"wKP3RSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sendDust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_minter\",\"type\":\"address\"}],\"name\":\"setMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"}],\"name\":\"setWKP3R\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wKP3R\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_governance\":\"Address of governance\",\"_wKP3R\":\"Address of wrapped KP3R implementation\"}},\"deposit(uint256)\":{\"params\":{\"_amount\":\"The amount of wKP3R to deposit\"}},\"mint(uint256)\":{\"params\":{\"_amount\":\"The amount of wKP3R to mint\"}},\"sendDust(address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of the token that will be transferred\",\"_to\":\"The address that will receive the idle funds\",\"_token\":\"The token that will be transferred\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setMinter(address)\":{\"params\":{\"_minter\":\"The address set as the minter\"}},\"setWKP3R(address)\":{\"params\":{\"_wKP3R\":\"the wKP3R address\"}}},\"stateVariables\":{\"wKP3R\":{\"return\":\"_wKP3RAddress The address of wKP3R\",\"returns\":{\"_0\":\"_wKP3RAddress The address of wKP3R\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InsufficientBalance()\":[{\"notice\":\"Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyMinter()\":[{\"notice\":\"Throws if the caller of the function is not the minter\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"DustSent(address,uint256,address)\":{\"notice\":\"Emitted when dust is sent\"},\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"MinterSet(address)\":{\"notice\":\"Emitted when governance sets a new minter\"},\"wKP3RDeposited(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rEscrow#deposit function is called\"},\"wKP3RMinted(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rEscrow#mint function is called\"},\"wKP3RSet(address)\":{\"notice\":\"Emitted when Keep3rEscrow#setWKP3R function is called\"}},\"kind\":\"user\",\"methods\":{\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"deposit(uint256)\":{\"notice\":\"Deposits wKP3R into the contract\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"mint(uint256)\":{\"notice\":\"mints wKP3R to the recipient\"},\"minter()\":{\"notice\":\"Stores the minter address\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"sendDust(address,uint256,address)\":{\"notice\":\"Allows an authorized user to transfer the tokens or eth that may have been left in a contract\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setMinter(address)\":{\"notice\":\"Sets a new address to be the minter\"},\"setWKP3R(address)\":{\"notice\":\"sets the wKP3R address\"},\"wKP3R()\":{\"notice\":\"Lists the address of the wKP3R contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/sidechain/Keep3rEscrow.sol\":\"Keep3rEscrow\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/DustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '../../contracts/peripherals/Governable.sol';\\nimport '../../interfaces/peripherals/IDustCollector.sol';\\n\\nabstract contract DustCollector is IDustCollector, Governable {\\n using SafeERC20 for IERC20;\\n\\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external override onlyGovernance {\\n if (_to == address(0)) revert ZeroAddress();\\n if (_token == _ETH_ADDRESS) {\\n payable(_to).transfer(_amount);\\n } else {\\n IERC20(_token).safeTransfer(_to, _amount);\\n }\\n emit DustSent(_token, _amount, _to);\\n }\\n}\\n\",\"keccak256\":\"0x246ac2c4057520bb627ea8040367549786f4477a04fd79358927cd607952bc2f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Mintable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IMintable.sol';\\nimport './Governable.sol';\\n\\nabstract contract Mintable is Governable, IMintable {\\n /// @inheritdoc IMintable\\n address public override minter;\\n\\n constructor(address _governance) Governable(_governance) {}\\n\\n /// @inheritdoc IMintable\\n function setMinter(address _minter) external override onlyGovernance {\\n if (_minter == address(0)) revert ZeroAddress();\\n minter = _minter;\\n emit MinterSet(_minter);\\n }\\n\\n /// @notice Functions with this modifier can only be called by the minter;\\n modifier onlyMinter() {\\n if (msg.sender != minter) revert OnlyMinter();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xc995899a6f8f32a0302fa017197b566012c2fefee9dc6fd2dac9d2674a5588f6\",\"license\":\"MIT\"},\"solidity/contracts/sidechain/Keep3rEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/Mintable.sol';\\nimport '../peripherals/DustCollector.sol';\\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rEscrow\\n address public override wKP3R;\\n\\n /// @param _governance Address of governance\\n /// @param _wKP3R Address of wrapped KP3R implementation\\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\\n wKP3R = _wKP3R;\\n }\\n\\n /// @inheritdoc IKeep3rEscrow\\n function deposit(uint256 _amount) external override {\\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rEscrow\\n function mint(uint256 _amount) external override onlyMinter {\\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rEscrow\\n function setWKP3R(address _wKP3R) external override onlyGovernance {\\n if (_wKP3R == address(0)) revert ZeroAddress();\\n wKP3R = _wKP3R;\\n emit wKP3RSet(wKP3R);\\n }\\n}\\n\",\"keccak256\":\"0x393124ed73b9b0b6aad631d03605302e1636beb478865cfa7b5d2b57aa517bca\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IMintable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IGovernable.sol';\\nimport './IBaseErrors.sol';\\n\\n/// @title Mintable contract\\n/// @notice Manages the minter role\\ninterface IMintable is IBaseErrors, IGovernable {\\n // Events\\n\\n /// @notice Emitted when governance sets a new minter\\n /// @param _minter Address of the new minter\\n event MinterSet(address _minter);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not the minter\\n error OnlyMinter();\\n\\n // Variables\\n\\n /// @notice Stores the minter address\\n /// @return _minter The minter addresss\\n function minter() external view returns (address _minter);\\n\\n // Methods\\n\\n /// @notice Sets a new address to be the minter\\n /// @param _minter The address set as the minter\\n function setMinter(address _minter) external;\\n}\\n\",\"keccak256\":\"0x255f4ed4b7c4ddf4fcff9db7524365ef734806583acca7c7912e867f110d9c81\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\nimport '../peripherals/IMintable.sol';\\n\\n/// @title Keep3rEscrow contract\\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\\ninterface IKeep3rEscrow is IMintable {\\n /// @notice Emitted when Keep3rEscrow#deposit function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _sender The address that called the function\\n /// @param _amount The amount of wKP3R the user deposited\\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#mint function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _recipient The address that will received the newly minted wKP3R\\n /// @param _amount The amount of wKP3R minted to the recipient\\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\\n /// @param _newWKP3R The address of the wKP3R contract\\n event wKP3RSet(address _newWKP3R);\\n\\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\\n error InsufficientBalance();\\n\\n /// @notice Lists the address of the wKP3R contract\\n /// @return _wKP3RAddress The address of wKP3R\\n function wKP3R() external view returns (address _wKP3RAddress);\\n\\n /// @notice Deposits wKP3R into the contract\\n /// @param _amount The amount of wKP3R to deposit\\n function deposit(uint256 _amount) external;\\n\\n /// @notice mints wKP3R to the recipient\\n /// @param _amount The amount of wKP3R to mint\\n function mint(uint256 _amount) external;\\n\\n /// @notice sets the wKP3R address\\n /// @param _wKP3R the wKP3R address\\n function setWKP3R(address _wKP3R) external;\\n}\\n\",\"keccak256\":\"0xf4796dde1afba7f50805aeae92ac0a4848525aeca8355d9b1c6b36c15cca4322\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x608060405234801561001057600080fd5b50604051610b1a380380610b1a83398101604081905261002f916100ab565b81806001600160a01b0381166100575760405162b293ed60e81b815260040160405180910390fd5b600080546001600160a01b039283166001600160a01b0319918216179091556003805494909216931692909217909155506100de9050565b80516001600160a01b03811681146100a657600080fd5b919050565b600080604083850312156100be57600080fd5b6100c78361008f565b91506100d56020840161008f565b90509250929050565b610a2d806100ed6000396000f3fe608060405234801561001057600080fd5b50600436106100995760003560e01c8063075461721461009e57806321316064146100c7578063238efcbc146100dc5780635aa6e675146100e4578063966abd00146100f7578063a0712d681461010a578063ab033ea91461011d578063b509ec4514610130578063b6b55f2514610143578063f39c38a014610156578063fca3b5aa14610169575b600080fd5b6002546100b1906001600160a01b031681565b6040516100be9190610960565b60405180910390f35b6100da6100d53660046108b2565b61017c565b005b6100da610225565b6000546100b1906001600160a01b031681565b6100da6101053660046108cd565b6102b1565b6100da61011836600461092b565b6103c7565b6100da61012b3660046108b2565b61044a565b6003546100b1906001600160a01b031681565b6100da61015136600461092b565b6104c0565b6001546100b1906001600160a01b031681565b6100da6101773660046108b2565b610519565b6000546001600160a01b031633146101a7576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166101ce5760405163d92e233d60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040517f8592ade84fad7cc1c020f9783980e05e1be8bf3c0b6b557f3f5d5b48b51476479161021a91610960565b60405180910390a150565b6001546001600160a01b0316331461025057604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b6916102a791610960565b60405180910390a1565b6000546001600160a01b031633146102dc576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166103035760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610364576040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561035e573d6000803e3d6000fd5b50610378565b6103786001600160a01b03841682846105b6565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6002546001600160a01b031633146103f257604051639cdc2ed560e01b815260040160405180910390fd5b600354610409906001600160a01b031633836105b6565b6003546040517f5c5d429f40d64606e3af1c2373aa5f5b0846566f2bb3871dcccf094850ed4fc89161021a916001600160a01b039091169033908590610974565b6000546001600160a01b03163314610475576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f9061021a908390610960565b6003546104d8906001600160a01b031633308461061e565b6003546040517fb0c9218af42df0588074c7f30948dd6d1293a5ef42e7762e83d62c5daa7c9b849161021a916001600160a01b039091169033908590610974565b6000546001600160a01b03163314610544576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661056b5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383161790556040517f726b590ef91a8c76ad05bbe91a57ef84605276528f49cd47d787f558a4e755b69061021a908390610960565b6040516001600160a01b03831660248201526044810182905261061990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610645565b505050565b61063f846323b872dd60e01b8585856040516024016105e293929190610974565b50505050565b600061069a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661071c9092919063ffffffff16565b80519091501561061957808060200190518101906106b89190610909565b6106195760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b606061072b8484600085610735565b90505b9392505050565b6060824710156107965760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610713565b843b6107e45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610713565b600080866001600160a01b031685876040516108009190610944565b60006040518083038185875af1925050503d806000811461083d576040519150601f19603f3d011682016040523d82523d6000602084013e610842565b606091505b509150915061085282828661085d565b979650505050505050565b6060831561086c57508161072e565b82511561087c5782518084602001fd5b8160405162461bcd60e51b81526004016107139190610998565b80356001600160a01b03811681146108ad57600080fd5b919050565b6000602082840312156108c457600080fd5b61072e82610896565b6000806000606084860312156108e257600080fd5b6108eb84610896565b92506020840135915061090060408501610896565b90509250925092565b60006020828403121561091b57600080fd5b8151801515811461072e57600080fd5b60006020828403121561093d57600080fd5b5035919050565b600082516109568184602087016109cb565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60208152600082518060208401526109b78160408501602087016109cb565b601f01601f19169190910160400192915050565b60005b838110156109e65781810151838201526020016109ce565b8381111561063f575050600091015256fea2646970667358221220f27662244867a849ca4b8b284ad15a4e1cf161566f3c6c1a40cca8dd7d21eaee64736f6c63430008070033", "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100995760003560e01c8063075461721461009e57806321316064146100c7578063238efcbc146100dc5780635aa6e675146100e4578063966abd00146100f7578063a0712d681461010a578063ab033ea91461011d578063b509ec4514610130578063b6b55f2514610143578063f39c38a014610156578063fca3b5aa14610169575b600080fd5b6002546100b1906001600160a01b031681565b6040516100be9190610960565b60405180910390f35b6100da6100d53660046108b2565b61017c565b005b6100da610225565b6000546100b1906001600160a01b031681565b6100da6101053660046108cd565b6102b1565b6100da61011836600461092b565b6103c7565b6100da61012b3660046108b2565b61044a565b6003546100b1906001600160a01b031681565b6100da61015136600461092b565b6104c0565b6001546100b1906001600160a01b031681565b6100da6101773660046108b2565b610519565b6000546001600160a01b031633146101a7576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166101ce5760405163d92e233d60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040517f8592ade84fad7cc1c020f9783980e05e1be8bf3c0b6b557f3f5d5b48b51476479161021a91610960565b60405180910390a150565b6001546001600160a01b0316331461025057604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b6916102a791610960565b60405180910390a1565b6000546001600160a01b031633146102dc576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166103035760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610364576040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561035e573d6000803e3d6000fd5b50610378565b6103786001600160a01b03841682846105b6565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6002546001600160a01b031633146103f257604051639cdc2ed560e01b815260040160405180910390fd5b600354610409906001600160a01b031633836105b6565b6003546040517f5c5d429f40d64606e3af1c2373aa5f5b0846566f2bb3871dcccf094850ed4fc89161021a916001600160a01b039091169033908590610974565b6000546001600160a01b03163314610475576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f9061021a908390610960565b6003546104d8906001600160a01b031633308461061e565b6003546040517fb0c9218af42df0588074c7f30948dd6d1293a5ef42e7762e83d62c5daa7c9b849161021a916001600160a01b039091169033908590610974565b6000546001600160a01b03163314610544576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661056b5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383161790556040517f726b590ef91a8c76ad05bbe91a57ef84605276528f49cd47d787f558a4e755b69061021a908390610960565b6040516001600160a01b03831660248201526044810182905261061990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610645565b505050565b61063f846323b872dd60e01b8585856040516024016105e293929190610974565b50505050565b600061069a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661071c9092919063ffffffff16565b80519091501561061957808060200190518101906106b89190610909565b6106195760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b606061072b8484600085610735565b90505b9392505050565b6060824710156107965760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610713565b843b6107e45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610713565b600080866001600160a01b031685876040516108009190610944565b60006040518083038185875af1925050503d806000811461083d576040519150601f19603f3d011682016040523d82523d6000602084013e610842565b606091505b509150915061085282828661085d565b979650505050505050565b6060831561086c57508161072e565b82511561087c5782518084602001fd5b8160405162461bcd60e51b81526004016107139190610998565b80356001600160a01b03811681146108ad57600080fd5b919050565b6000602082840312156108c457600080fd5b61072e82610896565b6000806000606084860312156108e257600080fd5b6108eb84610896565b92506020840135915061090060408501610896565b90509250925092565b60006020828403121561091b57600080fd5b8151801515811461072e57600080fd5b60006020828403121561093d57600080fd5b5035919050565b600082516109568184602087016109cb565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60208152600082518060208401526109b78160408501602087016109cb565b601f01601f19169190910160400192915050565b60005b838110156109e65781810151838201526020016109ce565b8381111561063f575050600091015256fea2646970667358221220f27662244867a849ca4b8b284ad15a4e1cf161566f3c6c1a40cca8dd7d21eaee64736f6c63430008070033", @@ -496,7 +496,7 @@ "storageLayout": { "storage": [ { - "astId": 5374, + "astId": 5362, "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", "label": "governance", "offset": 0, @@ -504,7 +504,7 @@ "type": "t_address" }, { - "astId": 5378, + "astId": 5366, "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", "label": "pendingGovernance", "offset": 0, @@ -512,7 +512,7 @@ "type": "t_address" }, { - "astId": 6171, + "astId": 6185, "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", "label": "minter", "offset": 0, @@ -520,7 +520,7 @@ "type": "t_address" }, { - "astId": 9636, + "astId": 9638, "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", "label": "wKP3R", "offset": 0, diff --git a/deployments/optimisticGoerli/Keep3rHelperSidechain.json b/deployments/optimisticGoerli/Keep3rHelperSidechain.json new file mode 100644 index 0000000..d7f4e07 --- /dev/null +++ b/deployments/optimisticGoerli/Keep3rHelperSidechain.json @@ -0,0 +1,1548 @@ +{ + "address": "0x399394ca069dCDE2C4d2a32E00a06C3D5fE17E3A", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rV2", + "type": "address" + }, + { + "internalType": "address", + "name": "_governance", + "type": "address" + }, + { + "internalType": "address", + "name": "_kp3r", + "type": "address" + }, + { + "internalType": "address", + "name": "_weth", + "type": "address" + }, + { + "internalType": "address", + "name": "_kp3rWethOracle", + "type": "address" + }, + { + "internalType": "address", + "name": "_wethUsdOracle", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidOraclePool", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidityPairInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "NoGovernanceZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyGovernance", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingGovernance", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_pendingGovernance", + "type": "address" + } + ], + "name": "GovernanceProposal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_governance", + "type": "address" + } + ], + "name": "GovernanceSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_keep3rV2", + "type": "address" + } + ], + "name": "Keep3rV2Change", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_isKP3RToken0", + "type": "bool" + } + ], + "name": "Kp3rWethPoolChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_maxBoost", + "type": "uint256" + } + ], + "name": "MaxBoostChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_minBaseFee", + "type": "uint256" + } + ], + "name": "MinBaseFeeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_minBoost", + "type": "uint256" + } + ], + "name": "MinBoostChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_minPriorityFee", + "type": "uint256" + } + ], + "name": "MinPriorityFeeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_oraclePool", + "type": "address" + } + ], + "name": "OracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "_quoteTwapTime", + "type": "uint32" + } + ], + "name": "QuoteTwapTimeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_targetBond", + "type": "uint256" + } + ], + "name": "TargetBondChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_isWETHToken0", + "type": "bool" + } + ], + "name": "WethUSDPoolChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_workExtraGas", + "type": "uint256" + } + ], + "name": "WorkExtraGasChange", + "type": "event" + }, + { + "inputs": [], + "name": "BOOST_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "KP3R", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + } + ], + "name": "bonds", + "outputs": [ + { + "internalType": "uint256", + "name": "_amountBonded", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_liquidityAmount", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "_tickDifference", + "type": "int56" + }, + { + "internalType": "uint256", + "name": "_timeInterval", + "type": "uint256" + } + ], + "name": "getKP3RsAtTick", + "outputs": [ + { + "internalType": "uint256", + "name": "_kp3rAmount", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bonds", + "type": "uint256" + } + ], + "name": "getPaymentParams", + "outputs": [ + { + "internalType": "uint256", + "name": "_boost", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_oneUsdQuote", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_extraGas", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "getPoolTokens", + "outputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "_baseAmount", + "type": "uint128" + }, + { + "internalType": "int56", + "name": "_tickDifference", + "type": "int56" + }, + { + "internalType": "uint256", + "name": "_timeInterval", + "type": "uint256" + } + ], + "name": "getQuoteAtTick", + "outputs": [ + { + "internalType": "uint256", + "name": "_quoteAmount", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_gasUsed", + "type": "uint256" + } + ], + "name": "getRewardAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_gasUsed", + "type": "uint256" + } + ], + "name": "getRewardAmountFor", + "outputs": [ + { + "internalType": "uint256", + "name": "_kp3r", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bonds", + "type": "uint256" + } + ], + "name": "getRewardBoostFor", + "outputs": [ + { + "internalType": "uint256", + "name": "_rewardBoost", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "isKP3RToken0", + "outputs": [ + { + "internalType": "bool", + "name": "_isKP3RToken0", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keep3rV2", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "kp3rWethPool", + "outputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isTKNToken0", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxBoost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minBaseFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minBoost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minPriorityFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "uint32[]", + "name": "_secondsAgo", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56", + "name": "_tickCumulative1", + "type": "int56" + }, + { + "internalType": "int56", + "name": "_tickCumulative2", + "type": "int56" + }, + { + "internalType": "bool", + "name": "_success", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "oracle", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingGovernance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eth", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "_amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "quoteTwapTime", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_usd", + "type": "uint256" + } + ], + "name": "quoteUsdToEth", + "outputs": [ + { + "internalType": "uint256", + "name": "_amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governance", + "type": "address" + } + ], + "name": "setGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rV2", + "type": "address" + } + ], + "name": "setKeep3rV2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolAddress", + "type": "address" + } + ], + "name": "setKp3rWethPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxBoost", + "type": "uint256" + } + ], + "name": "setMaxBoost", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minBaseFee", + "type": "uint256" + } + ], + "name": "setMinBaseFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minBoost", + "type": "uint256" + } + ], + "name": "setMinBoost", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minPriorityFee", + "type": "uint256" + } + ], + "name": "setMinPriorityFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "address", + "name": "_oracle", + "type": "address" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_quoteTwapTime", + "type": "uint32" + } + ], + "name": "setQuoteTwapTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_targetBond", + "type": "uint256" + } + ], + "name": "setTargetBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolAddress", + "type": "address" + } + ], + "name": "setWethUsdPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_workExtraGas", + "type": "uint256" + } + ], + "name": "setWorkExtraGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "targetBond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wethUSDPool", + "outputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isTKNToken0", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "workExtraGas", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x140e28be60d0f3e1c436f07b4ed24d38d4631a34dca88b8551f7800254f20b09", + "receipt": { + "to": null, + "from": "0x258b180E741157763236F5277619D71ECf00B906", + "contractAddress": "0x399394ca069dCDE2C4d2a32E00a06C3D5fE17E3A", + "transactionIndex": 0, + "gasUsed": "2156048", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000104000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000100000000000000000000000000000000000200000000000000000000000000000000000000008000000000000000000", + "blockHash": "0x24e734410564053a067d33b5f00a1e4aecc1de50263bd5b75fba51bec2c66df8", + "transactionHash": "0x140e28be60d0f3e1c436f07b4ed24d38d4631a34dca88b8551f7800254f20b09", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 3238158, + "transactionHash": "0x140e28be60d0f3e1c436f07b4ed24d38d4631a34dca88b8551f7800254f20b09", + "address": "0x399394ca069dCDE2C4d2a32E00a06C3D5fE17E3A", + "topics": [ + "0x554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf4108" + ], + "data": "0x0000000000000000000000004ecff2c532d47d7be3d957e4a332ab134cad1fd90000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 0, + "blockHash": "0x24e734410564053a067d33b5f00a1e4aecc1de50263bd5b75fba51bec2c66df8" + }, + { + "transactionIndex": 0, + "blockNumber": 3238158, + "transactionHash": "0x140e28be60d0f3e1c436f07b4ed24d38d4631a34dca88b8551f7800254f20b09", + "address": "0x399394ca069dCDE2C4d2a32E00a06C3D5fE17E3A", + "topics": [ + "0xc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000015180", + "logIndex": 1, + "blockHash": "0x24e734410564053a067d33b5f00a1e4aecc1de50263bd5b75fba51bec2c66df8" + } + ], + "blockNumber": 3238158, + "cumulativeGasUsed": "2156048", + "status": 1, + "byzantium": true + }, + "args": [ + "0x85063437C02Ba7F4f82F898859e4992380DEd3bb", + "0x258b180E741157763236F5277619D71ECf00B906", + "0x16F63C5036d3F48A239358656a8f123eCE85789C", + "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", + "0x4ECFF2c532d47D7be3D957E4a332AB134cad1fd9", + "0x4ECFF2c532d47D7be3D957E4a332AB134cad1fd9" + ], + "numDeployments": 1, + "solcInputHash": "7d006d28afea8f44b7106e2df679db88", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kp3r\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kp3rWethOracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_wethUsdOracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidOraclePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"Keep3rV2Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isKP3RToken0\",\"type\":\"bool\"}],\"name\":\"Kp3rWethPoolChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"MaxBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"MinBaseFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"MinBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"MinPriorityFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_oraclePool\",\"type\":\"address\"}],\"name\":\"OracleSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"QuoteTwapTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"TargetBondChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isWETHToken0\",\"type\":\"bool\"}],\"name\":\"WethUSDPoolChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"WorkExtraGasChange\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BOOST_BASE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"KP3R\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WETH\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountBonded\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityAmount\",\"type\":\"uint256\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getKP3RsAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3rAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getPaymentParams\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_boost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_oneUsdQuote\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_extraGas\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"}],\"name\":\"getPoolTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token1\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_baseAmount\",\"type\":\"uint128\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getQuoteAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_quoteAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmountFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3r\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getRewardBoostFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardBoost\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"}],\"name\":\"isKP3RToken0\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isKP3RToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV2\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"kp3rWethPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isTKNToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBaseFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minPriorityFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"},{\"internalType\":\"uint32[]\",\"name\":\"_secondsAgo\",\"type\":\"uint32[]\"}],\"name\":\"observe\",\"outputs\":[{\"internalType\":\"int56\",\"name\":\"_tickCumulative1\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"_tickCumulative2\",\"type\":\"int56\"},{\"internalType\":\"bool\",\"name\":\"_success\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eth\",\"type\":\"uint256\"}],\"name\":\"quote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"quoteTwapTime\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_usd\",\"type\":\"uint256\"}],\"name\":\"quoteUsdToEth\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"setKeep3rV2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddress\",\"type\":\"address\"}],\"name\":\"setKp3rWethPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"setMaxBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"setMinBaseFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"setMinBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"setMinPriorityFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"}],\"name\":\"setOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"setQuoteTwapTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"setTargetBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddress\",\"type\":\"address\"}],\"name\":\"setWethUsdPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"setWorkExtraGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetBond\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wethUSDPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isTKNToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"workExtraGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bonds(address)\":{\"params\":{\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_amountBonded\":\"The amount of KP3R the keeper has bonded\"}},\"constructor\":{\"details\":\"Oracle pools should use 18 decimals tokens\",\"params\":{\"_governance\":\"Address of governance\",\"_keep3rV2\":\"Address of sidechain Keep3r implementation\",\"_kp3rWethOracle\":\"Address of oracle used for KP3R/WETH quote\",\"_wethUsdOracle\":\"Address of oracle used for WETH/USD quote\"}},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"params\":{\"_liquidityAmount\":\"Amount of liquidity to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_kp3rAmount\":\"Amount of KP3R tokens underlying on the given liquidity\"}},\"getPaymentParams(uint256)\":{\"params\":{\"_bonds\":\"Amount of bonded KP3R owned by the keeper\"},\"returns\":{\"_boost\":\"Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\",\"_extraGas\":\"Amount of extra gas that should be added to the gas spent\",\"_oneUsdQuote\":\"Amount of KP3R tokens equivalent to 1 ETH\"}},\"getPoolTokens(address)\":{\"params\":{\"_pool\":\"Address of the correspondant pool\"},\"returns\":{\"_token0\":\"Address of the first token of the pair\",\"_token1\":\"Address of the second token of the pair\"}},\"getQuoteAtTick(uint128,int56,uint256)\":{\"params\":{\"_baseAmount\":\"Amount of token to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_quoteAmount\":\"Amount of credits deserved for the baseAmount at the tick value\"}},\"getRewardAmount(uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\"},\"returns\":{\"_amount\":\"The amount of KP3R that should be awarded to tx.origin\"}},\"getRewardAmountFor(address,uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\",\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_kp3r\":\"The amount of KP3R that should be awarded to the keeper\"}},\"getRewardBoostFor(uint256)\":{\"details\":\"If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\",\"params\":{\"_bonds\":\"The amount of KP3R tokens bonded by the keeper\"},\"returns\":{\"_rewardBoost\":\"The reward boost that corresponds to the keeper\"}},\"isKP3RToken0(address)\":{\"params\":{\"_pool\":\"Address of the correspondant pool\"},\"returns\":{\"_isKP3RToken0\":\"Boolean indicating the order of the tokens in the pair\"}},\"observe(address,uint32[])\":{\"params\":{\"_pool\":\"Address of the pool to observe\",\"_secondsAgo\":\"Array with time references to observe\"},\"returns\":{\"_success\":\"Boolean indicating if the observe call was succesfull\",\"_tickCumulative1\":\"Cumulative sum of ticks until first time reference\",\"_tickCumulative2\":\"Cumulative sum of ticks until second time reference\"}},\"quote(uint256)\":{\"details\":\"This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\",\"params\":{\"_eth\":\"The amount of ETH\"},\"returns\":{\"_amountOut\":\"The amount of KP3R\"}},\"quoteUsdToEth(uint256)\":{\"details\":\"Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\",\"params\":{\"_usd\":\"The amount of USD to quote to ETH\"},\"returns\":{\"_amountOut\":\"The resulting amount of ETH after quoting the USD\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setKeep3rV2(address)\":{\"params\":{\"_keep3rV2\":\"The address of Keep3r V2\"}},\"setKp3rWethPool(address)\":{\"params\":{\"_poolAddress\":\"The address of the KP3R-WETH pool\"}},\"setMaxBoost(uint256)\":{\"params\":{\"_maxBoost\":\"The maximum boost multiplier\"}},\"setMinBaseFee(uint256)\":{\"params\":{\"_minBaseFee\":\"The minimum rewarded gas fee\"}},\"setMinBoost(uint256)\":{\"params\":{\"_minBoost\":\"The minimum boost multiplier\"}},\"setMinPriorityFee(uint256)\":{\"params\":{\"_minPriorityFee\":\"The minimum rewarded priority fee\"}},\"setOracle(address,address)\":{\"details\":\"The oracle must contain KP3R as either token0 or token1\",\"params\":{\"_liquidity\":\"The address of the liquidity\",\"_oracle\":\"The address of the pool used to quote the liquidity from\"}},\"setQuoteTwapTime(uint32)\":{\"params\":{\"_quoteTwapTime\":\"The twap time for quoting\"}},\"setTargetBond(uint256)\":{\"params\":{\"_targetBond\":\"The target bond amount\"}},\"setWethUsdPool(address)\":{\"details\":\"The oracle must contain WETH as either token0 or token1\",\"params\":{\"_poolAddress\":\"The address of the pool used as oracle\"}},\"setWorkExtraGas(uint256)\":{\"params\":{\"_workExtraGas\":\"The work extra gas\"}}},\"stateVariables\":{\"oracle\":{\"return\":\"_oracle The address of the observable pool for given liquidity\",\"returns\":{\"_0\":\"_oracle The address of the observable pool for given liquidity\"}},\"wethUSDPool\":{\"returns\":{\"isTKNToken0\":\"True if calling the token0 method of the pool returns the WETH token address\",\"poolAddress\":\"Address of the pool\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidOraclePool()\":[{\"notice\":\"Throws when pool does not have KP3R as token0 nor token1\"}],\"LiquidityPairInvalid()\":[{\"notice\":\"Throws when none of the tokens in the liquidity pair is KP3R\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"Keep3rV2Change(address)\":{\"notice\":\"Emitted when the Keep3r V2 address is changed\"},\"Kp3rWethPoolChange(address,bool)\":{\"notice\":\"Emitted when the kp3r weth pool is changed\"},\"MaxBoostChange(uint256)\":{\"notice\":\"Emitted when the maximum boost multiplier is changed\"},\"MinBaseFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded gas fee is changed\"},\"MinBoostChange(uint256)\":{\"notice\":\"Emitted when the minimum boost multiplier is changed\"},\"MinPriorityFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded priority fee is changed\"},\"OracleSet(address,address)\":{\"notice\":\"The oracle for a liquidity has been saved\"},\"QuoteTwapTimeChange(uint32)\":{\"notice\":\"Emitted when the quote twap time is changed\"},\"TargetBondChange(uint256)\":{\"notice\":\"Emitted when the target bond amount is changed\"},\"WethUSDPoolChange(address,bool)\":{\"notice\":\"Emitted when the WETH USD pool is changed\"},\"WorkExtraGasChange(uint256)\":{\"notice\":\"Emitted when the work extra gas amount is changed\"}},\"kind\":\"user\",\"methods\":{\"BOOST_BASE()\":{\"notice\":\"The boost base used to calculate the boost rewards for the keeper\"},\"KP3R()\":{\"notice\":\"Address of KP3R token\"},\"WETH()\":{\"notice\":\"Ethereum mainnet WETH address used for quoting references\"},\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"bonds(address)\":{\"notice\":\"Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\"},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"notice\":\"Given a tick and a liquidity amount, calculates the underlying KP3R tokens\"},\"getPaymentParams(uint256)\":{\"notice\":\"Get multiplier, quote, and extra, in order to calculate keeper payment\"},\"getPoolTokens(address)\":{\"notice\":\"Given a pool address, returns the underlying tokens of the pair\"},\"getQuoteAtTick(uint128,int56,uint256)\":{\"notice\":\"Given a tick and a token amount, calculates the output in correspondant token\"},\"getRewardAmount(uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\"},\"getRewardAmountFor(address,uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to a keeper for using gas\"},\"getRewardBoostFor(uint256)\":{\"notice\":\"Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"isKP3RToken0(address)\":{\"notice\":\"Defines the order of the tokens in the pair for twap calculations\"},\"keep3rV2()\":{\"notice\":\"Address of Keep3r V2\"},\"kp3rWethPool()\":{\"notice\":\"KP3R-WETH pool that is being used as oracle\"},\"maxBoost()\":{\"notice\":\"The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\"},\"minBaseFee()\":{\"notice\":\"The minimum base fee that is used to calculate keeper rewards\"},\"minBoost()\":{\"notice\":\"The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\"},\"minPriorityFee()\":{\"notice\":\"The minimum priority fee that is also rewarded for keepers\"},\"observe(address,uint32[])\":{\"notice\":\"Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"quote(uint256)\":{\"notice\":\"Calculates the amount of KP3R that corresponds to the ETH passed into the function\"},\"quoteTwapTime()\":{\"notice\":\"The twap time for quoting\"},\"quoteUsdToEth(uint256)\":{\"notice\":\"Quotes USD to ETH\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setKeep3rV2(address)\":{\"notice\":\"Sets the Keep3r V2 address\"},\"setKp3rWethPool(address)\":{\"notice\":\"Sets KP3R-WETH pool\"},\"setMaxBoost(uint256)\":{\"notice\":\"Sets the maximum boost multiplier\"},\"setMinBaseFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas fee\"},\"setMinBoost(uint256)\":{\"notice\":\"Sets the minimum boost multiplier\"},\"setMinPriorityFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas priority fee\"},\"setOracle(address,address)\":{\"notice\":\"Sets an oracle for a given liquidity\"},\"setQuoteTwapTime(uint32)\":{\"notice\":\"Sets the quote twap time\"},\"setTargetBond(uint256)\":{\"notice\":\"Sets the target bond amount\"},\"setWethUsdPool(address)\":{\"notice\":\"Sets an oracle for querying WETH/USD quote\"},\"setWorkExtraGas(uint256)\":{\"notice\":\"Sets the work extra gas amount\"},\"targetBond()\":{\"notice\":\"The targeted amount of bonded KP3Rs to max-up reward multiplier For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\"},\"wethUSDPool()\":{\"notice\":\"WETH-USD pool that is being used as oracle\"},\"workExtraGas()\":{\"notice\":\"The amount of unaccounted gas that is going to be added to keeper payments\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/sidechain/Keep3rHelperSidechain.sol\":\"Keep3rHelperSidechain\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\nimport './pool/IUniswapV3PoolImmutables.sol';\\nimport './pool/IUniswapV3PoolState.sol';\\nimport './pool/IUniswapV3PoolDerivedState.sol';\\nimport './pool/IUniswapV3PoolActions.sol';\\nimport './pool/IUniswapV3PoolOwnerActions.sol';\\nimport './pool/IUniswapV3PoolEvents.sol';\\n\\n/// @title The interface for a Uniswap V3 Pool\\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\\n/// to the ERC20 specification\\n/// @dev The pool interface is broken up into many smaller pieces\\ninterface IUniswapV3Pool is\\n IUniswapV3PoolImmutables,\\n IUniswapV3PoolState,\\n IUniswapV3PoolDerivedState,\\n IUniswapV3PoolActions,\\n IUniswapV3PoolOwnerActions,\\n IUniswapV3PoolEvents\\n{\\n\\n}\\n\",\"keccak256\":\"0xfe6113d518466cd6652c85b111e01f33eb62157f49ae5ed7d5a3947a2044adb1\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissionless pool actions\\n/// @notice Contains pool methods that can be called by anyone\\ninterface IUniswapV3PoolActions {\\n /// @notice Sets the initial price for the pool\\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\\n function initialize(uint160 sqrtPriceX96) external;\\n\\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\\n /// @param recipient The address for which the liquidity will be created\\n /// @param tickLower The lower tick of the position in which to add liquidity\\n /// @param tickUpper The upper tick of the position in which to add liquidity\\n /// @param amount The amount of liquidity to mint\\n /// @param data Any data that should be passed through to the callback\\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n function mint(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount,\\n bytes calldata data\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Collects tokens owed to a position\\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\\n /// @param recipient The address which should receive the fees collected\\n /// @param tickLower The lower tick of the position for which to collect fees\\n /// @param tickUpper The upper tick of the position for which to collect fees\\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\\n /// @return amount0 The amount of fees collected in token0\\n /// @return amount1 The amount of fees collected in token1\\n function collect(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n\\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\\n /// @dev Fees must be collected separately via a call to #collect\\n /// @param tickLower The lower tick of the position for which to burn liquidity\\n /// @param tickUpper The upper tick of the position for which to burn liquidity\\n /// @param amount How much liquidity to burn\\n /// @return amount0 The amount of token0 sent to the recipient\\n /// @return amount1 The amount of token1 sent to the recipient\\n function burn(\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Swap token0 for token1, or token1 for token0\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\\n /// @param recipient The address to receive the output of the swap\\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\\n /// @param data Any data to be passed through to the callback\\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\\n /// @param recipient The address which will receive the token0 and token1 amounts\\n /// @param amount0 The amount of token0 to send\\n /// @param amount1 The amount of token1 to send\\n /// @param data Any data to be passed through to the callback\\n function flash(\\n address recipient,\\n uint256 amount0,\\n uint256 amount1,\\n bytes calldata data\\n ) external;\\n\\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\\n /// the input observationCardinalityNext.\\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0x9453dd0e7442188667d01d9b65de3f1e14e9511ff3e303179a15f6fc267f7634\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that is not stored\\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\\n/// blockchain. The functions here may have variable gas costs.\\ninterface IUniswapV3PoolDerivedState {\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\\n /// you must call it with secondsAgos = [3600, 0].\\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\\n /// timestamp\\n function observe(uint32[] calldata secondsAgos)\\n external\\n view\\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\\n\\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\\n /// snapshot is taken and the second snapshot is taken.\\n /// @param tickLower The lower tick of the range\\n /// @param tickUpper The upper tick of the range\\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\\n /// @return secondsInside The snapshot of seconds per liquidity for the range\\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\\n external\\n view\\n returns (\\n int56 tickCumulativeInside,\\n uint160 secondsPerLiquidityInsideX128,\\n uint32 secondsInside\\n );\\n}\\n\",\"keccak256\":\"0xe603ac5b17ecdee73ba2b27efdf386c257a19c14206e87eee77e2017b742d9e5\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Events emitted by a pool\\n/// @notice Contains all events emitted by the pool\\ninterface IUniswapV3PoolEvents {\\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\\n event Initialize(uint160 sqrtPriceX96, int24 tick);\\n\\n /// @notice Emitted when liquidity is minted for a given position\\n /// @param sender The address that minted the liquidity\\n /// @param owner The owner of the position and recipient of any minted liquidity\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity minted to the position range\\n /// @param amount0 How much token0 was required for the minted liquidity\\n /// @param amount1 How much token1 was required for the minted liquidity\\n event Mint(\\n address sender,\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted when fees are collected by the owner of a position\\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\\n /// @param owner The owner of the position for which fees are collected\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount0 The amount of token0 fees collected\\n /// @param amount1 The amount of token1 fees collected\\n event Collect(\\n address indexed owner,\\n address recipient,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount0,\\n uint128 amount1\\n );\\n\\n /// @notice Emitted when a position's liquidity is removed\\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\\n /// @param owner The owner of the position for which liquidity is removed\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity to remove\\n /// @param amount0 The amount of token0 withdrawn\\n /// @param amount1 The amount of token1 withdrawn\\n event Burn(\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted by the pool for any swaps between token0 and token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the output of the swap\\n /// @param amount0 The delta of the token0 balance of the pool\\n /// @param amount1 The delta of the token1 balance of the pool\\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param liquidity The liquidity of the pool after the swap\\n /// @param tick The log base 1.0001 of price of the pool after the swap\\n event Swap(\\n address indexed sender,\\n address indexed recipient,\\n int256 amount0,\\n int256 amount1,\\n uint160 sqrtPriceX96,\\n uint128 liquidity,\\n int24 tick\\n );\\n\\n /// @notice Emitted by the pool for any flashes of token0/token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the tokens from flash\\n /// @param amount0 The amount of token0 that was flashed\\n /// @param amount1 The amount of token1 that was flashed\\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\\n event Flash(\\n address indexed sender,\\n address indexed recipient,\\n uint256 amount0,\\n uint256 amount1,\\n uint256 paid0,\\n uint256 paid1\\n );\\n\\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\\n /// just before a mint/swap/burn.\\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(\\n uint16 observationCardinalityNextOld,\\n uint16 observationCardinalityNextNew\\n );\\n\\n /// @notice Emitted when the protocol fee is changed by the pool\\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\\n /// @param feeProtocol0New The updated value of the token0 protocol fee\\n /// @param feeProtocol1New The updated value of the token1 protocol fee\\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\\n\\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\\n /// @param sender The address that collects the protocol fees\\n /// @param recipient The address that receives the collected protocol fees\\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x8071514d0fe5d17d6fbd31c191cdfb703031c24e0ece3621d88ab10e871375cd\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that never changes\\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\\ninterface IUniswapV3PoolImmutables {\\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\\n /// @return The contract address\\n function factory() external view returns (address);\\n\\n /// @notice The first of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token0() external view returns (address);\\n\\n /// @notice The second of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token1() external view returns (address);\\n\\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\\n /// @return The fee\\n function fee() external view returns (uint24);\\n\\n /// @notice The pool tick spacing\\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\\n /// This value is an int24 to avoid casting even though it is always positive.\\n /// @return The tick spacing\\n function tickSpacing() external view returns (int24);\\n\\n /// @notice The maximum amount of position liquidity that can use any tick in the range\\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\\n /// @return The max amount of liquidity per tick\\n function maxLiquidityPerTick() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xf6e5d2cd1139c4c276bdbc8e1d2b256e456c866a91f1b868da265c6d2685c3f7\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissioned pool actions\\n/// @notice Contains pool methods that may only be called by the factory owner\\ninterface IUniswapV3PoolOwnerActions {\\n /// @notice Set the denominator of the protocol's % share of the fees\\n /// @param feeProtocol0 new protocol fee for token0 of the pool\\n /// @param feeProtocol1 new protocol fee for token1 of the pool\\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\\n\\n /// @notice Collect the protocol fee accrued to the pool\\n /// @param recipient The address to which collected protocol fees should be sent\\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\\n /// @return amount0 The protocol fee collected in token0\\n /// @return amount1 The protocol fee collected in token1\\n function collectProtocol(\\n address recipient,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x759b78a2918af9e99e246dc3af084f654e48ef32bb4e4cb8a966aa3dcaece235\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that can change\\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\\n/// per transaction\\ninterface IUniswapV3PoolState {\\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\\n /// when accessed externally.\\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\\n /// boundary.\\n /// observationIndex The index of the last oracle observation that was written,\\n /// observationCardinality The current maximum number of observations stored in the pool,\\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// feeProtocol The protocol fee for both tokens of the pool.\\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\\n /// unlocked Whether the pool is currently locked to reentrancy\\n function slot0()\\n external\\n view\\n returns (\\n uint160 sqrtPriceX96,\\n int24 tick,\\n uint16 observationIndex,\\n uint16 observationCardinality,\\n uint16 observationCardinalityNext,\\n uint8 feeProtocol,\\n bool unlocked\\n );\\n\\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal0X128() external view returns (uint256);\\n\\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal1X128() external view returns (uint256);\\n\\n /// @notice The amounts of token0 and token1 that are owed to the protocol\\n /// @dev Protocol fees will never exceed uint128 max in either token\\n function protocolFees() external view returns (uint128 token0, uint128 token1);\\n\\n /// @notice The currently in range liquidity available to the pool\\n /// @dev This value has no relationship to the total liquidity across all ticks\\n function liquidity() external view returns (uint128);\\n\\n /// @notice Look up information about a specific tick in the pool\\n /// @param tick The tick to look up\\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\\n /// tick upper,\\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\\n /// a specific position.\\n function ticks(int24 tick)\\n external\\n view\\n returns (\\n uint128 liquidityGross,\\n int128 liquidityNet,\\n uint256 feeGrowthOutside0X128,\\n uint256 feeGrowthOutside1X128,\\n int56 tickCumulativeOutside,\\n uint160 secondsPerLiquidityOutsideX128,\\n uint32 secondsOutside,\\n bool initialized\\n );\\n\\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\\n function tickBitmap(int16 wordPosition) external view returns (uint256);\\n\\n /// @notice Returns the information about a position by the position's key\\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\\n /// @return _liquidity The amount of liquidity in the position,\\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\\n function positions(bytes32 key)\\n external\\n view\\n returns (\\n uint128 _liquidity,\\n uint256 feeGrowthInside0LastX128,\\n uint256 feeGrowthInside1LastX128,\\n uint128 tokensOwed0,\\n uint128 tokensOwed1\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param index The element of the observations array to fetch\\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\\n /// ago, rather than at a specific index in the array.\\n /// @return blockTimestamp The timestamp of the observation,\\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// Returns initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 index)\\n external\\n view\\n returns (\\n uint32 blockTimestamp,\\n int56 tickCumulative,\\n uint160 secondsPerLiquidityCumulativeX128,\\n bool initialized\\n );\\n}\\n\",\"keccak256\":\"0x852dc1f5df7dcf7f11e7bb3eed79f0cea72ad4b25f6a9d2c35aafb48925fd49f\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/Keep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2003\\u2003\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2003\\u2003\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/IKeep3rHelper.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\\n\\n /// @inheritdoc IKeep3rHelper\\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\\n uint32[] memory _secondsAgos = new uint32[](2);\\n _secondsAgos[1] = quoteTwapTime;\\n\\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\\n // solhint-disable-next-line avoid-tx-origin\\n return getRewardAmountFor(tx.origin, _gasUsed);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\\n _bonds = Math.min(_bonds, targetBond);\\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\\n _rewardBoost = _cap * _getBasefee();\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\\n address _token0;\\n address _token1;\\n (_token0, _token1) = getPoolTokens(_pool);\\n if (_token0 == KP3R) {\\n return true;\\n } else if (_token1 != KP3R) {\\n revert LiquidityPairInvalid();\\n }\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n override\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n )\\n {\\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\\n _tickCumulative1 = _uniswapResponse[0];\\n if (_uniswapResponse.length > 1) {\\n _tickCumulative2 = _uniswapResponse[1];\\n }\\n _success = true;\\n } catch (bytes memory) {}\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n virtual\\n override\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n )\\n {\\n _oneEthQuote = quote(1 ether);\\n _boost = getRewardBoostFor(_bonds);\\n _extra = workExtraGas;\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure override returns (uint256 _kp3rAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) public pure override returns (uint256 _quoteAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n\\n if (sqrtRatioX96 <= type(uint128).max) {\\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\\n } else {\\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\\n }\\n }\\n\\n /// @notice Gets the gas basefee cost to calculate keeper rewards\\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\\n }\\n}\\n\",\"keccak256\":\"0x022987525462636329608fd3032553a123451854d6191d863f068de237302d17\",\"license\":\"MIT\"},\"solidity/contracts/Keep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/peripherals/IBaseErrors.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/external/IKeep3rV1.sol';\\nimport '../interfaces/IKeep3rHelperParameters.sol';\\nimport './peripherals/Governable.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\\n /// @inheritdoc IKeep3rHelperParameters\\n address public immutable override KP3R;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public constant override BOOST_BASE = 10_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBoost = 11_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override maxBoost = 12_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override targetBond = 200 ether;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override workExtraGas = 34_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint32 public override quoteTwapTime = 10 minutes;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBaseFee = 15e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minPriorityFee = 2e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n address public override keep3rV2;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\\n\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Governable(_governance) {\\n KP3R = _kp3r;\\n keep3rV2 = _keep3rV2;\\n\\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\\n if (_poolAddress == address(0)) revert ZeroAddress();\\n _setKp3rWethPool(_poolAddress);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\\n minBoost = _minBoost;\\n emit MinBoostChange(minBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\\n maxBoost = _maxBoost;\\n emit MaxBoostChange(maxBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\\n targetBond = _targetBond;\\n emit TargetBondChange(targetBond);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\\n if (_keep3rV2 == address(0)) revert ZeroAddress();\\n keep3rV2 = _keep3rV2;\\n emit Keep3rV2Change(keep3rV2);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\\n workExtraGas = _workExtraGas;\\n emit WorkExtraGasChange(workExtraGas);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\\n _setQuoteTwapTime(_quoteTwapTime);\\n }\\n\\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\\n quoteTwapTime = _quoteTwapTime;\\n emit QuoteTwapTimeChange(quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\\n minBaseFee = _minBaseFee;\\n emit MinBaseFeeChange(minBaseFee);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\\n minPriorityFee = _minPriorityFee;\\n emit MinPriorityFeeChange(minPriorityFee);\\n }\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function _setKp3rWethPool(address _poolAddress) internal {\\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\\n }\\n\\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\\n\\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\\n\\n return TokenOraclePool(_poolAddress, _isTKNToken0);\\n }\\n}\\n\",\"keccak256\":\"0xff1d1cdd8acec9bed3ac67c0980c1e211e6e09483e30a090c05ed4698a5c0dd4\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n// solhint-disable\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\\n\\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n // Second inequality must be < because the price can never reach the price at the max tick\\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n}\\n\",\"keccak256\":\"0x11b965ba576ff91b4a6e9533c0f334f2b7b6024ee1c54e36d21799de5580899d\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/contracts/sidechain/Keep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3rHelper.sol';\\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\\n\\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\\n /// @inheritdoc IKeep3rHelperSidechain\\n mapping(address => address) public override oracle;\\n /// @inheritdoc IKeep3rHelperSidechain\\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n address public immutable override WETH;\\n\\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\\n /// @param _governance Address of governance\\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\\n /// @dev Oracle pools should use 18 decimals tokens\\n constructor(\\n address _keep3rV2,\\n address _governance,\\n address _kp3r,\\n address _weth,\\n address _kp3rWethOracle,\\n address _wethUsdOracle\\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\\n WETH = _weth;\\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\\n _setQuoteTwapTime(1 days);\\n workExtraGas = 0;\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\\n oracle[_liquidity] = _oracle;\\n emit OracleSet(_liquidity, _oracle);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\\n uint32[] memory _secondsAgos = new uint32[](2);\\n _secondsAgos[1] = quoteTwapTime;\\n\\n /// @dev Oracle is compatible with IUniswapV3Pool\\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\\n if (_poolAddress == address(0)) revert ZeroAddress();\\n _setWethUsdPool(_poolAddress);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n virtual\\n override(Keep3rHelper, IKeep3rHelper)\\n returns (\\n uint256 _boost,\\n uint256 _oneUsdQuote,\\n uint256 _extraGas\\n )\\n {\\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\\n _boost = getRewardBoostFor(_bonds);\\n _extraGas = workExtraGas;\\n }\\n\\n function _setWethUsdPool(address _poolAddress) internal {\\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\\n }\\n\\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\\n return 1;\\n }\\n}\\n\",\"keccak256\":\"0x285aae877c6f2de8dba6fd12f31f1105ca214b3025537081f521dc628f72a677\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct TokenOraclePool {\\n address poolAddress;\\n bool isTKNToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0x76f99ca04361c0459fc9e99f0387ddb76da18cc470ec5bc744e7dc3bf6e9d334\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0xf4748c236ddf409e45e7169c735e2fc54e627b2b3ccd189ebb438ad768f1deb1\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../IKeep3rHelper.sol';\\n\\n/// @title Keep3rHelperSidechain contract\\n/// @notice Contains all the helper functions for sidechain keep3r implementations\\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\\n // Events\\n\\n /// @notice The oracle for a liquidity has been saved\\n /// @param _liquidity The address of the given liquidity\\n /// @param _oraclePool The address of the oracle pool\\n event OracleSet(address _liquidity, address _oraclePool);\\n\\n /// @notice Emitted when the WETH USD pool is changed\\n /// @param _address Address of the new WETH USD pool\\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\\n\\n /// Variables\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n /// @return _weth Address of WETH token\\n // solhint-disable func-name-mixedcase\\n function WETH() external view returns (address _weth);\\n\\n /// @return _oracle The address of the observable pool for given liquidity\\n function oracle(address _liquidity) external view returns (address _oracle);\\n\\n /// @notice WETH-USD pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice Quotes USD to ETH\\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\\n /// @param _usd The amount of USD to quote to ETH\\n /// @return _eth The resulting amount of ETH after quoting the USD\\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\\n\\n /// Methods\\n\\n /// @notice Sets an oracle for a given liquidity\\n /// @param _liquidity The address of the liquidity\\n /// @param _oracle The address of the pool used to quote the liquidity from\\n /// @dev The oracle must contain KP3R as either token0 or token1\\n function setOracle(address _liquidity, address _oracle) external;\\n\\n /// @notice Sets an oracle for querying WETH/USD quote\\n /// @param _poolAddress The address of the pool used as oracle\\n /// @dev The oracle must contain WETH as either token0 or token1\\n function setWethUsdPool(address _poolAddress) external;\\n}\\n\",\"keccak256\":\"0xb6d5459e8a47ab09a052e1acac1c28304f9f0762d20f01819559b4d39729c987\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60c0604052612af8600255612ee0600355680ad78ebc5ac62000006004556184d06005556006805463ffffffff191661025817905564037e11d60060075563773594006008553480156200005257600080fd5b5060405162002625380380620026258339810160408190526200007591620003f1565b8386868483838383816001600160a01b038116620000a55760405162b293ed60e81b815260040160405180910390fd5b600080546001600160a01b03199081166001600160a01b0393841617909155606086901b6001600160601b03191660805260098054909116918516919091179055620000f28185620001e7565b8051600a80546020938401511515600160a01b9081026001600160a81b03199092166001600160a01b03948516179190911791829055604080519383168452910460ff161515928201929092527f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf4108910160405180910390a15050505050606086901b6001600160601b03191660a0525062000192915082905084620001e7565b8051600c80546020909301511515600160a01b026001600160a81b03199093166001600160a01b0390921691909117919091179055620001d56201518062000361565b50506000600555506200047292505050565b60408051808201909152600080825260208201526000826001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156200024157600080fd5b505afa15801562000256573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200027c9190620003cc565b6001600160a01b03161490508015816200031c5750826001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015620002d557600080fd5b505afa158015620002ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003109190620003cc565b6001600160a01b031614155b156200033b5760405163db60809d60e01b815260040160405180910390fd5b604080518082019091526001600160a01b03851681529015156020820152905092915050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de9060200160405180910390a150565b80516001600160a01b0381168114620003c757600080fd5b919050565b600060208284031215620003df57600080fd5b620003ea82620003af565b9392505050565b60008060008060008060c087890312156200040b57600080fd5b6200041687620003af565b95506200042660208801620003af565b94506200043660408801620003af565b93506200044660608801620003af565b92506200045660808801620003af565b91506200046660a08801620003af565b90509295509295509295565b60805160601c60a05160601c61216b620004ba6000396000818161047001526119130152600081816101fd01528181610b6901528181610bad0152611363015261216b6000f3fe608060405234801561001057600080fd5b50600436106101f35760003560e01c80637b40c913116101165780637b40c913146103c05780638561579c146103df5780638a9b1b09146103e85780639aaad679146103f1578063a0d2710714610416578063a62611a214610429578063ab033ea914610432578063ab5dce0014610445578063ab8cedc514610458578063ad5c46481461046b578063b2e0df9614610492578063b93f5af0146104a5578063c84993af146104b8578063ca4f2803146104cb578063dc686d91146104ec578063e244208b14610524578063eb37d34914610537578063ed1bd76c14610560578063f39c38a014610573578063fae63d6114610586578063fe10d7741461059957600080fd5b806305e0b9a0146101f85780630c52583514610235578063117cfc1b1461024a578063160e1e311461025d5780632248e82d14610270578063238efcbc1461029157806325f09e61146102995780632742b9e7146102a25780632750c0f9146102ab578063289adb44146102d857806337090c2f146102eb5780633b67c3bd146102f45780633cc7ab30146103075780633facf2421461031a578063435b21c114610323578063516c3323146103515780635aa6e675146103645780635c38eb3a14610377578063607e48d41461038a578063696a437b1461039d575b600080fd5b61021f7f000000000000000000000000000000000000000000000000000000000000000081565b60405161022c9190611e85565b60405180910390f35b610248610243366004611e11565b6105ac565b005b60095461021f906001600160a01b031681565b61024861026b366004611ba7565b610613565b61028361027e366004611ccd565b610671565b60405190815260200161022c565b6102486106a4565b61028361271081565b61028360045481565b600c546102ca906001600160a01b03811690600160a01b900460ff1682565b60405161022c929190611eb3565b6102486102e6366004611e11565b610730565b61028360035481565b610283610302366004611e11565b610790565b610248610315366004611ba7565b6108f4565b61028360055481565b610336610331366004611e11565b610992565b6040805193845260208401929092529082015260600161022c565b61028361035f366004611e11565b6109c3565b60005461021f906001600160a01b031681565b610248610385366004611be1565b610a1e565b610248610398366004611e11565b610af1565b6103b06103ab366004611ba7565b610b51565b604051901515815260200161022c565b600a546102ca906001600160a01b03811690600160a01b900460ff1682565b61028360025481565b61028360085481565b6006546104019063ffffffff1681565b60405163ffffffff909116815260200161022c565b610283610424366004611e43565b610c04565b61028360075481565b610248610440366004611ba7565b610c37565b610248610453366004611e11565b610cad565b610283610466366004611dc4565b610d0d565b61021f7f000000000000000000000000000000000000000000000000000000000000000081565b6102486104a0366004611e11565b610db1565b6102486104b3366004611e6a565b610e11565b6102836104c6366004611e11565b610e45565b6104de6104d9366004611ba7565b610e57565b60405161022c929190611e99565b6104ff6104fa366004611c1a565b610f45565b60408051600694850b81529290930b602083015215159181019190915260600161022c565b610248610532366004611e11565b611050565b61021f610545366004611ba7565b600b602052600090815260409020546001600160a01b031681565b61028361056e366004611e11565b6110b0565b60015461021f906001600160a01b031681565b610248610594366004611ba7565b6111f6565b6102836105a7366004611ba7565b611251565b6000546001600160a01b031633146105d7576040516354348f0360e01b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b0316331461063e576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166106655760405163d92e233d60e01b815260040160405180910390fd5b61066e8161135d565b50565b60008061068061035f85611251565b905061069c6127106106928386611fc5565b61056e9190611fb1565b949350505050565b6001546001600160a01b031633146106cf57604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161072691611e85565b60405180910390a1565b6000546001600160a01b0316331461075b576040516354348f0360e01b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b90602001610608565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff169183915060019081106107d4576107d46120e5565b63ffffffff90921660209283029190910190910152600c5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd9061081a908590600401611ece565b60006040518083038186803b15801561083257600080fd5b505afa158015610846573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261086e9190810190611cf9565b509050600081600181518110610886576108866120e5565b6020026020010151826000815181106108a1576108a16120e5565b60200260200101516108b39190611fe4565b600c549091506108eb908690600160a01b900460ff166108db576108d68361209f565b6108dd565b825b60065463ffffffff16610d0d565b95945050505050565b6000546001600160a01b0316331461091f576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166109465760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a9161060891611e85565b60008060006109ab61056e670de0b6b3a7640000610790565b91506109b6846109c3565b6005549095929450925050565b60006109d1826004546113f3565b91506000600454836002546003546109e99190612034565b6109f39190611fc5565b6109fd9190611fb1565b600254610a0a9190611f6b565b9050610a17600182611fc5565b9392505050565b6000546001600160a01b03163314610a49576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0382161580610a6657506001600160a01b038116155b15610a845760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038281166000908152600b60205260409081902080546001600160a01b03191692841692909217909155517fc1d3048301c0d23629a2532c8defa6d68f8e1a0e4157918769e9fb1b2eeb888e90610ae59084908490611e99565b60405180910390a15050565b6000546001600160a01b03163314610b1c576040516354348f0360e01b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b90602001610608565b6000806000610b5f84610e57565b80925081935050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610bab575060019392505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614610bfd57604051637d7c8f2760e11b815260040160405180910390fd5b5050919050565b600080610c1d610c1884600687900b611f83565b611409565b90506108eb600160601b86836001600160a01b0316611817565b6000546001600160a01b03163314610c62576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90610608908390611e85565b6000546001600160a01b03163314610cd8576040516354348f0360e01b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e90602001610608565b600080610d21610c1884600687900b611f83565b90506001600160801b036001600160a01b03821611610d71576000610d4f6001600160a01b03831680611fc5565b9050610d69600160c01b876001600160801b031683611817565b925050610da9565b6000610d8b6001600160a01b03831680600160401b611817565b9050610da5600160801b876001600160801b031683611817565b9250505b509392505050565b6000546001600160a01b03163314610ddc576040516354348f0360e01b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa90602001610608565b6000546001600160a01b03163314610e3c576040516354348f0360e01b815260040160405180910390fd5b61066e816118c5565b6000610e513283610671565b92915050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610e9357600080fd5b505afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190611bc4565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610f0457600080fd5b505afa158015610f18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3c9190611bc4565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b8152600401610f769190611ece565b60006040518083038186803b158015610f8e57600080fd5b505afa925050508015610fc357506040513d6000823e601f3d908101601f19168201604052610fc09190810190611cf9565b60015b610ffd573d808015610ff1576040519150601f19603f3d011682016040523d82523d6000602084013e610ff6565b606091505b5050611049565b81600081518110611010576110106120e5565b602002602001015194506001825111156110425781600181518110611037576110376120e5565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b0316331461107b576040516354348f0360e01b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d5415922190602001610608565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff169183915060019081106110f4576110f46120e5565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd9061113a908590600401611ece565b60006040518083038186803b15801561115257600080fd5b505afa158015611166573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261118e9190810190611cf9565b5090506000816001815181106111a6576111a66120e5565b6020026020010151826000815181106111c1576111c16120e5565b60200260200101516111d39190611fe4565b600a549091506108eb908690600160a01b900460ff166108db576108d68361209f565b6000546001600160a01b03163314611221576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166112485760405163d92e233d60e01b815260040160405180910390fd5b61066e8161190d565b600080600960009054906101000a90046001600160a01b03166001600160a01b0316631ef94b916040518163ffffffff1660e01b815260040160206040518083038186803b1580156112a257600080fd5b505afa1580156112b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112da9190611bc4565b60095460405163a39744b560e01b81529192506001600160a01b03169063a39744b59061130d9086908590600401611e99565b60206040518083038186803b15801561132557600080fd5b505afa158015611339573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a179190611e2a565b611387817f00000000000000000000000000000000000000000000000000000000000000006119a3565b8051600a80546020909301511515600160a01b9081026001600160a81b03199094166001600160a01b039384161793909317908190556040517f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf410893610608938316920460ff1690611eb3565b60008183106114025781610a17565b5090919050565b60008060008360020b12611420578260020b61142d565b8260020b61142d90612082565b905061143c620d89e71961205f565b60020b8111156114765760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b60006001821661148a57600160801b61149c565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b0316905060028216156114d15760806114cc826ffff97272373d413259a46990580e213a611fc5565b901c90505b60048216156114fb5760806114f6826ffff2e50f5f656932ef12357cf3c7fdcc611fc5565b901c90505b6008821615611525576080611520826fffe5caca7e10e4e61c3624eaa0941cd0611fc5565b901c90505b601082161561154f57608061154a826fffcb9843d60f6159c9db58835c926644611fc5565b901c90505b6020821615611579576080611574826fff973b41fa98c081472e6896dfb254c0611fc5565b901c90505b60408216156115a357608061159e826fff2ea16466c96a3843ec78b326b52861611fc5565b901c90505b60808216156115cd5760806115c8826ffe5dee046a99a2a811c461f1969c3053611fc5565b901c90505b6101008216156115f85760806115f3826ffcbe86c7900a88aedcffc83b479aa3a4611fc5565b901c90505b61020082161561162357608061161e826ff987a7253ac413176f2b074cf7815e54611fc5565b901c90505b61040082161561164e576080611649826ff3392b0822b70005940c7a398e4b70f3611fc5565b901c90505b610800821615611679576080611674826fe7159475a2c29b7443b29c7fa6e889d9611fc5565b901c90505b6110008216156116a457608061169f826fd097f3bdfd2022b8845ad8f792aa5825611fc5565b901c90505b6120008216156116cf5760806116ca826fa9f746462d870fdf8a65dc1f90e061e5611fc5565b901c90505b6140008216156116fa5760806116f5826f70d869a156d2a1b890bb3df62baf32f7611fc5565b901c90505b618000821615611725576080611720826f31be135f97d08fd981231505542fcfa6611fc5565b901c90505b6201000082161561175157608061174c826f09aa508b5b7a84e1c677de54f3e99bc9611fc5565b901c90505b6202000082161561177c576080611777826e5d6af8dedb81196699c329225ee604611fc5565b901c90505b620400008216156117a65760806117a1826d2216e584f5fa1ea926041bedfe98611fc5565b901c90505b620800008216156117ce5760806117c9826b048a170391f7dc42444e8fa2611fc5565b901c90505b60008460020b13156117e9576117e681600019611fb1565b90505b6117f7600160201b8261204b565b15611803576001611806565b60005b61069c9060ff16602083901c611f6b565b600080806000198587098587029250828110838203039150508060001415611851576000841161184657600080fd5b508290049050610a17565b80841161185d57600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de90602001610608565b611937817f00000000000000000000000000000000000000000000000000000000000000006119a3565b8051600c80546020909301511515600160a01b9081026001600160a81b03199094166001600160a01b039384161793909317908190556040517fefe4783561b790425a9d83dd379f0e184938b04965a63d14ec51c27cb4ca1b3c93610608938316920460ff1690611eb3565b60408051808201909152600080825260208201526000826001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156119fc57600080fd5b505afa158015611a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a349190611bc4565b6001600160a01b0316149050801581611acf5750826001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015611a8b57600080fd5b505afa158015611a9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac39190611bc4565b6001600160a01b031614155b15611aed5760405163db60809d60e01b815260040160405180910390fd5b604080518082019091526001600160a01b03851681529015156020820152905092915050565b600082601f830112611b2457600080fd5b81516020611b39611b3483611f48565b611f18565b80838252828201915082860187848660051b8901011115611b5957600080fd5b60005b85811015611b81578151611b6f81612111565b84529284019290840190600101611b5c565b5090979650505050505050565b803563ffffffff81168114611ba257600080fd5b919050565b600060208284031215611bb957600080fd5b8135610a1781612111565b600060208284031215611bd657600080fd5b8151610a1781612111565b60008060408385031215611bf457600080fd5b8235611bff81612111565b91506020830135611c0f81612111565b809150509250929050565b60008060408385031215611c2d57600080fd5b8235611c3881612111565b91506020838101356001600160401b03811115611c5457600080fd5b8401601f81018613611c6557600080fd5b8035611c73611b3482611f48565b80828252848201915084840189868560051b8701011115611c9357600080fd5b600094505b83851015611cbd57611ca981611b8e565b835260019490940193918501918501611c98565b5080955050505050509250929050565b60008060408385031215611ce057600080fd5b8235611ceb81612111565b946020939093013593505050565b60008060408385031215611d0c57600080fd5b82516001600160401b0380821115611d2357600080fd5b818501915085601f830112611d3757600080fd5b81516020611d47611b3483611f48565b8083825282820191508286018a848660051b8901011115611d6757600080fd5b600096505b84871015611d93578051611d7f81612126565b835260019690960195918301918301611d6c565b5091880151919650909350505080821115611dad57600080fd5b50611dba85828601611b13565b9150509250929050565b600080600060608486031215611dd957600080fd5b83356001600160801b0381168114611df057600080fd5b92506020840135611e0081612126565b929592945050506040919091013590565b600060208284031215611e2357600080fd5b5035919050565b600060208284031215611e3c57600080fd5b5051919050565b600080600060608486031215611e5857600080fd5b833592506020840135611e0081612126565b600060208284031215611e7c57600080fd5b610a1782611b8e565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015611f0c57835163ffffffff1683529284019291840191600101611eea565b50909695505050505050565b604051601f8201601f191681016001600160401b0381118282101715611f4057611f406120fb565b604052919050565b60006001600160401b03821115611f6157611f616120fb565b5060051b60200190565b60008219821115611f7e57611f7e6120b9565b500190565b600082611f9257611f926120cf565b600160ff1b821460001984141615611fac57611fac6120b9565b500590565b600082611fc057611fc06120cf565b500490565b6000816000190483118215151615611fdf57611fdf6120b9565b500290565b60008160060b8360060b6000811281667fffffffffffff190183128115161561200f5761200f6120b9565b81667fffffffffffff01831381161561202a5761202a6120b9565b5090039392505050565b600082821015612046576120466120b9565b500390565b60008261205a5761205a6120cf565b500690565b60008160020b627fffff19811415612079576120796120b9565b60000392915050565b6000600160ff1b821415612098576120986120b9565b5060000390565b60008160060b667fffffffffffff19811415612079576120795b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461066e57600080fd5b8060060b811461066e57600080fdfea264697066735822122013caec67b9b218ca18a717b11d92ba62488d93a218d97f2464182db56918e05c64736f6c63430008070033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101f35760003560e01c80637b40c913116101165780637b40c913146103c05780638561579c146103df5780638a9b1b09146103e85780639aaad679146103f1578063a0d2710714610416578063a62611a214610429578063ab033ea914610432578063ab5dce0014610445578063ab8cedc514610458578063ad5c46481461046b578063b2e0df9614610492578063b93f5af0146104a5578063c84993af146104b8578063ca4f2803146104cb578063dc686d91146104ec578063e244208b14610524578063eb37d34914610537578063ed1bd76c14610560578063f39c38a014610573578063fae63d6114610586578063fe10d7741461059957600080fd5b806305e0b9a0146101f85780630c52583514610235578063117cfc1b1461024a578063160e1e311461025d5780632248e82d14610270578063238efcbc1461029157806325f09e61146102995780632742b9e7146102a25780632750c0f9146102ab578063289adb44146102d857806337090c2f146102eb5780633b67c3bd146102f45780633cc7ab30146103075780633facf2421461031a578063435b21c114610323578063516c3323146103515780635aa6e675146103645780635c38eb3a14610377578063607e48d41461038a578063696a437b1461039d575b600080fd5b61021f7f000000000000000000000000000000000000000000000000000000000000000081565b60405161022c9190611e85565b60405180910390f35b610248610243366004611e11565b6105ac565b005b60095461021f906001600160a01b031681565b61024861026b366004611ba7565b610613565b61028361027e366004611ccd565b610671565b60405190815260200161022c565b6102486106a4565b61028361271081565b61028360045481565b600c546102ca906001600160a01b03811690600160a01b900460ff1682565b60405161022c929190611eb3565b6102486102e6366004611e11565b610730565b61028360035481565b610283610302366004611e11565b610790565b610248610315366004611ba7565b6108f4565b61028360055481565b610336610331366004611e11565b610992565b6040805193845260208401929092529082015260600161022c565b61028361035f366004611e11565b6109c3565b60005461021f906001600160a01b031681565b610248610385366004611be1565b610a1e565b610248610398366004611e11565b610af1565b6103b06103ab366004611ba7565b610b51565b604051901515815260200161022c565b600a546102ca906001600160a01b03811690600160a01b900460ff1682565b61028360025481565b61028360085481565b6006546104019063ffffffff1681565b60405163ffffffff909116815260200161022c565b610283610424366004611e43565b610c04565b61028360075481565b610248610440366004611ba7565b610c37565b610248610453366004611e11565b610cad565b610283610466366004611dc4565b610d0d565b61021f7f000000000000000000000000000000000000000000000000000000000000000081565b6102486104a0366004611e11565b610db1565b6102486104b3366004611e6a565b610e11565b6102836104c6366004611e11565b610e45565b6104de6104d9366004611ba7565b610e57565b60405161022c929190611e99565b6104ff6104fa366004611c1a565b610f45565b60408051600694850b81529290930b602083015215159181019190915260600161022c565b610248610532366004611e11565b611050565b61021f610545366004611ba7565b600b602052600090815260409020546001600160a01b031681565b61028361056e366004611e11565b6110b0565b60015461021f906001600160a01b031681565b610248610594366004611ba7565b6111f6565b6102836105a7366004611ba7565b611251565b6000546001600160a01b031633146105d7576040516354348f0360e01b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b0316331461063e576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166106655760405163d92e233d60e01b815260040160405180910390fd5b61066e8161135d565b50565b60008061068061035f85611251565b905061069c6127106106928386611fc5565b61056e9190611fb1565b949350505050565b6001546001600160a01b031633146106cf57604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161072691611e85565b60405180910390a1565b6000546001600160a01b0316331461075b576040516354348f0360e01b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b90602001610608565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff169183915060019081106107d4576107d46120e5565b63ffffffff90921660209283029190910190910152600c5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd9061081a908590600401611ece565b60006040518083038186803b15801561083257600080fd5b505afa158015610846573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261086e9190810190611cf9565b509050600081600181518110610886576108866120e5565b6020026020010151826000815181106108a1576108a16120e5565b60200260200101516108b39190611fe4565b600c549091506108eb908690600160a01b900460ff166108db576108d68361209f565b6108dd565b825b60065463ffffffff16610d0d565b95945050505050565b6000546001600160a01b0316331461091f576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166109465760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a9161060891611e85565b60008060006109ab61056e670de0b6b3a7640000610790565b91506109b6846109c3565b6005549095929450925050565b60006109d1826004546113f3565b91506000600454836002546003546109e99190612034565b6109f39190611fc5565b6109fd9190611fb1565b600254610a0a9190611f6b565b9050610a17600182611fc5565b9392505050565b6000546001600160a01b03163314610a49576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0382161580610a6657506001600160a01b038116155b15610a845760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038281166000908152600b60205260409081902080546001600160a01b03191692841692909217909155517fc1d3048301c0d23629a2532c8defa6d68f8e1a0e4157918769e9fb1b2eeb888e90610ae59084908490611e99565b60405180910390a15050565b6000546001600160a01b03163314610b1c576040516354348f0360e01b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b90602001610608565b6000806000610b5f84610e57565b80925081935050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610bab575060019392505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614610bfd57604051637d7c8f2760e11b815260040160405180910390fd5b5050919050565b600080610c1d610c1884600687900b611f83565b611409565b90506108eb600160601b86836001600160a01b0316611817565b6000546001600160a01b03163314610c62576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90610608908390611e85565b6000546001600160a01b03163314610cd8576040516354348f0360e01b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e90602001610608565b600080610d21610c1884600687900b611f83565b90506001600160801b036001600160a01b03821611610d71576000610d4f6001600160a01b03831680611fc5565b9050610d69600160c01b876001600160801b031683611817565b925050610da9565b6000610d8b6001600160a01b03831680600160401b611817565b9050610da5600160801b876001600160801b031683611817565b9250505b509392505050565b6000546001600160a01b03163314610ddc576040516354348f0360e01b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa90602001610608565b6000546001600160a01b03163314610e3c576040516354348f0360e01b815260040160405180910390fd5b61066e816118c5565b6000610e513283610671565b92915050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610e9357600080fd5b505afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190611bc4565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610f0457600080fd5b505afa158015610f18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3c9190611bc4565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b8152600401610f769190611ece565b60006040518083038186803b158015610f8e57600080fd5b505afa925050508015610fc357506040513d6000823e601f3d908101601f19168201604052610fc09190810190611cf9565b60015b610ffd573d808015610ff1576040519150601f19603f3d011682016040523d82523d6000602084013e610ff6565b606091505b5050611049565b81600081518110611010576110106120e5565b602002602001015194506001825111156110425781600181518110611037576110376120e5565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b0316331461107b576040516354348f0360e01b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d5415922190602001610608565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff169183915060019081106110f4576110f46120e5565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd9061113a908590600401611ece565b60006040518083038186803b15801561115257600080fd5b505afa158015611166573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261118e9190810190611cf9565b5090506000816001815181106111a6576111a66120e5565b6020026020010151826000815181106111c1576111c16120e5565b60200260200101516111d39190611fe4565b600a549091506108eb908690600160a01b900460ff166108db576108d68361209f565b6000546001600160a01b03163314611221576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166112485760405163d92e233d60e01b815260040160405180910390fd5b61066e8161190d565b600080600960009054906101000a90046001600160a01b03166001600160a01b0316631ef94b916040518163ffffffff1660e01b815260040160206040518083038186803b1580156112a257600080fd5b505afa1580156112b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112da9190611bc4565b60095460405163a39744b560e01b81529192506001600160a01b03169063a39744b59061130d9086908590600401611e99565b60206040518083038186803b15801561132557600080fd5b505afa158015611339573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a179190611e2a565b611387817f00000000000000000000000000000000000000000000000000000000000000006119a3565b8051600a80546020909301511515600160a01b9081026001600160a81b03199094166001600160a01b039384161793909317908190556040517f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf410893610608938316920460ff1690611eb3565b60008183106114025781610a17565b5090919050565b60008060008360020b12611420578260020b61142d565b8260020b61142d90612082565b905061143c620d89e71961205f565b60020b8111156114765760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b60006001821661148a57600160801b61149c565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b0316905060028216156114d15760806114cc826ffff97272373d413259a46990580e213a611fc5565b901c90505b60048216156114fb5760806114f6826ffff2e50f5f656932ef12357cf3c7fdcc611fc5565b901c90505b6008821615611525576080611520826fffe5caca7e10e4e61c3624eaa0941cd0611fc5565b901c90505b601082161561154f57608061154a826fffcb9843d60f6159c9db58835c926644611fc5565b901c90505b6020821615611579576080611574826fff973b41fa98c081472e6896dfb254c0611fc5565b901c90505b60408216156115a357608061159e826fff2ea16466c96a3843ec78b326b52861611fc5565b901c90505b60808216156115cd5760806115c8826ffe5dee046a99a2a811c461f1969c3053611fc5565b901c90505b6101008216156115f85760806115f3826ffcbe86c7900a88aedcffc83b479aa3a4611fc5565b901c90505b61020082161561162357608061161e826ff987a7253ac413176f2b074cf7815e54611fc5565b901c90505b61040082161561164e576080611649826ff3392b0822b70005940c7a398e4b70f3611fc5565b901c90505b610800821615611679576080611674826fe7159475a2c29b7443b29c7fa6e889d9611fc5565b901c90505b6110008216156116a457608061169f826fd097f3bdfd2022b8845ad8f792aa5825611fc5565b901c90505b6120008216156116cf5760806116ca826fa9f746462d870fdf8a65dc1f90e061e5611fc5565b901c90505b6140008216156116fa5760806116f5826f70d869a156d2a1b890bb3df62baf32f7611fc5565b901c90505b618000821615611725576080611720826f31be135f97d08fd981231505542fcfa6611fc5565b901c90505b6201000082161561175157608061174c826f09aa508b5b7a84e1c677de54f3e99bc9611fc5565b901c90505b6202000082161561177c576080611777826e5d6af8dedb81196699c329225ee604611fc5565b901c90505b620400008216156117a65760806117a1826d2216e584f5fa1ea926041bedfe98611fc5565b901c90505b620800008216156117ce5760806117c9826b048a170391f7dc42444e8fa2611fc5565b901c90505b60008460020b13156117e9576117e681600019611fb1565b90505b6117f7600160201b8261204b565b15611803576001611806565b60005b61069c9060ff16602083901c611f6b565b600080806000198587098587029250828110838203039150508060001415611851576000841161184657600080fd5b508290049050610a17565b80841161185d57600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de90602001610608565b611937817f00000000000000000000000000000000000000000000000000000000000000006119a3565b8051600c80546020909301511515600160a01b9081026001600160a81b03199094166001600160a01b039384161793909317908190556040517fefe4783561b790425a9d83dd379f0e184938b04965a63d14ec51c27cb4ca1b3c93610608938316920460ff1690611eb3565b60408051808201909152600080825260208201526000826001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156119fc57600080fd5b505afa158015611a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a349190611bc4565b6001600160a01b0316149050801581611acf5750826001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015611a8b57600080fd5b505afa158015611a9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac39190611bc4565b6001600160a01b031614155b15611aed5760405163db60809d60e01b815260040160405180910390fd5b604080518082019091526001600160a01b03851681529015156020820152905092915050565b600082601f830112611b2457600080fd5b81516020611b39611b3483611f48565b611f18565b80838252828201915082860187848660051b8901011115611b5957600080fd5b60005b85811015611b81578151611b6f81612111565b84529284019290840190600101611b5c565b5090979650505050505050565b803563ffffffff81168114611ba257600080fd5b919050565b600060208284031215611bb957600080fd5b8135610a1781612111565b600060208284031215611bd657600080fd5b8151610a1781612111565b60008060408385031215611bf457600080fd5b8235611bff81612111565b91506020830135611c0f81612111565b809150509250929050565b60008060408385031215611c2d57600080fd5b8235611c3881612111565b91506020838101356001600160401b03811115611c5457600080fd5b8401601f81018613611c6557600080fd5b8035611c73611b3482611f48565b80828252848201915084840189868560051b8701011115611c9357600080fd5b600094505b83851015611cbd57611ca981611b8e565b835260019490940193918501918501611c98565b5080955050505050509250929050565b60008060408385031215611ce057600080fd5b8235611ceb81612111565b946020939093013593505050565b60008060408385031215611d0c57600080fd5b82516001600160401b0380821115611d2357600080fd5b818501915085601f830112611d3757600080fd5b81516020611d47611b3483611f48565b8083825282820191508286018a848660051b8901011115611d6757600080fd5b600096505b84871015611d93578051611d7f81612126565b835260019690960195918301918301611d6c565b5091880151919650909350505080821115611dad57600080fd5b50611dba85828601611b13565b9150509250929050565b600080600060608486031215611dd957600080fd5b83356001600160801b0381168114611df057600080fd5b92506020840135611e0081612126565b929592945050506040919091013590565b600060208284031215611e2357600080fd5b5035919050565b600060208284031215611e3c57600080fd5b5051919050565b600080600060608486031215611e5857600080fd5b833592506020840135611e0081612126565b600060208284031215611e7c57600080fd5b610a1782611b8e565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015611f0c57835163ffffffff1683529284019291840191600101611eea565b50909695505050505050565b604051601f8201601f191681016001600160401b0381118282101715611f4057611f406120fb565b604052919050565b60006001600160401b03821115611f6157611f616120fb565b5060051b60200190565b60008219821115611f7e57611f7e6120b9565b500190565b600082611f9257611f926120cf565b600160ff1b821460001984141615611fac57611fac6120b9565b500590565b600082611fc057611fc06120cf565b500490565b6000816000190483118215151615611fdf57611fdf6120b9565b500290565b60008160060b8360060b6000811281667fffffffffffff190183128115161561200f5761200f6120b9565b81667fffffffffffff01831381161561202a5761202a6120b9565b5090039392505050565b600082821015612046576120466120b9565b500390565b60008261205a5761205a6120cf565b500690565b60008160020b627fffff19811415612079576120796120b9565b60000392915050565b6000600160ff1b821415612098576120986120b9565b5060000390565b60008160060b667fffffffffffff19811415612079576120795b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461066e57600080fd5b8060060b811461066e57600080fdfea264697066735822122013caec67b9b218ca18a717b11d92ba62488d93a218d97f2464182db56918e05c64736f6c63430008070033", + "devdoc": { + "kind": "dev", + "methods": { + "bonds(address)": { + "params": { + "_keeper": "The address of the keeper to check" + }, + "returns": { + "_amountBonded": "The amount of KP3R the keeper has bonded" + } + }, + "constructor": { + "details": "Oracle pools should use 18 decimals tokens", + "params": { + "_governance": "Address of governance", + "_keep3rV2": "Address of sidechain Keep3r implementation", + "_kp3rWethOracle": "Address of oracle used for KP3R/WETH quote", + "_wethUsdOracle": "Address of oracle used for WETH/USD quote" + } + }, + "getKP3RsAtTick(uint256,int56,uint256)": { + "params": { + "_liquidityAmount": "Amount of liquidity to be converted", + "_tickDifference": "Tick value used to calculate the quote", + "_timeInterval": "Time value used to calculate the quote" + }, + "returns": { + "_kp3rAmount": "Amount of KP3R tokens underlying on the given liquidity" + } + }, + "getPaymentParams(uint256)": { + "params": { + "_bonds": "Amount of bonded KP3R owned by the keeper" + }, + "returns": { + "_boost": "Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R", + "_extraGas": "Amount of extra gas that should be added to the gas spent", + "_oneUsdQuote": "Amount of KP3R tokens equivalent to 1 ETH" + } + }, + "getPoolTokens(address)": { + "params": { + "_pool": "Address of the correspondant pool" + }, + "returns": { + "_token0": "Address of the first token of the pair", + "_token1": "Address of the second token of the pair" + } + }, + "getQuoteAtTick(uint128,int56,uint256)": { + "params": { + "_baseAmount": "Amount of token to be converted", + "_tickDifference": "Tick value used to calculate the quote", + "_timeInterval": "Time value used to calculate the quote" + }, + "returns": { + "_quoteAmount": "Amount of credits deserved for the baseAmount at the tick value" + } + }, + "getRewardAmount(uint256)": { + "params": { + "_gasUsed": "The amount of gas used that will be rewarded" + }, + "returns": { + "_amount": "The amount of KP3R that should be awarded to tx.origin" + } + }, + "getRewardAmountFor(address,uint256)": { + "params": { + "_gasUsed": "The amount of gas used that will be rewarded", + "_keeper": "The address of the keeper to check" + }, + "returns": { + "_kp3r": "The amount of KP3R that should be awarded to the keeper" + } + }, + "getRewardBoostFor(uint256)": { + "details": "If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%", + "params": { + "_bonds": "The amount of KP3R tokens bonded by the keeper" + }, + "returns": { + "_rewardBoost": "The reward boost that corresponds to the keeper" + } + }, + "isKP3RToken0(address)": { + "params": { + "_pool": "Address of the correspondant pool" + }, + "returns": { + "_isKP3RToken0": "Boolean indicating the order of the tokens in the pair" + } + }, + "observe(address,uint32[])": { + "params": { + "_pool": "Address of the pool to observe", + "_secondsAgo": "Array with time references to observe" + }, + "returns": { + "_success": "Boolean indicating if the observe call was succesfull", + "_tickCumulative1": "Cumulative sum of ticks until first time reference", + "_tickCumulative2": "Cumulative sum of ticks until second time reference" + } + }, + "quote(uint256)": { + "details": "This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas", + "params": { + "_eth": "The amount of ETH" + }, + "returns": { + "_amountOut": "The amount of KP3R" + } + }, + "quoteUsdToEth(uint256)": { + "details": "Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R", + "params": { + "_usd": "The amount of USD to quote to ETH" + }, + "returns": { + "_amountOut": "The resulting amount of ETH after quoting the USD" + } + }, + "setGovernance(address)": { + "params": { + "_governance": "The address being proposed as the new governance" + } + }, + "setKeep3rV2(address)": { + "params": { + "_keep3rV2": "The address of Keep3r V2" + } + }, + "setKp3rWethPool(address)": { + "params": { + "_poolAddress": "The address of the KP3R-WETH pool" + } + }, + "setMaxBoost(uint256)": { + "params": { + "_maxBoost": "The maximum boost multiplier" + } + }, + "setMinBaseFee(uint256)": { + "params": { + "_minBaseFee": "The minimum rewarded gas fee" + } + }, + "setMinBoost(uint256)": { + "params": { + "_minBoost": "The minimum boost multiplier" + } + }, + "setMinPriorityFee(uint256)": { + "params": { + "_minPriorityFee": "The minimum rewarded priority fee" + } + }, + "setOracle(address,address)": { + "details": "The oracle must contain KP3R as either token0 or token1", + "params": { + "_liquidity": "The address of the liquidity", + "_oracle": "The address of the pool used to quote the liquidity from" + } + }, + "setQuoteTwapTime(uint32)": { + "params": { + "_quoteTwapTime": "The twap time for quoting" + } + }, + "setTargetBond(uint256)": { + "params": { + "_targetBond": "The target bond amount" + } + }, + "setWethUsdPool(address)": { + "details": "The oracle must contain WETH as either token0 or token1", + "params": { + "_poolAddress": "The address of the pool used as oracle" + } + }, + "setWorkExtraGas(uint256)": { + "params": { + "_workExtraGas": "The work extra gas" + } + } + }, + "stateVariables": { + "oracle": { + "return": "_oracle The address of the observable pool for given liquidity", + "returns": { + "_0": "_oracle The address of the observable pool for given liquidity" + } + }, + "wethUSDPool": { + "returns": { + "isTKNToken0": "True if calling the token0 method of the pool returns the WETH token address", + "poolAddress": "Address of the pool" + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidOraclePool()": [ + { + "notice": "Throws when pool does not have KP3R as token0 nor token1" + } + ], + "LiquidityPairInvalid()": [ + { + "notice": "Throws when none of the tokens in the liquidity pair is KP3R" + } + ], + "NoGovernanceZeroAddress()": [ + { + "notice": "Throws if trying to set governance to zero address" + } + ], + "OnlyGovernance()": [ + { + "notice": "Throws if the caller of the function is not governance" + } + ], + "OnlyPendingGovernance()": [ + { + "notice": "Throws if the caller of the function is not pendingGovernance" + } + ], + "ZeroAddress()": [ + { + "notice": "Throws if a variable is assigned to the zero address" + } + ] + }, + "events": { + "GovernanceProposal(address)": { + "notice": "Emitted when a new governance is proposed" + }, + "GovernanceSet(address)": { + "notice": "Emitted when pendingGovernance accepts to be governance" + }, + "Keep3rV2Change(address)": { + "notice": "Emitted when the Keep3r V2 address is changed" + }, + "Kp3rWethPoolChange(address,bool)": { + "notice": "Emitted when the kp3r weth pool is changed" + }, + "MaxBoostChange(uint256)": { + "notice": "Emitted when the maximum boost multiplier is changed" + }, + "MinBaseFeeChange(uint256)": { + "notice": "Emitted when minimum rewarded gas fee is changed" + }, + "MinBoostChange(uint256)": { + "notice": "Emitted when the minimum boost multiplier is changed" + }, + "MinPriorityFeeChange(uint256)": { + "notice": "Emitted when minimum rewarded priority fee is changed" + }, + "OracleSet(address,address)": { + "notice": "The oracle for a liquidity has been saved" + }, + "QuoteTwapTimeChange(uint32)": { + "notice": "Emitted when the quote twap time is changed" + }, + "TargetBondChange(uint256)": { + "notice": "Emitted when the target bond amount is changed" + }, + "WethUSDPoolChange(address,bool)": { + "notice": "Emitted when the WETH USD pool is changed" + }, + "WorkExtraGasChange(uint256)": { + "notice": "Emitted when the work extra gas amount is changed" + } + }, + "kind": "user", + "methods": { + "BOOST_BASE()": { + "notice": "The boost base used to calculate the boost rewards for the keeper" + }, + "KP3R()": { + "notice": "Address of KP3R token" + }, + "WETH()": { + "notice": "Ethereum mainnet WETH address used for quoting references" + }, + "acceptGovernance()": { + "notice": "Changes the governance from the current governance to the previously proposed address" + }, + "bonds(address)": { + "notice": "Uses valid wKP3R address from Keep3rSidechain to query keeper bonds" + }, + "getKP3RsAtTick(uint256,int56,uint256)": { + "notice": "Given a tick and a liquidity amount, calculates the underlying KP3R tokens" + }, + "getPaymentParams(uint256)": { + "notice": "Get multiplier, quote, and extra, in order to calculate keeper payment" + }, + "getPoolTokens(address)": { + "notice": "Given a pool address, returns the underlying tokens of the pair" + }, + "getQuoteAtTick(uint128,int56,uint256)": { + "notice": "Given a tick and a token amount, calculates the output in correspondant token" + }, + "getRewardAmount(uint256)": { + "notice": "Calculates the reward (in KP3R) that corresponds to tx.origin for using gas" + }, + "getRewardAmountFor(address,uint256)": { + "notice": "Calculates the reward (in KP3R) that corresponds to a keeper for using gas" + }, + "getRewardBoostFor(uint256)": { + "notice": "Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded" + }, + "governance()": { + "notice": "Stores the governance address" + }, + "isKP3RToken0(address)": { + "notice": "Defines the order of the tokens in the pair for twap calculations" + }, + "keep3rV2()": { + "notice": "Address of Keep3r V2" + }, + "kp3rWethPool()": { + "notice": "KP3R-WETH pool that is being used as oracle" + }, + "maxBoost()": { + "notice": "The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE" + }, + "minBaseFee()": { + "notice": "The minimum base fee that is used to calculate keeper rewards" + }, + "minBoost()": { + "notice": "The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE" + }, + "minPriorityFee()": { + "notice": "The minimum priority fee that is also rewarded for keepers" + }, + "observe(address,uint32[])": { + "notice": "Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment" + }, + "pendingGovernance()": { + "notice": "Stores the pendingGovernance address" + }, + "quote(uint256)": { + "notice": "Calculates the amount of KP3R that corresponds to the ETH passed into the function" + }, + "quoteTwapTime()": { + "notice": "The twap time for quoting" + }, + "quoteUsdToEth(uint256)": { + "notice": "Quotes USD to ETH" + }, + "setGovernance(address)": { + "notice": "Proposes a new address to be governance" + }, + "setKeep3rV2(address)": { + "notice": "Sets the Keep3r V2 address" + }, + "setKp3rWethPool(address)": { + "notice": "Sets KP3R-WETH pool" + }, + "setMaxBoost(uint256)": { + "notice": "Sets the maximum boost multiplier" + }, + "setMinBaseFee(uint256)": { + "notice": "Sets the minimum rewarded gas fee" + }, + "setMinBoost(uint256)": { + "notice": "Sets the minimum boost multiplier" + }, + "setMinPriorityFee(uint256)": { + "notice": "Sets the minimum rewarded gas priority fee" + }, + "setOracle(address,address)": { + "notice": "Sets an oracle for a given liquidity" + }, + "setQuoteTwapTime(uint32)": { + "notice": "Sets the quote twap time" + }, + "setTargetBond(uint256)": { + "notice": "Sets the target bond amount" + }, + "setWethUsdPool(address)": { + "notice": "Sets an oracle for querying WETH/USD quote" + }, + "setWorkExtraGas(uint256)": { + "notice": "Sets the work extra gas amount" + }, + "targetBond()": { + "notice": "The targeted amount of bonded KP3Rs to max-up reward multiplier For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get the maximum boost possible in his rewards, if it's less, the reward boost will be proportional" + }, + "wethUSDPool()": { + "notice": "WETH-USD pool that is being used as oracle" + }, + "workExtraGas()": { + "notice": "The amount of unaccounted gas that is going to be added to keeper payments" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 5362, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "governance", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 5366, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "pendingGovernance", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 2989, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "minBoost", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 2994, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "maxBoost", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 2999, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "targetBond", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 3004, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "workExtraGas", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 3009, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "quoteTwapTime", + "offset": 0, + "slot": "6", + "type": "t_uint32" + }, + { + "astId": 3014, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "minBaseFee", + "offset": 0, + "slot": "7", + "type": "t_uint256" + }, + { + "astId": 3019, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "minPriorityFee", + "offset": 0, + "slot": "8", + "type": "t_uint256" + }, + { + "astId": 3023, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "keep3rV2", + "offset": 0, + "slot": "9", + "type": "t_address" + }, + { + "astId": 3028, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "kp3rWethPool", + "offset": 0, + "slot": "10", + "type": "t_struct(TokenOraclePool)12841_storage" + }, + { + "astId": 9751, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "oracle", + "offset": 0, + "slot": "11", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 9756, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "wethUSDPool", + "offset": 0, + "slot": "12", + "type": "t_struct(TokenOraclePool)12841_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_struct(TokenOraclePool)12841_storage": { + "encoding": "inplace", + "label": "struct IKeep3rHelperParameters.TokenOraclePool", + "members": [ + { + "astId": 12838, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "poolAddress", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 12840, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "isTKNToken0", + "offset": 20, + "slot": "0", + "type": "t_bool" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimisticGoerli/Keep3rHelperSidechainForTestnet.json b/deployments/optimisticGoerli/Keep3rHelperSidechainForTestnet.json deleted file mode 100644 index bbf09de..0000000 --- a/deployments/optimisticGoerli/Keep3rHelperSidechainForTestnet.json +++ /dev/null @@ -1,1517 +0,0 @@ -{ - "address": "0x4C4cCAf09004838851c8AC5B3fc822A09c9f3Ec2", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_keep3rV2", - "type": "address" - }, - { - "internalType": "address", - "name": "_governance", - "type": "address" - }, - { - "internalType": "address", - "name": "_kp3r", - "type": "address" - }, - { - "internalType": "address", - "name": "_weth", - "type": "address" - }, - { - "internalType": "address", - "name": "_kp3rWethOracle", - "type": "address" - }, - { - "internalType": "address", - "name": "_wethUsdOracle", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "InvalidOraclePool", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidityPairInvalid", - "type": "error" - }, - { - "inputs": [], - "name": "NoGovernanceZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyGovernance", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyPendingGovernance", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "_pendingGovernance", - "type": "address" - } - ], - "name": "GovernanceProposal", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "_governance", - "type": "address" - } - ], - "name": "GovernanceSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "_keep3rV2", - "type": "address" - } - ], - "name": "Keep3rV2Change", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "_address", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "_isKP3RToken0", - "type": "bool" - } - ], - "name": "Kp3rWethPoolChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "_maxBoost", - "type": "uint256" - } - ], - "name": "MaxBoostChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "_minBaseFee", - "type": "uint256" - } - ], - "name": "MinBaseFeeChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "_minBoost", - "type": "uint256" - } - ], - "name": "MinBoostChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "_minPriorityFee", - "type": "uint256" - } - ], - "name": "MinPriorityFeeChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "_liquidity", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "_oraclePool", - "type": "address" - } - ], - "name": "OracleSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint32", - "name": "_quoteTwapTime", - "type": "uint32" - } - ], - "name": "QuoteTwapTimeChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "_targetBond", - "type": "uint256" - } - ], - "name": "TargetBondChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "_address", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "_isWETHToken0", - "type": "bool" - } - ], - "name": "WethUSDPoolChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "_workExtraGas", - "type": "uint256" - } - ], - "name": "WorkExtraGasChange", - "type": "event" - }, - { - "inputs": [], - "name": "BOOST_BASE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "KP3R", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "WETH", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "acceptGovernance", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_keeper", - "type": "address" - } - ], - "name": "bonds", - "outputs": [ - { - "internalType": "uint256", - "name": "_amountBonded", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_liquidityAmount", - "type": "uint256" - }, - { - "internalType": "int56", - "name": "_tickDifference", - "type": "int56" - }, - { - "internalType": "uint256", - "name": "_timeInterval", - "type": "uint256" - } - ], - "name": "getKP3RsAtTick", - "outputs": [ - { - "internalType": "uint256", - "name": "_kp3rAmount", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_bonds", - "type": "uint256" - } - ], - "name": "getPaymentParams", - "outputs": [ - { - "internalType": "uint256", - "name": "_boost", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_oneEthQuote", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_extra", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_pool", - "type": "address" - } - ], - "name": "getPoolTokens", - "outputs": [ - { - "internalType": "address", - "name": "_token0", - "type": "address" - }, - { - "internalType": "address", - "name": "_token1", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "_baseAmount", - "type": "uint128" - }, - { - "internalType": "int56", - "name": "_tickDifference", - "type": "int56" - }, - { - "internalType": "uint256", - "name": "_timeInterval", - "type": "uint256" - } - ], - "name": "getQuoteAtTick", - "outputs": [ - { - "internalType": "uint256", - "name": "_quoteAmount", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_gasUsed", - "type": "uint256" - } - ], - "name": "getRewardAmount", - "outputs": [ - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_keeper", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_gasUsed", - "type": "uint256" - } - ], - "name": "getRewardAmountFor", - "outputs": [ - { - "internalType": "uint256", - "name": "_kp3r", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_bonds", - "type": "uint256" - } - ], - "name": "getRewardBoostFor", - "outputs": [ - { - "internalType": "uint256", - "name": "_rewardBoost", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "governance", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "isKP3RToken0", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "keep3rV2", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "kp3rWethPool", - "outputs": [ - { - "internalType": "address", - "name": "poolAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "isTKNToken0", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxBoost", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minBaseFee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minBoost", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minPriorityFee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_pool", - "type": "address" - }, - { - "internalType": "uint32[]", - "name": "_secondsAgo", - "type": "uint32[]" - } - ], - "name": "observe", - "outputs": [ - { - "internalType": "int56", - "name": "_tickCumulative1", - "type": "int56" - }, - { - "internalType": "int56", - "name": "_tickCumulative2", - "type": "int56" - }, - { - "internalType": "bool", - "name": "_success", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "oracle", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingGovernance", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_eth", - "type": "uint256" - } - ], - "name": "quote", - "outputs": [ - { - "internalType": "uint256", - "name": "_amountOut", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "quoteTwapTime", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_usd", - "type": "uint256" - } - ], - "name": "quoteUsdToEth", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_governance", - "type": "address" - } - ], - "name": "setGovernance", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_keep3rV2", - "type": "address" - } - ], - "name": "setKeep3rV2", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_poolAddress", - "type": "address" - } - ], - "name": "setKp3rWethPool", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_maxBoost", - "type": "uint256" - } - ], - "name": "setMaxBoost", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_minBaseFee", - "type": "uint256" - } - ], - "name": "setMinBaseFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_minBoost", - "type": "uint256" - } - ], - "name": "setMinBoost", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_minPriorityFee", - "type": "uint256" - } - ], - "name": "setMinPriorityFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_liquidity", - "type": "address" - }, - { - "internalType": "address", - "name": "_oracle", - "type": "address" - } - ], - "name": "setOracle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "_quoteTwapTime", - "type": "uint32" - } - ], - "name": "setQuoteTwapTime", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_targetBond", - "type": "uint256" - } - ], - "name": "setTargetBond", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_poolAddress", - "type": "address" - } - ], - "name": "setWethUsdPool", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_workExtraGas", - "type": "uint256" - } - ], - "name": "setWorkExtraGas", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "targetBond", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "wethUSDPool", - "outputs": [ - { - "internalType": "address", - "name": "poolAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "isTKNToken0", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "workExtraGas", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x2df158d44e0fb04416fbbf29cce8dc6e89260f78de6575177602b5466a049a60", - "receipt": { - "to": null, - "from": "0x258b180E741157763236F5277619D71ECf00B906", - "contractAddress": "0x4C4cCAf09004838851c8AC5B3fc822A09c9f3Ec2", - "transactionIndex": 0, - "gasUsed": "1986814", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000040000002000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000008000000000000000000", - "blockHash": "0x40017da9aa2494cf90dae646d4c46877d79c658a0d9db405ac9791888a185821", - "transactionHash": "0x2df158d44e0fb04416fbbf29cce8dc6e89260f78de6575177602b5466a049a60", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 3074388, - "transactionHash": "0x2df158d44e0fb04416fbbf29cce8dc6e89260f78de6575177602b5466a049a60", - "address": "0x4C4cCAf09004838851c8AC5B3fc822A09c9f3Ec2", - "topics": [ - "0x554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf4108" - ], - "data": "0x0000000000000000000000004ecff2c532d47d7be3d957e4a332ab134cad1fd90000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 0, - "blockHash": "0x40017da9aa2494cf90dae646d4c46877d79c658a0d9db405ac9791888a185821" - }, - { - "transactionIndex": 0, - "blockNumber": 3074388, - "transactionHash": "0x2df158d44e0fb04416fbbf29cce8dc6e89260f78de6575177602b5466a049a60", - "address": "0x4C4cCAf09004838851c8AC5B3fc822A09c9f3Ec2", - "topics": [ - "0xc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000015180", - "logIndex": 1, - "blockHash": "0x40017da9aa2494cf90dae646d4c46877d79c658a0d9db405ac9791888a185821" - } - ], - "blockNumber": 3074388, - "cumulativeGasUsed": "1986814", - "status": 1, - "byzantium": true - }, - "args": [ - "0x3C9636ab56aced6C845d6D13805901A0a0B13b51", - "0x258b180E741157763236F5277619D71ECf00B906", - "0x68Db1c8d85C09d546097C65ec7DCBFF4D6497CbF", - "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", - "0x4ECFF2c532d47D7be3D957E4a332AB134cad1fd9", - "0x4ECFF2c532d47D7be3D957E4a332AB134cad1fd9" - ], - "numDeployments": 3, - "solcInputHash": "85c2893002b147e91499124ad14b40ea", - "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kp3r\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kp3rWethOracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_wethUsdOracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidOraclePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"Keep3rV2Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isKP3RToken0\",\"type\":\"bool\"}],\"name\":\"Kp3rWethPoolChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"MaxBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"MinBaseFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"MinBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"MinPriorityFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_oraclePool\",\"type\":\"address\"}],\"name\":\"OracleSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"QuoteTwapTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"TargetBondChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isWETHToken0\",\"type\":\"bool\"}],\"name\":\"WethUSDPoolChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"WorkExtraGasChange\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BOOST_BASE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"KP3R\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WETH\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountBonded\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityAmount\",\"type\":\"uint256\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getKP3RsAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3rAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getPaymentParams\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_boost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_oneEthQuote\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_extra\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"}],\"name\":\"getPoolTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token1\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_baseAmount\",\"type\":\"uint128\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getQuoteAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_quoteAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmountFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3r\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getRewardBoostFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardBoost\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isKP3RToken0\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV2\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"kp3rWethPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isTKNToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBaseFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minPriorityFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"},{\"internalType\":\"uint32[]\",\"name\":\"_secondsAgo\",\"type\":\"uint32[]\"}],\"name\":\"observe\",\"outputs\":[{\"internalType\":\"int56\",\"name\":\"_tickCumulative1\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"_tickCumulative2\",\"type\":\"int56\"},{\"internalType\":\"bool\",\"name\":\"_success\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eth\",\"type\":\"uint256\"}],\"name\":\"quote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"quoteTwapTime\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_usd\",\"type\":\"uint256\"}],\"name\":\"quoteUsdToEth\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"setKeep3rV2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddress\",\"type\":\"address\"}],\"name\":\"setKp3rWethPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"setMaxBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"setMinBaseFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"setMinBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"setMinPriorityFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"}],\"name\":\"setOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"setQuoteTwapTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"setTargetBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddress\",\"type\":\"address\"}],\"name\":\"setWethUsdPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"setWorkExtraGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetBond\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wethUSDPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isTKNToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"workExtraGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bonds(address)\":{\"params\":{\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_amountBonded\":\"The amount of KP3R the keeper has bonded\"}},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"params\":{\"_liquidityAmount\":\"Amount of liquidity to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_kp3rAmount\":\"Amount of KP3R tokens underlying on the given liquidity\"}},\"getPaymentParams(uint256)\":{\"params\":{\"_bonds\":\"Amount of bonded KP3R owned by the keeper\"},\"returns\":{\"_boost\":\"Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\",\"_extra\":\"Amount of extra gas that should be added to the gas spent\",\"_oneEthQuote\":\"Amount of KP3R tokens equivalent to 1 ETH\"}},\"getPoolTokens(address)\":{\"params\":{\"_pool\":\"Address of the correspondant pool\"},\"returns\":{\"_token0\":\"Address of the first token of the pair\",\"_token1\":\"Address of the second token of the pair\"}},\"getQuoteAtTick(uint128,int56,uint256)\":{\"params\":{\"_baseAmount\":\"Amount of token to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_quoteAmount\":\"Amount of credits deserved for the baseAmount at the tick value\"}},\"getRewardAmount(uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\"},\"returns\":{\"_amount\":\"The amount of KP3R that should be awarded to tx.origin\"}},\"getRewardAmountFor(address,uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\",\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_kp3r\":\"The amount of KP3R that should be awarded to the keeper\"}},\"getRewardBoostFor(uint256)\":{\"details\":\"If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\",\"params\":{\"_bonds\":\"The amount of KP3R tokens bonded by the keeper\"},\"returns\":{\"_rewardBoost\":\"The reward boost that corresponds to the keeper\"}},\"isKP3RToken0(address)\":{\"details\":\"Overrides token comparison with KP3R address\"},\"observe(address,uint32[])\":{\"params\":{\"_pool\":\"Address of the pool to observe\",\"_secondsAgo\":\"Array with time references to observe\"},\"returns\":{\"_success\":\"Boolean indicating if the observe call was succesfull\",\"_tickCumulative1\":\"Cumulative sum of ticks until first time reference\",\"_tickCumulative2\":\"Cumulative sum of ticks until second time reference\"}},\"quote(uint256)\":{\"details\":\"This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\",\"params\":{\"_eth\":\"The amount of ETH\"},\"returns\":{\"_amountOut\":\"The amount of KP3R\"}},\"quoteUsdToEth(uint256)\":{\"details\":\"Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\",\"params\":{\"_usd\":\"The amount of USD to quote to ETH\"},\"returns\":{\"_0\":\"The resulting amount of ETH after quoting the USD\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setKeep3rV2(address)\":{\"params\":{\"_keep3rV2\":\"The address of Keep3r V2\"}},\"setKp3rWethPool(address)\":{\"params\":{\"_poolAddress\":\"The address of the KP3R-WETH pool\"}},\"setMaxBoost(uint256)\":{\"params\":{\"_maxBoost\":\"The maximum boost multiplier\"}},\"setMinBaseFee(uint256)\":{\"params\":{\"_minBaseFee\":\"The minimum rewarded gas fee\"}},\"setMinBoost(uint256)\":{\"params\":{\"_minBoost\":\"The minimum boost multiplier\"}},\"setMinPriorityFee(uint256)\":{\"params\":{\"_minPriorityFee\":\"The minimum rewarded priority fee\"}},\"setOracle(address,address)\":{\"details\":\"The oracle must contain KP3R as either token0 or token1\",\"params\":{\"_liquidity\":\"The address of the liquidity\",\"_oracle\":\"The address of the pool used to quote the liquidity from\"}},\"setQuoteTwapTime(uint32)\":{\"params\":{\"_quoteTwapTime\":\"The twap time for quoting\"}},\"setTargetBond(uint256)\":{\"params\":{\"_targetBond\":\"The target bond amount\"}},\"setWethUsdPool(address)\":{\"details\":\"The oracle must contain WETH as either token0 or token1\",\"params\":{\"_poolAddress\":\"The address of the pool used as oracle\"}},\"setWorkExtraGas(uint256)\":{\"params\":{\"_workExtraGas\":\"The work extra gas\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidOraclePool()\":[{\"notice\":\"Throws when pool does not have KP3R as token0 nor token1\"}],\"LiquidityPairInvalid()\":[{\"notice\":\"Throws when none of the tokens in the liquidity pair is KP3R\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"Keep3rV2Change(address)\":{\"notice\":\"Emitted when the Keep3r V2 address is changed\"},\"Kp3rWethPoolChange(address,bool)\":{\"notice\":\"Emitted when the kp3r weth pool is changed\"},\"MaxBoostChange(uint256)\":{\"notice\":\"Emitted when the maximum boost multiplier is changed\"},\"MinBaseFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded gas fee is changed\"},\"MinBoostChange(uint256)\":{\"notice\":\"Emitted when the minimum boost multiplier is changed\"},\"MinPriorityFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded priority fee is changed\"},\"OracleSet(address,address)\":{\"notice\":\"The oracle for a liquidity has been saved\"},\"QuoteTwapTimeChange(uint32)\":{\"notice\":\"Emitted when the quote twap time is changed\"},\"TargetBondChange(uint256)\":{\"notice\":\"Emitted when the target bond amount is changed\"},\"WethUSDPoolChange(address,bool)\":{\"notice\":\"Emitted when the WETH USD pool is changed\"},\"WorkExtraGasChange(uint256)\":{\"notice\":\"Emitted when the work extra gas amount is changed\"}},\"kind\":\"user\",\"methods\":{\"BOOST_BASE()\":{\"notice\":\"The boost base used to calculate the boost rewards for the keeper\"},\"KP3R()\":{\"notice\":\"Address of KP3R token\"},\"WETH()\":{\"notice\":\"Ethereum mainnet WETH address used for quoting references\"},\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"bonds(address)\":{\"notice\":\"Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\"},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"notice\":\"Given a tick and a liquidity amount, calculates the underlying KP3R tokens\"},\"getPaymentParams(uint256)\":{\"notice\":\"Get multiplier, quote, and extra, in order to calculate keeper payment\"},\"getPoolTokens(address)\":{\"notice\":\"Given a pool address, returns the underlying tokens of the pair\"},\"getQuoteAtTick(uint128,int56,uint256)\":{\"notice\":\"Given a tick and a token amount, calculates the output in correspondant token\"},\"getRewardAmount(uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\"},\"getRewardAmountFor(address,uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to a keeper for using gas\"},\"getRewardBoostFor(uint256)\":{\"notice\":\"Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"keep3rV2()\":{\"notice\":\"Address of Keep3r V2\"},\"kp3rWethPool()\":{\"notice\":\"KP3R-WETH pool that is being used as oracle\"},\"maxBoost()\":{\"notice\":\"The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\"},\"minBaseFee()\":{\"notice\":\"The minimum base fee that is used to calculate keeper rewards\"},\"minBoost()\":{\"notice\":\"The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\"},\"minPriorityFee()\":{\"notice\":\"The minimum priority fee that is also rewarded for keepers\"},\"observe(address,uint32[])\":{\"notice\":\"Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"quote(uint256)\":{\"notice\":\"Calculates the amount of KP3R that corresponds to the ETH passed into the function\"},\"quoteTwapTime()\":{\"notice\":\"The twap time for quoting\"},\"quoteUsdToEth(uint256)\":{\"notice\":\"Quotes USD to ETH\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setKeep3rV2(address)\":{\"notice\":\"Sets the Keep3r V2 address\"},\"setKp3rWethPool(address)\":{\"notice\":\"Sets KP3R-WETH pool\"},\"setMaxBoost(uint256)\":{\"notice\":\"Sets the maximum boost multiplier\"},\"setMinBaseFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas fee\"},\"setMinBoost(uint256)\":{\"notice\":\"Sets the minimum boost multiplier\"},\"setMinPriorityFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas priority fee\"},\"setOracle(address,address)\":{\"notice\":\"Sets an oracle for a given liquidity\"},\"setQuoteTwapTime(uint32)\":{\"notice\":\"Sets the quote twap time\"},\"setTargetBond(uint256)\":{\"notice\":\"Sets the target bond amount\"},\"setWethUsdPool(address)\":{\"notice\":\"Sets an oracle for querying WETH/USD quote\"},\"setWorkExtraGas(uint256)\":{\"notice\":\"Sets the work extra gas amount\"},\"targetBond()\":{\"notice\":\"The targeted amount of bonded KP3Rs to max-up reward multiplier For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\"},\"wethUSDPool()\":{\"notice\":\"WETH-USD pool that is being used as oracle\"},\"workExtraGas()\":{\"notice\":\"The amount of unaccounted gas that is going to be added to keeper payments\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol\":\"Keep3rHelperSidechainForTestnet\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\nimport './pool/IUniswapV3PoolImmutables.sol';\\nimport './pool/IUniswapV3PoolState.sol';\\nimport './pool/IUniswapV3PoolDerivedState.sol';\\nimport './pool/IUniswapV3PoolActions.sol';\\nimport './pool/IUniswapV3PoolOwnerActions.sol';\\nimport './pool/IUniswapV3PoolEvents.sol';\\n\\n/// @title The interface for a Uniswap V3 Pool\\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\\n/// to the ERC20 specification\\n/// @dev The pool interface is broken up into many smaller pieces\\ninterface IUniswapV3Pool is\\n IUniswapV3PoolImmutables,\\n IUniswapV3PoolState,\\n IUniswapV3PoolDerivedState,\\n IUniswapV3PoolActions,\\n IUniswapV3PoolOwnerActions,\\n IUniswapV3PoolEvents\\n{\\n\\n}\\n\",\"keccak256\":\"0xfe6113d518466cd6652c85b111e01f33eb62157f49ae5ed7d5a3947a2044adb1\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissionless pool actions\\n/// @notice Contains pool methods that can be called by anyone\\ninterface IUniswapV3PoolActions {\\n /// @notice Sets the initial price for the pool\\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\\n function initialize(uint160 sqrtPriceX96) external;\\n\\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\\n /// @param recipient The address for which the liquidity will be created\\n /// @param tickLower The lower tick of the position in which to add liquidity\\n /// @param tickUpper The upper tick of the position in which to add liquidity\\n /// @param amount The amount of liquidity to mint\\n /// @param data Any data that should be passed through to the callback\\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n function mint(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount,\\n bytes calldata data\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Collects tokens owed to a position\\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\\n /// @param recipient The address which should receive the fees collected\\n /// @param tickLower The lower tick of the position for which to collect fees\\n /// @param tickUpper The upper tick of the position for which to collect fees\\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\\n /// @return amount0 The amount of fees collected in token0\\n /// @return amount1 The amount of fees collected in token1\\n function collect(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n\\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\\n /// @dev Fees must be collected separately via a call to #collect\\n /// @param tickLower The lower tick of the position for which to burn liquidity\\n /// @param tickUpper The upper tick of the position for which to burn liquidity\\n /// @param amount How much liquidity to burn\\n /// @return amount0 The amount of token0 sent to the recipient\\n /// @return amount1 The amount of token1 sent to the recipient\\n function burn(\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Swap token0 for token1, or token1 for token0\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\\n /// @param recipient The address to receive the output of the swap\\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\\n /// @param data Any data to be passed through to the callback\\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\\n /// @param recipient The address which will receive the token0 and token1 amounts\\n /// @param amount0 The amount of token0 to send\\n /// @param amount1 The amount of token1 to send\\n /// @param data Any data to be passed through to the callback\\n function flash(\\n address recipient,\\n uint256 amount0,\\n uint256 amount1,\\n bytes calldata data\\n ) external;\\n\\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\\n /// the input observationCardinalityNext.\\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0x9453dd0e7442188667d01d9b65de3f1e14e9511ff3e303179a15f6fc267f7634\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that is not stored\\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\\n/// blockchain. The functions here may have variable gas costs.\\ninterface IUniswapV3PoolDerivedState {\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\\n /// you must call it with secondsAgos = [3600, 0].\\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\\n /// timestamp\\n function observe(uint32[] calldata secondsAgos)\\n external\\n view\\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\\n\\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\\n /// snapshot is taken and the second snapshot is taken.\\n /// @param tickLower The lower tick of the range\\n /// @param tickUpper The upper tick of the range\\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\\n /// @return secondsInside The snapshot of seconds per liquidity for the range\\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\\n external\\n view\\n returns (\\n int56 tickCumulativeInside,\\n uint160 secondsPerLiquidityInsideX128,\\n uint32 secondsInside\\n );\\n}\\n\",\"keccak256\":\"0xe603ac5b17ecdee73ba2b27efdf386c257a19c14206e87eee77e2017b742d9e5\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Events emitted by a pool\\n/// @notice Contains all events emitted by the pool\\ninterface IUniswapV3PoolEvents {\\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\\n event Initialize(uint160 sqrtPriceX96, int24 tick);\\n\\n /// @notice Emitted when liquidity is minted for a given position\\n /// @param sender The address that minted the liquidity\\n /// @param owner The owner of the position and recipient of any minted liquidity\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity minted to the position range\\n /// @param amount0 How much token0 was required for the minted liquidity\\n /// @param amount1 How much token1 was required for the minted liquidity\\n event Mint(\\n address sender,\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted when fees are collected by the owner of a position\\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\\n /// @param owner The owner of the position for which fees are collected\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount0 The amount of token0 fees collected\\n /// @param amount1 The amount of token1 fees collected\\n event Collect(\\n address indexed owner,\\n address recipient,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount0,\\n uint128 amount1\\n );\\n\\n /// @notice Emitted when a position's liquidity is removed\\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\\n /// @param owner The owner of the position for which liquidity is removed\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity to remove\\n /// @param amount0 The amount of token0 withdrawn\\n /// @param amount1 The amount of token1 withdrawn\\n event Burn(\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted by the pool for any swaps between token0 and token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the output of the swap\\n /// @param amount0 The delta of the token0 balance of the pool\\n /// @param amount1 The delta of the token1 balance of the pool\\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param liquidity The liquidity of the pool after the swap\\n /// @param tick The log base 1.0001 of price of the pool after the swap\\n event Swap(\\n address indexed sender,\\n address indexed recipient,\\n int256 amount0,\\n int256 amount1,\\n uint160 sqrtPriceX96,\\n uint128 liquidity,\\n int24 tick\\n );\\n\\n /// @notice Emitted by the pool for any flashes of token0/token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the tokens from flash\\n /// @param amount0 The amount of token0 that was flashed\\n /// @param amount1 The amount of token1 that was flashed\\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\\n event Flash(\\n address indexed sender,\\n address indexed recipient,\\n uint256 amount0,\\n uint256 amount1,\\n uint256 paid0,\\n uint256 paid1\\n );\\n\\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\\n /// just before a mint/swap/burn.\\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(\\n uint16 observationCardinalityNextOld,\\n uint16 observationCardinalityNextNew\\n );\\n\\n /// @notice Emitted when the protocol fee is changed by the pool\\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\\n /// @param feeProtocol0New The updated value of the token0 protocol fee\\n /// @param feeProtocol1New The updated value of the token1 protocol fee\\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\\n\\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\\n /// @param sender The address that collects the protocol fees\\n /// @param recipient The address that receives the collected protocol fees\\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x8071514d0fe5d17d6fbd31c191cdfb703031c24e0ece3621d88ab10e871375cd\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that never changes\\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\\ninterface IUniswapV3PoolImmutables {\\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\\n /// @return The contract address\\n function factory() external view returns (address);\\n\\n /// @notice The first of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token0() external view returns (address);\\n\\n /// @notice The second of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token1() external view returns (address);\\n\\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\\n /// @return The fee\\n function fee() external view returns (uint24);\\n\\n /// @notice The pool tick spacing\\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\\n /// This value is an int24 to avoid casting even though it is always positive.\\n /// @return The tick spacing\\n function tickSpacing() external view returns (int24);\\n\\n /// @notice The maximum amount of position liquidity that can use any tick in the range\\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\\n /// @return The max amount of liquidity per tick\\n function maxLiquidityPerTick() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xf6e5d2cd1139c4c276bdbc8e1d2b256e456c866a91f1b868da265c6d2685c3f7\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissioned pool actions\\n/// @notice Contains pool methods that may only be called by the factory owner\\ninterface IUniswapV3PoolOwnerActions {\\n /// @notice Set the denominator of the protocol's % share of the fees\\n /// @param feeProtocol0 new protocol fee for token0 of the pool\\n /// @param feeProtocol1 new protocol fee for token1 of the pool\\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\\n\\n /// @notice Collect the protocol fee accrued to the pool\\n /// @param recipient The address to which collected protocol fees should be sent\\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\\n /// @return amount0 The protocol fee collected in token0\\n /// @return amount1 The protocol fee collected in token1\\n function collectProtocol(\\n address recipient,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x759b78a2918af9e99e246dc3af084f654e48ef32bb4e4cb8a966aa3dcaece235\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that can change\\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\\n/// per transaction\\ninterface IUniswapV3PoolState {\\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\\n /// when accessed externally.\\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\\n /// boundary.\\n /// observationIndex The index of the last oracle observation that was written,\\n /// observationCardinality The current maximum number of observations stored in the pool,\\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// feeProtocol The protocol fee for both tokens of the pool.\\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\\n /// unlocked Whether the pool is currently locked to reentrancy\\n function slot0()\\n external\\n view\\n returns (\\n uint160 sqrtPriceX96,\\n int24 tick,\\n uint16 observationIndex,\\n uint16 observationCardinality,\\n uint16 observationCardinalityNext,\\n uint8 feeProtocol,\\n bool unlocked\\n );\\n\\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal0X128() external view returns (uint256);\\n\\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal1X128() external view returns (uint256);\\n\\n /// @notice The amounts of token0 and token1 that are owed to the protocol\\n /// @dev Protocol fees will never exceed uint128 max in either token\\n function protocolFees() external view returns (uint128 token0, uint128 token1);\\n\\n /// @notice The currently in range liquidity available to the pool\\n /// @dev This value has no relationship to the total liquidity across all ticks\\n function liquidity() external view returns (uint128);\\n\\n /// @notice Look up information about a specific tick in the pool\\n /// @param tick The tick to look up\\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\\n /// tick upper,\\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\\n /// a specific position.\\n function ticks(int24 tick)\\n external\\n view\\n returns (\\n uint128 liquidityGross,\\n int128 liquidityNet,\\n uint256 feeGrowthOutside0X128,\\n uint256 feeGrowthOutside1X128,\\n int56 tickCumulativeOutside,\\n uint160 secondsPerLiquidityOutsideX128,\\n uint32 secondsOutside,\\n bool initialized\\n );\\n\\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\\n function tickBitmap(int16 wordPosition) external view returns (uint256);\\n\\n /// @notice Returns the information about a position by the position's key\\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\\n /// @return _liquidity The amount of liquidity in the position,\\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\\n function positions(bytes32 key)\\n external\\n view\\n returns (\\n uint128 _liquidity,\\n uint256 feeGrowthInside0LastX128,\\n uint256 feeGrowthInside1LastX128,\\n uint128 tokensOwed0,\\n uint128 tokensOwed1\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param index The element of the observations array to fetch\\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\\n /// ago, rather than at a specific index in the array.\\n /// @return blockTimestamp The timestamp of the observation,\\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// Returns initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 index)\\n external\\n view\\n returns (\\n uint32 blockTimestamp,\\n int56 tickCumulative,\\n uint160 secondsPerLiquidityCumulativeX128,\\n bool initialized\\n );\\n}\\n\",\"keccak256\":\"0x852dc1f5df7dcf7f11e7bb3eed79f0cea72ad4b25f6a9d2c35aafb48925fd49f\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/Keep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2003\\u2003\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2003\\u2003\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/IKeep3rHelper.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\\n\\n /// @inheritdoc IKeep3rHelper\\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\\n uint32[] memory _secondsAgos = new uint32[](2);\\n _secondsAgos[1] = quoteTwapTime;\\n\\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\\n // solhint-disable-next-line avoid-tx-origin\\n return getRewardAmountFor(tx.origin, _gasUsed);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\\n _bonds = Math.min(_bonds, targetBond);\\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\\n _rewardBoost = _cap * _getBasefee();\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\\n address _token0;\\n address _token1;\\n (_token0, _token1) = getPoolTokens(_pool);\\n if (_token0 == KP3R) {\\n return true;\\n } else if (_token1 != KP3R) {\\n revert LiquidityPairInvalid();\\n }\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n override\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n )\\n {\\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\\n _tickCumulative1 = _uniswapResponse[0];\\n if (_uniswapResponse.length > 1) {\\n _tickCumulative2 = _uniswapResponse[1];\\n }\\n _success = true;\\n } catch (bytes memory) {}\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n override\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n )\\n {\\n _oneEthQuote = quote(1 ether);\\n _boost = getRewardBoostFor(_bonds);\\n _extra = workExtraGas;\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure override returns (uint256 _kp3rAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) public pure override returns (uint256 _quoteAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n\\n if (sqrtRatioX96 <= type(uint128).max) {\\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\\n } else {\\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\\n }\\n }\\n\\n /// @notice Gets the gas basefee cost to calculate keeper rewards\\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\\n }\\n}\\n\",\"keccak256\":\"0x88844b43c69ff137c86106096e251dea858bc45ddb198ea08c97735dc6bf4951\",\"license\":\"MIT\"},\"solidity/contracts/Keep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/peripherals/IBaseErrors.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/external/IKeep3rV1.sol';\\nimport '../interfaces/IKeep3rHelperParameters.sol';\\nimport './peripherals/Governable.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\\n /// @inheritdoc IKeep3rHelperParameters\\n address public immutable override KP3R;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public constant override BOOST_BASE = 10_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBoost = 11_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override maxBoost = 12_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override targetBond = 200 ether;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override workExtraGas = 30_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint32 public override quoteTwapTime = 10 minutes;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBaseFee = 15e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minPriorityFee = 2e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n address public override keep3rV2;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\\n\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governance,\\n address _kp3rWethPool\\n ) Governable(_governance) {\\n KP3R = _kp3r;\\n keep3rV2 = _keep3rV2;\\n\\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\\n if (_poolAddress == address(0)) revert ZeroAddress();\\n _setKp3rWethPool(_poolAddress);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\\n minBoost = _minBoost;\\n emit MinBoostChange(minBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\\n maxBoost = _maxBoost;\\n emit MaxBoostChange(maxBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\\n targetBond = _targetBond;\\n emit TargetBondChange(targetBond);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\\n if (_keep3rV2 == address(0)) revert ZeroAddress();\\n keep3rV2 = _keep3rV2;\\n emit Keep3rV2Change(keep3rV2);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\\n workExtraGas = _workExtraGas;\\n emit WorkExtraGasChange(workExtraGas);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\\n _setQuoteTwapTime(_quoteTwapTime);\\n }\\n\\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\\n quoteTwapTime = _quoteTwapTime;\\n emit QuoteTwapTimeChange(quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\\n minBaseFee = _minBaseFee;\\n emit MinBaseFeeChange(minBaseFee);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\\n minPriorityFee = _minPriorityFee;\\n emit MinPriorityFeeChange(minPriorityFee);\\n }\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function _setKp3rWethPool(address _poolAddress) internal {\\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\\n }\\n\\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\\n\\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\\n\\n return TokenOraclePool(_poolAddress, _isTKNToken0);\\n }\\n}\\n\",\"keccak256\":\"0xd16cb900c60b28a7eda5467b43c9d47ca9d48b1d7aab967bf1083c1449d39113\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n// solhint-disable\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\\n\\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n // Second inequality must be < because the price can never reach the price at the max tick\\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n}\\n\",\"keccak256\":\"0x11b965ba576ff91b4a6e9533c0f334f2b7b6024ee1c54e36d21799de5580899d\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/contracts/sidechain/Keep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3rHelper.sol';\\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\\n\\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\\n /// @inheritdoc IKeep3rHelperSidechain\\n mapping(address => address) public override oracle;\\n /// @inheritdoc IKeep3rHelperSidechain\\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n address public immutable override WETH;\\n\\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\\n /// @param _governance Address of governance\\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\\n /// @dev Oracle pools should use 18 decimals tokens\\n constructor(\\n address _keep3rV2,\\n address _governance,\\n address _kp3r,\\n address _weth,\\n address _kp3rWethOracle,\\n address _wethUsdOracle\\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\\n WETH = _weth;\\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\\n _setQuoteTwapTime(1 days);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\\n oracle[_liquidity] = _oracle;\\n emit OracleSet(_liquidity, _oracle);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\\n uint32[] memory _secondsAgos = new uint32[](2);\\n _secondsAgos[1] = quoteTwapTime;\\n\\n /// @dev Oracle is compatible with IUniswapV3Pool\\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\\n if (_poolAddress == address(0)) revert ZeroAddress();\\n _setWethUsdPool(_poolAddress);\\n }\\n\\n function _setWethUsdPool(address _poolAddress) internal {\\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\\n }\\n\\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\\n return 1;\\n }\\n}\\n\",\"keccak256\":\"0x2ceaf6057a5d287debb43c7583a1d9f9ac0986c78ea107caa10da303b7ec7d3d\",\"license\":\"MIT\"},\"solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../contracts/sidechain/Keep3rHelperSidechain.sol';\\n\\ncontract Keep3rHelperSidechainForTestnet is Keep3rHelperSidechain {\\n constructor(\\n address _keep3rV2,\\n address _governance,\\n address _kp3r,\\n address _weth,\\n address _kp3rWethOracle,\\n address _wethUsdOracle\\n ) Keep3rHelperSidechain(_keep3rV2, _governance, _kp3r, _weth, _kp3rWethOracle, _wethUsdOracle) {}\\n\\n /// @dev Overrides oracle validation that uses KP3R and WETH addresses\\n function _validateOraclePool(address _poolAddress, address) internal view virtual override returns (TokenOraclePool memory _oraclePool) {\\n return TokenOraclePool(_poolAddress, true);\\n }\\n\\n /// @dev Overrides token comparison with KP3R address\\n function isKP3RToken0(address) public view virtual override returns (bool) {\\n return true;\\n }\\n\\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256) {\\n return _usd / 1000;\\n }\\n}\\n\",\"keccak256\":\"0xea4a299ce9358cd7201acebd372fdcdfc38953ee8ba02dc69c78344296d0debe\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct TokenOraclePool {\\n address poolAddress;\\n bool isTKNToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0x76f99ca04361c0459fc9e99f0387ddb76da18cc470ec5bc744e7dc3bf6e9d334\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0x060f701c6991d323bcf360738568714956013b17b3e3443ea21d825a70c3947c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../IKeep3rHelper.sol';\\n\\n/// @title Keep3rHelperSidechain contract\\n/// @notice Contains all the helper functions for sidechain keep3r implementations\\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\\n // Events\\n\\n /// @notice The oracle for a liquidity has been saved\\n /// @param _liquidity The address of the given liquidity\\n /// @param _oraclePool The address of the oracle pool\\n event OracleSet(address _liquidity, address _oraclePool);\\n\\n /// @notice Emitted when the WETH USD pool is changed\\n /// @param _address Address of the new WETH USD pool\\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\\n\\n /// Variables\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n /// @return _weth Address of WETH token\\n // solhint-disable func-name-mixedcase\\n function WETH() external view returns (address _weth);\\n\\n /// @return _oracle The address of the observable pool for given liquidity\\n function oracle(address _liquidity) external view returns (address _oracle);\\n\\n /// @notice WETH-USD pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice Quotes USD to ETH\\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\\n /// @param _usd The amount of USD to quote to ETH\\n /// @return _eth The resulting amount of ETH after quoting the USD\\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\\n\\n /// Methods\\n\\n /// @notice Sets an oracle for a given liquidity\\n /// @param _liquidity The address of the liquidity\\n /// @param _oracle The address of the pool used to quote the liquidity from\\n /// @dev The oracle must contain KP3R as either token0 or token1\\n function setOracle(address _liquidity, address _oracle) external;\\n\\n /// @notice Sets an oracle for querying WETH/USD quote\\n /// @param _poolAddress The address of the pool used as oracle\\n /// @dev The oracle must contain WETH as either token0 or token1\\n function setWethUsdPool(address _poolAddress) external;\\n}\\n\",\"keccak256\":\"0xb6d5459e8a47ab09a052e1acac1c28304f9f0762d20f01819559b4d39729c987\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60c0604052612af8600255612ee0600355680ad78ebc5ac62000006004556175306005556006805463ffffffff191661025817905564037e11d60060075563773594006008553480156200005257600080fd5b506040516200216538038062002165833981016040819052620000759162000264565b8585858585858386868483838383816001600160a01b038116620000ab5760405162b293ed60e81b815260040160405180910390fd5b600080546001600160a01b03199081166001600160a01b03938416178255606087901b6001600160601b0319166080526009805490911686841617905560408051808201825282815260209081019290925280518082018252848416808252600191840191909152600a8054600160a01b6001600160a81b0319909116909217821790819055825194811685520460ff1615159183019190915280517f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf41089281900390910190a15050506001600160601b0319606089901b1660a0525050604080518082018252600080825260209182015281518083019092526001600160a01b03861680835260019290910191909152600c80546001600160a81b031916909117600160a01b17905550620001e79150620151809050620001f9565b505050505050505050505050620002e5565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de9060200160405180910390a150565b80516001600160a01b03811681146200025f57600080fd5b919050565b60008060008060008060c087890312156200027e57600080fd5b620002898762000247565b9550620002996020880162000247565b9450620002a96040880162000247565b9350620002b96060880162000247565b9250620002c96080880162000247565b9150620002d960a0880162000247565b90509295509295509295565b60805160601c60a05160601c611e466200031f6000396000818161047101526117260152600081816101fd01526111760152611e466000f3fe608060405234801561001057600080fd5b50600436106101f35760003560e01c80637b40c913116101165780637b40c913146103c15780638561579c146103e05780638a9b1b09146103e95780639aaad679146103f2578063a0d2710714610417578063a62611a21461042a578063ab033ea914610433578063ab5dce0014610446578063ab8cedc514610459578063ad5c46481461046c578063b2e0df9614610493578063b93f5af0146104a6578063c84993af146104b9578063ca4f2803146104cc578063dc686d91146104ed578063e244208b14610525578063eb37d34914610538578063ed1bd76c14610561578063f39c38a014610574578063fae63d6114610587578063fe10d7741461059a57600080fd5b806305e0b9a0146101f85780630c52583514610235578063117cfc1b1461024a578063160e1e311461025d5780632248e82d14610270578063238efcbc1461029157806325f09e61146102995780632742b9e7146102a25780632750c0f9146102ab578063289adb44146102d857806337090c2f146102eb5780633b67c3bd146102f45780633cc7ab30146103075780633facf2421461031a578063435b21c114610323578063516c3323146103515780635aa6e675146103645780635c38eb3a14610377578063607e48d41461038a578063696a437b1461039d575b600080fd5b61021f7f000000000000000000000000000000000000000000000000000000000000000081565b60405161022c9190611b60565b60405180910390f35b610248610243366004611aec565b6105ad565b005b60095461021f906001600160a01b031681565b61024861026b366004611882565b610614565b61028361027e3660046119a8565b610672565b60405190815260200161022c565b6102486106a5565b61028361271081565b61028360045481565b600c546102ca906001600160a01b03811690600160a01b900460ff1682565b60405161022c929190611b8e565b6102486102e6366004611aec565b610731565b61028360035481565b610283610302366004611aec565b610791565b610248610315366004611882565b6107a5565b61028360055481565b610336610331366004611aec565b610843565b6040805193845260208401929092529082015260600161022c565b61028361035f366004611aec565b610871565b60005461021f906001600160a01b031681565b6102486103853660046118bc565b6108cc565b610248610398366004611aec565b61099f565b6103b16103ab366004611882565b50600190565b604051901515815260200161022c565b600a546102ca906001600160a01b03811690600160a01b900460ff1682565b61028360025481565b61028360085481565b6006546104029063ffffffff1681565b60405163ffffffff909116815260200161022c565b610283610425366004611b1e565b6109ff565b61028360075481565b610248610441366004611882565b610a3b565b610248610454366004611aec565b610ab1565b610283610467366004611a9f565b610b11565b61021f7f000000000000000000000000000000000000000000000000000000000000000081565b6102486104a1366004611aec565b610bb5565b6102486104b4366004611b45565b610c15565b6102836104c7366004611aec565b610c49565b6104df6104da366004611882565b610c55565b60405161022c929190611b74565b6105006104fb3660046118f5565b610d43565b60408051600694850b81529290930b602083015215159181019190915260600161022c565b610248610533366004611aec565b610e4e565b61021f610546366004611882565b600b602052600090815260409020546001600160a01b031681565b61028361056f366004611aec565b610eae565b60015461021f906001600160a01b031681565b610248610595366004611882565b611009565b6102836105a8366004611882565b611064565b6000546001600160a01b031633146105d8576040516354348f0360e01b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b0316331461063f576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166106665760405163d92e233d60e01b815260040160405180910390fd5b61066f81611170565b50565b60008061068161035f85611064565b905061069d6127106106938386611ca0565b61056f9190611c8c565b949350505050565b6001546001600160a01b031633146106d057604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161072791611b60565b60405180910390a1565b6000546001600160a01b0316331461075c576040516354348f0360e01b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b90602001610609565b600061079f6103e883611c8c565b92915050565b6000546001600160a01b031633146107d0576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166107f75760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a9161060991611b60565b6000806000610859670de0b6b3a7640000610eae565b915061086484610871565b6005549095929450925050565b600061087f82600454611206565b91506000600454836002546003546108979190611d0f565b6108a19190611ca0565b6108ab9190611c8c565b6002546108b89190611c46565b90506108c5600182611ca0565b9392505050565b6000546001600160a01b031633146108f7576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038216158061091457506001600160a01b038116155b156109325760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038281166000908152600b60205260409081902080546001600160a01b03191692841692909217909155517fc1d3048301c0d23629a2532c8defa6d68f8e1a0e4157918769e9fb1b2eeb888e906109939084908490611b74565b60405180910390a15050565b6000546001600160a01b031633146109ca576040516354348f0360e01b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b90602001610609565b600080610a18610a1384600687900b611c5e565b61121c565b9050610a32600160601b86836001600160a01b031661162a565b95945050505050565b6000546001600160a01b03163314610a66576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90610609908390611b60565b6000546001600160a01b03163314610adc576040516354348f0360e01b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e90602001610609565b600080610b25610a1384600687900b611c5e565b90506001600160801b036001600160a01b03821611610b75576000610b536001600160a01b03831680611ca0565b9050610b6d600160c01b876001600160801b03168361162a565b925050610bad565b6000610b8f6001600160a01b03831680600160401b61162a565b9050610ba9600160801b876001600160801b03168361162a565b9250505b509392505050565b6000546001600160a01b03163314610be0576040516354348f0360e01b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa90602001610609565b6000546001600160a01b03163314610c40576040516354348f0360e01b815260040160405180910390fd5b61066f816116d8565b600061079f3283610672565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610c9157600080fd5b505afa158015610ca5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc9919061189f565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0257600080fd5b505afa158015610d16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3a919061189f565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b8152600401610d749190611ba9565b60006040518083038186803b158015610d8c57600080fd5b505afa925050508015610dc157506040513d6000823e601f3d908101601f19168201604052610dbe91908101906119d4565b60015b610dfb573d808015610def576040519150601f19603f3d011682016040523d82523d6000602084013e610df4565b606091505b5050610e47565b81600081518110610e0e57610e0e611dc0565b60200260200101519450600182511115610e405781600181518110610e3557610e35611dc0565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b03163314610e79576040516354348f0360e01b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d5415922190602001610609565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff16918391506001908110610ef257610ef2611dc0565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd90610f38908590600401611ba9565b60006040518083038186803b158015610f5057600080fd5b505afa158015610f64573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f8c91908101906119d4565b509050600081600181518110610fa457610fa4611dc0565b602002602001015182600081518110610fbf57610fbf611dc0565b6020026020010151610fd19190611cbf565b600a54909150610a32908690600160a01b900460ff16610ff957610ff483611d7a565b610ffb565b825b60065463ffffffff16610b11565b6000546001600160a01b03163314611034576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661105b5760405163d92e233d60e01b815260040160405180910390fd5b61066f81611720565b600080600960009054906101000a90046001600160a01b03166001600160a01b0316631ef94b916040518163ffffffff1660e01b815260040160206040518083038186803b1580156110b557600080fd5b505afa1580156110c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ed919061189f565b60095460405163a39744b560e01b81529192506001600160a01b03169063a39744b5906111209086908590600401611b74565b60206040518083038186803b15801561113857600080fd5b505afa15801561114c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c59190611b05565b61119a817f00000000000000000000000000000000000000000000000000000000000000006117b6565b8051600a80546020909301511515600160a01b9081026001600160a81b03199094166001600160a01b039384161793909317908190556040517f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf410893610609938316920460ff1690611b8e565b600081831061121557816108c5565b5090919050565b60008060008360020b12611233578260020b611240565b8260020b61124090611d5d565b905061124f620d89e719611d3a565b60020b8111156112895760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b60006001821661129d57600160801b6112af565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b0316905060028216156112e45760806112df826ffff97272373d413259a46990580e213a611ca0565b901c90505b600482161561130e576080611309826ffff2e50f5f656932ef12357cf3c7fdcc611ca0565b901c90505b6008821615611338576080611333826fffe5caca7e10e4e61c3624eaa0941cd0611ca0565b901c90505b601082161561136257608061135d826fffcb9843d60f6159c9db58835c926644611ca0565b901c90505b602082161561138c576080611387826fff973b41fa98c081472e6896dfb254c0611ca0565b901c90505b60408216156113b65760806113b1826fff2ea16466c96a3843ec78b326b52861611ca0565b901c90505b60808216156113e05760806113db826ffe5dee046a99a2a811c461f1969c3053611ca0565b901c90505b61010082161561140b576080611406826ffcbe86c7900a88aedcffc83b479aa3a4611ca0565b901c90505b610200821615611436576080611431826ff987a7253ac413176f2b074cf7815e54611ca0565b901c90505b61040082161561146157608061145c826ff3392b0822b70005940c7a398e4b70f3611ca0565b901c90505b61080082161561148c576080611487826fe7159475a2c29b7443b29c7fa6e889d9611ca0565b901c90505b6110008216156114b75760806114b2826fd097f3bdfd2022b8845ad8f792aa5825611ca0565b901c90505b6120008216156114e25760806114dd826fa9f746462d870fdf8a65dc1f90e061e5611ca0565b901c90505b61400082161561150d576080611508826f70d869a156d2a1b890bb3df62baf32f7611ca0565b901c90505b618000821615611538576080611533826f31be135f97d08fd981231505542fcfa6611ca0565b901c90505b6201000082161561156457608061155f826f09aa508b5b7a84e1c677de54f3e99bc9611ca0565b901c90505b6202000082161561158f57608061158a826e5d6af8dedb81196699c329225ee604611ca0565b901c90505b620400008216156115b95760806115b4826d2216e584f5fa1ea926041bedfe98611ca0565b901c90505b620800008216156115e15760806115dc826b048a170391f7dc42444e8fa2611ca0565b901c90505b60008460020b13156115fc576115f981600019611c8c565b90505b61160a600160201b82611d26565b15611616576001611619565b60005b61069d9060ff16602083901c611c46565b600080806000198587098587029250828110838203039150508060001415611664576000841161165957600080fd5b5082900490506108c5565b80841161167057600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de90602001610609565b61174a817f00000000000000000000000000000000000000000000000000000000000000006117b6565b8051600c80546020909301511515600160a01b9081026001600160a81b03199094166001600160a01b039384161793909317908190556040517fefe4783561b790425a9d83dd379f0e184938b04965a63d14ec51c27cb4ca1b3c93610609938316920460ff1690611b8e565b604080518082019091526000808252602082015250604080518082019091526001600160a01b03831681526001602082015292915050565b600082601f8301126117ff57600080fd5b8151602061181461180f83611c23565b611bf3565b80838252828201915082860187848660051b890101111561183457600080fd5b60005b8581101561185c57815161184a81611dec565b84529284019290840190600101611837565b5090979650505050505050565b803563ffffffff8116811461187d57600080fd5b919050565b60006020828403121561189457600080fd5b81356108c581611dec565b6000602082840312156118b157600080fd5b81516108c581611dec565b600080604083850312156118cf57600080fd5b82356118da81611dec565b915060208301356118ea81611dec565b809150509250929050565b6000806040838503121561190857600080fd5b823561191381611dec565b91506020838101356001600160401b0381111561192f57600080fd5b8401601f8101861361194057600080fd5b803561194e61180f82611c23565b80828252848201915084840189868560051b870101111561196e57600080fd5b600094505b838510156119985761198481611869565b835260019490940193918501918501611973565b5080955050505050509250929050565b600080604083850312156119bb57600080fd5b82356119c681611dec565b946020939093013593505050565b600080604083850312156119e757600080fd5b82516001600160401b03808211156119fe57600080fd5b818501915085601f830112611a1257600080fd5b81516020611a2261180f83611c23565b8083825282820191508286018a848660051b8901011115611a4257600080fd5b600096505b84871015611a6e578051611a5a81611e01565b835260019690960195918301918301611a47565b5091880151919650909350505080821115611a8857600080fd5b50611a95858286016117ee565b9150509250929050565b600080600060608486031215611ab457600080fd5b83356001600160801b0381168114611acb57600080fd5b92506020840135611adb81611e01565b929592945050506040919091013590565b600060208284031215611afe57600080fd5b5035919050565b600060208284031215611b1757600080fd5b5051919050565b600080600060608486031215611b3357600080fd5b833592506020840135611adb81611e01565b600060208284031215611b5757600080fd5b6108c582611869565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015611be757835163ffffffff1683529284019291840191600101611bc5565b50909695505050505050565b604051601f8201601f191681016001600160401b0381118282101715611c1b57611c1b611dd6565b604052919050565b60006001600160401b03821115611c3c57611c3c611dd6565b5060051b60200190565b60008219821115611c5957611c59611d94565b500190565b600082611c6d57611c6d611daa565b600160ff1b821460001984141615611c8757611c87611d94565b500590565b600082611c9b57611c9b611daa565b500490565b6000816000190483118215151615611cba57611cba611d94565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615611cea57611cea611d94565b81667fffffffffffff018313811615611d0557611d05611d94565b5090039392505050565b600082821015611d2157611d21611d94565b500390565b600082611d3557611d35611daa565b500690565b60008160020b627fffff19811415611d5457611d54611d94565b60000392915050565b6000600160ff1b821415611d7357611d73611d94565b5060000390565b60008160060b667fffffffffffff19811415611d5457611d545b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461066f57600080fd5b8060060b811461066f57600080fdfea264697066735822122011a569d9b067df5849bbb39f35f6e4fa0bacdee433b747b160865948c42a65ef64736f6c63430008070033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101f35760003560e01c80637b40c913116101165780637b40c913146103c15780638561579c146103e05780638a9b1b09146103e95780639aaad679146103f2578063a0d2710714610417578063a62611a21461042a578063ab033ea914610433578063ab5dce0014610446578063ab8cedc514610459578063ad5c46481461046c578063b2e0df9614610493578063b93f5af0146104a6578063c84993af146104b9578063ca4f2803146104cc578063dc686d91146104ed578063e244208b14610525578063eb37d34914610538578063ed1bd76c14610561578063f39c38a014610574578063fae63d6114610587578063fe10d7741461059a57600080fd5b806305e0b9a0146101f85780630c52583514610235578063117cfc1b1461024a578063160e1e311461025d5780632248e82d14610270578063238efcbc1461029157806325f09e61146102995780632742b9e7146102a25780632750c0f9146102ab578063289adb44146102d857806337090c2f146102eb5780633b67c3bd146102f45780633cc7ab30146103075780633facf2421461031a578063435b21c114610323578063516c3323146103515780635aa6e675146103645780635c38eb3a14610377578063607e48d41461038a578063696a437b1461039d575b600080fd5b61021f7f000000000000000000000000000000000000000000000000000000000000000081565b60405161022c9190611b60565b60405180910390f35b610248610243366004611aec565b6105ad565b005b60095461021f906001600160a01b031681565b61024861026b366004611882565b610614565b61028361027e3660046119a8565b610672565b60405190815260200161022c565b6102486106a5565b61028361271081565b61028360045481565b600c546102ca906001600160a01b03811690600160a01b900460ff1682565b60405161022c929190611b8e565b6102486102e6366004611aec565b610731565b61028360035481565b610283610302366004611aec565b610791565b610248610315366004611882565b6107a5565b61028360055481565b610336610331366004611aec565b610843565b6040805193845260208401929092529082015260600161022c565b61028361035f366004611aec565b610871565b60005461021f906001600160a01b031681565b6102486103853660046118bc565b6108cc565b610248610398366004611aec565b61099f565b6103b16103ab366004611882565b50600190565b604051901515815260200161022c565b600a546102ca906001600160a01b03811690600160a01b900460ff1682565b61028360025481565b61028360085481565b6006546104029063ffffffff1681565b60405163ffffffff909116815260200161022c565b610283610425366004611b1e565b6109ff565b61028360075481565b610248610441366004611882565b610a3b565b610248610454366004611aec565b610ab1565b610283610467366004611a9f565b610b11565b61021f7f000000000000000000000000000000000000000000000000000000000000000081565b6102486104a1366004611aec565b610bb5565b6102486104b4366004611b45565b610c15565b6102836104c7366004611aec565b610c49565b6104df6104da366004611882565b610c55565b60405161022c929190611b74565b6105006104fb3660046118f5565b610d43565b60408051600694850b81529290930b602083015215159181019190915260600161022c565b610248610533366004611aec565b610e4e565b61021f610546366004611882565b600b602052600090815260409020546001600160a01b031681565b61028361056f366004611aec565b610eae565b60015461021f906001600160a01b031681565b610248610595366004611882565b611009565b6102836105a8366004611882565b611064565b6000546001600160a01b031633146105d8576040516354348f0360e01b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b0316331461063f576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166106665760405163d92e233d60e01b815260040160405180910390fd5b61066f81611170565b50565b60008061068161035f85611064565b905061069d6127106106938386611ca0565b61056f9190611c8c565b949350505050565b6001546001600160a01b031633146106d057604051637ef5703160e11b815260040160405180910390fd5b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161072791611b60565b60405180910390a1565b6000546001600160a01b0316331461075c576040516354348f0360e01b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b90602001610609565b600061079f6103e883611c8c565b92915050565b6000546001600160a01b031633146107d0576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166107f75760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a9161060991611b60565b6000806000610859670de0b6b3a7640000610eae565b915061086484610871565b6005549095929450925050565b600061087f82600454611206565b91506000600454836002546003546108979190611d0f565b6108a19190611ca0565b6108ab9190611c8c565b6002546108b89190611c46565b90506108c5600182611ca0565b9392505050565b6000546001600160a01b031633146108f7576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038216158061091457506001600160a01b038116155b156109325760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038281166000908152600b60205260409081902080546001600160a01b03191692841692909217909155517fc1d3048301c0d23629a2532c8defa6d68f8e1a0e4157918769e9fb1b2eeb888e906109939084908490611b74565b60405180910390a15050565b6000546001600160a01b031633146109ca576040516354348f0360e01b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b90602001610609565b600080610a18610a1384600687900b611c5e565b61121c565b9050610a32600160601b86836001600160a01b031661162a565b95945050505050565b6000546001600160a01b03163314610a66576040516354348f0360e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90610609908390611b60565b6000546001600160a01b03163314610adc576040516354348f0360e01b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e90602001610609565b600080610b25610a1384600687900b611c5e565b90506001600160801b036001600160a01b03821611610b75576000610b536001600160a01b03831680611ca0565b9050610b6d600160c01b876001600160801b03168361162a565b925050610bad565b6000610b8f6001600160a01b03831680600160401b61162a565b9050610ba9600160801b876001600160801b03168361162a565b9250505b509392505050565b6000546001600160a01b03163314610be0576040516354348f0360e01b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa90602001610609565b6000546001600160a01b03163314610c40576040516354348f0360e01b815260040160405180910390fd5b61066f816116d8565b600061079f3283610672565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610c9157600080fd5b505afa158015610ca5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc9919061189f565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0257600080fd5b505afa158015610d16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3a919061189f565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b8152600401610d749190611ba9565b60006040518083038186803b158015610d8c57600080fd5b505afa925050508015610dc157506040513d6000823e601f3d908101601f19168201604052610dbe91908101906119d4565b60015b610dfb573d808015610def576040519150601f19603f3d011682016040523d82523d6000602084013e610df4565b606091505b5050610e47565b81600081518110610e0e57610e0e611dc0565b60200260200101519450600182511115610e405781600181518110610e3557610e35611dc0565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b03163314610e79576040516354348f0360e01b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d5415922190602001610609565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff16918391506001908110610ef257610ef2611dc0565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd90610f38908590600401611ba9565b60006040518083038186803b158015610f5057600080fd5b505afa158015610f64573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f8c91908101906119d4565b509050600081600181518110610fa457610fa4611dc0565b602002602001015182600081518110610fbf57610fbf611dc0565b6020026020010151610fd19190611cbf565b600a54909150610a32908690600160a01b900460ff16610ff957610ff483611d7a565b610ffb565b825b60065463ffffffff16610b11565b6000546001600160a01b03163314611034576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661105b5760405163d92e233d60e01b815260040160405180910390fd5b61066f81611720565b600080600960009054906101000a90046001600160a01b03166001600160a01b0316631ef94b916040518163ffffffff1660e01b815260040160206040518083038186803b1580156110b557600080fd5b505afa1580156110c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ed919061189f565b60095460405163a39744b560e01b81529192506001600160a01b03169063a39744b5906111209086908590600401611b74565b60206040518083038186803b15801561113857600080fd5b505afa15801561114c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c59190611b05565b61119a817f00000000000000000000000000000000000000000000000000000000000000006117b6565b8051600a80546020909301511515600160a01b9081026001600160a81b03199094166001600160a01b039384161793909317908190556040517f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf410893610609938316920460ff1690611b8e565b600081831061121557816108c5565b5090919050565b60008060008360020b12611233578260020b611240565b8260020b61124090611d5d565b905061124f620d89e719611d3a565b60020b8111156112895760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b60006001821661129d57600160801b6112af565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b0316905060028216156112e45760806112df826ffff97272373d413259a46990580e213a611ca0565b901c90505b600482161561130e576080611309826ffff2e50f5f656932ef12357cf3c7fdcc611ca0565b901c90505b6008821615611338576080611333826fffe5caca7e10e4e61c3624eaa0941cd0611ca0565b901c90505b601082161561136257608061135d826fffcb9843d60f6159c9db58835c926644611ca0565b901c90505b602082161561138c576080611387826fff973b41fa98c081472e6896dfb254c0611ca0565b901c90505b60408216156113b65760806113b1826fff2ea16466c96a3843ec78b326b52861611ca0565b901c90505b60808216156113e05760806113db826ffe5dee046a99a2a811c461f1969c3053611ca0565b901c90505b61010082161561140b576080611406826ffcbe86c7900a88aedcffc83b479aa3a4611ca0565b901c90505b610200821615611436576080611431826ff987a7253ac413176f2b074cf7815e54611ca0565b901c90505b61040082161561146157608061145c826ff3392b0822b70005940c7a398e4b70f3611ca0565b901c90505b61080082161561148c576080611487826fe7159475a2c29b7443b29c7fa6e889d9611ca0565b901c90505b6110008216156114b75760806114b2826fd097f3bdfd2022b8845ad8f792aa5825611ca0565b901c90505b6120008216156114e25760806114dd826fa9f746462d870fdf8a65dc1f90e061e5611ca0565b901c90505b61400082161561150d576080611508826f70d869a156d2a1b890bb3df62baf32f7611ca0565b901c90505b618000821615611538576080611533826f31be135f97d08fd981231505542fcfa6611ca0565b901c90505b6201000082161561156457608061155f826f09aa508b5b7a84e1c677de54f3e99bc9611ca0565b901c90505b6202000082161561158f57608061158a826e5d6af8dedb81196699c329225ee604611ca0565b901c90505b620400008216156115b95760806115b4826d2216e584f5fa1ea926041bedfe98611ca0565b901c90505b620800008216156115e15760806115dc826b048a170391f7dc42444e8fa2611ca0565b901c90505b60008460020b13156115fc576115f981600019611c8c565b90505b61160a600160201b82611d26565b15611616576001611619565b60005b61069d9060ff16602083901c611c46565b600080806000198587098587029250828110838203039150508060001415611664576000841161165957600080fd5b5082900490506108c5565b80841161167057600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de90602001610609565b61174a817f00000000000000000000000000000000000000000000000000000000000000006117b6565b8051600c80546020909301511515600160a01b9081026001600160a81b03199094166001600160a01b039384161793909317908190556040517fefe4783561b790425a9d83dd379f0e184938b04965a63d14ec51c27cb4ca1b3c93610609938316920460ff1690611b8e565b604080518082019091526000808252602082015250604080518082019091526001600160a01b03831681526001602082015292915050565b600082601f8301126117ff57600080fd5b8151602061181461180f83611c23565b611bf3565b80838252828201915082860187848660051b890101111561183457600080fd5b60005b8581101561185c57815161184a81611dec565b84529284019290840190600101611837565b5090979650505050505050565b803563ffffffff8116811461187d57600080fd5b919050565b60006020828403121561189457600080fd5b81356108c581611dec565b6000602082840312156118b157600080fd5b81516108c581611dec565b600080604083850312156118cf57600080fd5b82356118da81611dec565b915060208301356118ea81611dec565b809150509250929050565b6000806040838503121561190857600080fd5b823561191381611dec565b91506020838101356001600160401b0381111561192f57600080fd5b8401601f8101861361194057600080fd5b803561194e61180f82611c23565b80828252848201915084840189868560051b870101111561196e57600080fd5b600094505b838510156119985761198481611869565b835260019490940193918501918501611973565b5080955050505050509250929050565b600080604083850312156119bb57600080fd5b82356119c681611dec565b946020939093013593505050565b600080604083850312156119e757600080fd5b82516001600160401b03808211156119fe57600080fd5b818501915085601f830112611a1257600080fd5b81516020611a2261180f83611c23565b8083825282820191508286018a848660051b8901011115611a4257600080fd5b600096505b84871015611a6e578051611a5a81611e01565b835260019690960195918301918301611a47565b5091880151919650909350505080821115611a8857600080fd5b50611a95858286016117ee565b9150509250929050565b600080600060608486031215611ab457600080fd5b83356001600160801b0381168114611acb57600080fd5b92506020840135611adb81611e01565b929592945050506040919091013590565b600060208284031215611afe57600080fd5b5035919050565b600060208284031215611b1757600080fd5b5051919050565b600080600060608486031215611b3357600080fd5b833592506020840135611adb81611e01565b600060208284031215611b5757600080fd5b6108c582611869565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682521515602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015611be757835163ffffffff1683529284019291840191600101611bc5565b50909695505050505050565b604051601f8201601f191681016001600160401b0381118282101715611c1b57611c1b611dd6565b604052919050565b60006001600160401b03821115611c3c57611c3c611dd6565b5060051b60200190565b60008219821115611c5957611c59611d94565b500190565b600082611c6d57611c6d611daa565b600160ff1b821460001984141615611c8757611c87611d94565b500590565b600082611c9b57611c9b611daa565b500490565b6000816000190483118215151615611cba57611cba611d94565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615611cea57611cea611d94565b81667fffffffffffff018313811615611d0557611d05611d94565b5090039392505050565b600082821015611d2157611d21611d94565b500390565b600082611d3557611d35611daa565b500690565b60008160020b627fffff19811415611d5457611d54611d94565b60000392915050565b6000600160ff1b821415611d7357611d73611d94565b5060000390565b60008160060b667fffffffffffff19811415611d5457611d545b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461066f57600080fd5b8060060b811461066f57600080fdfea264697066735822122011a569d9b067df5849bbb39f35f6e4fa0bacdee433b747b160865948c42a65ef64736f6c63430008070033", - "devdoc": { - "kind": "dev", - "methods": { - "bonds(address)": { - "params": { - "_keeper": "The address of the keeper to check" - }, - "returns": { - "_amountBonded": "The amount of KP3R the keeper has bonded" - } - }, - "getKP3RsAtTick(uint256,int56,uint256)": { - "params": { - "_liquidityAmount": "Amount of liquidity to be converted", - "_tickDifference": "Tick value used to calculate the quote", - "_timeInterval": "Time value used to calculate the quote" - }, - "returns": { - "_kp3rAmount": "Amount of KP3R tokens underlying on the given liquidity" - } - }, - "getPaymentParams(uint256)": { - "params": { - "_bonds": "Amount of bonded KP3R owned by the keeper" - }, - "returns": { - "_boost": "Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R", - "_extra": "Amount of extra gas that should be added to the gas spent", - "_oneEthQuote": "Amount of KP3R tokens equivalent to 1 ETH" - } - }, - "getPoolTokens(address)": { - "params": { - "_pool": "Address of the correspondant pool" - }, - "returns": { - "_token0": "Address of the first token of the pair", - "_token1": "Address of the second token of the pair" - } - }, - "getQuoteAtTick(uint128,int56,uint256)": { - "params": { - "_baseAmount": "Amount of token to be converted", - "_tickDifference": "Tick value used to calculate the quote", - "_timeInterval": "Time value used to calculate the quote" - }, - "returns": { - "_quoteAmount": "Amount of credits deserved for the baseAmount at the tick value" - } - }, - "getRewardAmount(uint256)": { - "params": { - "_gasUsed": "The amount of gas used that will be rewarded" - }, - "returns": { - "_amount": "The amount of KP3R that should be awarded to tx.origin" - } - }, - "getRewardAmountFor(address,uint256)": { - "params": { - "_gasUsed": "The amount of gas used that will be rewarded", - "_keeper": "The address of the keeper to check" - }, - "returns": { - "_kp3r": "The amount of KP3R that should be awarded to the keeper" - } - }, - "getRewardBoostFor(uint256)": { - "details": "If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%", - "params": { - "_bonds": "The amount of KP3R tokens bonded by the keeper" - }, - "returns": { - "_rewardBoost": "The reward boost that corresponds to the keeper" - } - }, - "isKP3RToken0(address)": { - "details": "Overrides token comparison with KP3R address" - }, - "observe(address,uint32[])": { - "params": { - "_pool": "Address of the pool to observe", - "_secondsAgo": "Array with time references to observe" - }, - "returns": { - "_success": "Boolean indicating if the observe call was succesfull", - "_tickCumulative1": "Cumulative sum of ticks until first time reference", - "_tickCumulative2": "Cumulative sum of ticks until second time reference" - } - }, - "quote(uint256)": { - "details": "This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas", - "params": { - "_eth": "The amount of ETH" - }, - "returns": { - "_amountOut": "The amount of KP3R" - } - }, - "quoteUsdToEth(uint256)": { - "details": "Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R", - "params": { - "_usd": "The amount of USD to quote to ETH" - }, - "returns": { - "_0": "The resulting amount of ETH after quoting the USD" - } - }, - "setGovernance(address)": { - "params": { - "_governance": "The address being proposed as the new governance" - } - }, - "setKeep3rV2(address)": { - "params": { - "_keep3rV2": "The address of Keep3r V2" - } - }, - "setKp3rWethPool(address)": { - "params": { - "_poolAddress": "The address of the KP3R-WETH pool" - } - }, - "setMaxBoost(uint256)": { - "params": { - "_maxBoost": "The maximum boost multiplier" - } - }, - "setMinBaseFee(uint256)": { - "params": { - "_minBaseFee": "The minimum rewarded gas fee" - } - }, - "setMinBoost(uint256)": { - "params": { - "_minBoost": "The minimum boost multiplier" - } - }, - "setMinPriorityFee(uint256)": { - "params": { - "_minPriorityFee": "The minimum rewarded priority fee" - } - }, - "setOracle(address,address)": { - "details": "The oracle must contain KP3R as either token0 or token1", - "params": { - "_liquidity": "The address of the liquidity", - "_oracle": "The address of the pool used to quote the liquidity from" - } - }, - "setQuoteTwapTime(uint32)": { - "params": { - "_quoteTwapTime": "The twap time for quoting" - } - }, - "setTargetBond(uint256)": { - "params": { - "_targetBond": "The target bond amount" - } - }, - "setWethUsdPool(address)": { - "details": "The oracle must contain WETH as either token0 or token1", - "params": { - "_poolAddress": "The address of the pool used as oracle" - } - }, - "setWorkExtraGas(uint256)": { - "params": { - "_workExtraGas": "The work extra gas" - } - } - }, - "version": 1 - }, - "userdoc": { - "errors": { - "InvalidOraclePool()": [ - { - "notice": "Throws when pool does not have KP3R as token0 nor token1" - } - ], - "LiquidityPairInvalid()": [ - { - "notice": "Throws when none of the tokens in the liquidity pair is KP3R" - } - ], - "NoGovernanceZeroAddress()": [ - { - "notice": "Throws if trying to set governance to zero address" - } - ], - "OnlyGovernance()": [ - { - "notice": "Throws if the caller of the function is not governance" - } - ], - "OnlyPendingGovernance()": [ - { - "notice": "Throws if the caller of the function is not pendingGovernance" - } - ], - "ZeroAddress()": [ - { - "notice": "Throws if a variable is assigned to the zero address" - } - ] - }, - "events": { - "GovernanceProposal(address)": { - "notice": "Emitted when a new governance is proposed" - }, - "GovernanceSet(address)": { - "notice": "Emitted when pendingGovernance accepts to be governance" - }, - "Keep3rV2Change(address)": { - "notice": "Emitted when the Keep3r V2 address is changed" - }, - "Kp3rWethPoolChange(address,bool)": { - "notice": "Emitted when the kp3r weth pool is changed" - }, - "MaxBoostChange(uint256)": { - "notice": "Emitted when the maximum boost multiplier is changed" - }, - "MinBaseFeeChange(uint256)": { - "notice": "Emitted when minimum rewarded gas fee is changed" - }, - "MinBoostChange(uint256)": { - "notice": "Emitted when the minimum boost multiplier is changed" - }, - "MinPriorityFeeChange(uint256)": { - "notice": "Emitted when minimum rewarded priority fee is changed" - }, - "OracleSet(address,address)": { - "notice": "The oracle for a liquidity has been saved" - }, - "QuoteTwapTimeChange(uint32)": { - "notice": "Emitted when the quote twap time is changed" - }, - "TargetBondChange(uint256)": { - "notice": "Emitted when the target bond amount is changed" - }, - "WethUSDPoolChange(address,bool)": { - "notice": "Emitted when the WETH USD pool is changed" - }, - "WorkExtraGasChange(uint256)": { - "notice": "Emitted when the work extra gas amount is changed" - } - }, - "kind": "user", - "methods": { - "BOOST_BASE()": { - "notice": "The boost base used to calculate the boost rewards for the keeper" - }, - "KP3R()": { - "notice": "Address of KP3R token" - }, - "WETH()": { - "notice": "Ethereum mainnet WETH address used for quoting references" - }, - "acceptGovernance()": { - "notice": "Changes the governance from the current governance to the previously proposed address" - }, - "bonds(address)": { - "notice": "Uses valid wKP3R address from Keep3rSidechain to query keeper bonds" - }, - "getKP3RsAtTick(uint256,int56,uint256)": { - "notice": "Given a tick and a liquidity amount, calculates the underlying KP3R tokens" - }, - "getPaymentParams(uint256)": { - "notice": "Get multiplier, quote, and extra, in order to calculate keeper payment" - }, - "getPoolTokens(address)": { - "notice": "Given a pool address, returns the underlying tokens of the pair" - }, - "getQuoteAtTick(uint128,int56,uint256)": { - "notice": "Given a tick and a token amount, calculates the output in correspondant token" - }, - "getRewardAmount(uint256)": { - "notice": "Calculates the reward (in KP3R) that corresponds to tx.origin for using gas" - }, - "getRewardAmountFor(address,uint256)": { - "notice": "Calculates the reward (in KP3R) that corresponds to a keeper for using gas" - }, - "getRewardBoostFor(uint256)": { - "notice": "Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded" - }, - "governance()": { - "notice": "Stores the governance address" - }, - "keep3rV2()": { - "notice": "Address of Keep3r V2" - }, - "kp3rWethPool()": { - "notice": "KP3R-WETH pool that is being used as oracle" - }, - "maxBoost()": { - "notice": "The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE" - }, - "minBaseFee()": { - "notice": "The minimum base fee that is used to calculate keeper rewards" - }, - "minBoost()": { - "notice": "The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE" - }, - "minPriorityFee()": { - "notice": "The minimum priority fee that is also rewarded for keepers" - }, - "observe(address,uint32[])": { - "notice": "Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment" - }, - "pendingGovernance()": { - "notice": "Stores the pendingGovernance address" - }, - "quote(uint256)": { - "notice": "Calculates the amount of KP3R that corresponds to the ETH passed into the function" - }, - "quoteTwapTime()": { - "notice": "The twap time for quoting" - }, - "quoteUsdToEth(uint256)": { - "notice": "Quotes USD to ETH" - }, - "setGovernance(address)": { - "notice": "Proposes a new address to be governance" - }, - "setKeep3rV2(address)": { - "notice": "Sets the Keep3r V2 address" - }, - "setKp3rWethPool(address)": { - "notice": "Sets KP3R-WETH pool" - }, - "setMaxBoost(uint256)": { - "notice": "Sets the maximum boost multiplier" - }, - "setMinBaseFee(uint256)": { - "notice": "Sets the minimum rewarded gas fee" - }, - "setMinBoost(uint256)": { - "notice": "Sets the minimum boost multiplier" - }, - "setMinPriorityFee(uint256)": { - "notice": "Sets the minimum rewarded gas priority fee" - }, - "setOracle(address,address)": { - "notice": "Sets an oracle for a given liquidity" - }, - "setQuoteTwapTime(uint32)": { - "notice": "Sets the quote twap time" - }, - "setTargetBond(uint256)": { - "notice": "Sets the target bond amount" - }, - "setWethUsdPool(address)": { - "notice": "Sets an oracle for querying WETH/USD quote" - }, - "setWorkExtraGas(uint256)": { - "notice": "Sets the work extra gas amount" - }, - "targetBond()": { - "notice": "The targeted amount of bonded KP3Rs to max-up reward multiplier For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get the maximum boost possible in his rewards, if it's less, the reward boost will be proportional" - }, - "wethUSDPool()": { - "notice": "WETH-USD pool that is being used as oracle" - }, - "workExtraGas()": { - "notice": "The amount of unaccounted gas that is going to be added to keeper payments" - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 5374, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "governance", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 5378, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "pendingGovernance", - "offset": 0, - "slot": "1", - "type": "t_address" - }, - { - "astId": 2989, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "minBoost", - "offset": 0, - "slot": "2", - "type": "t_uint256" - }, - { - "astId": 2994, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "maxBoost", - "offset": 0, - "slot": "3", - "type": "t_uint256" - }, - { - "astId": 2999, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "targetBond", - "offset": 0, - "slot": "4", - "type": "t_uint256" - }, - { - "astId": 3004, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "workExtraGas", - "offset": 0, - "slot": "5", - "type": "t_uint256" - }, - { - "astId": 3009, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "quoteTwapTime", - "offset": 0, - "slot": "6", - "type": "t_uint32" - }, - { - "astId": 3014, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "minBaseFee", - "offset": 0, - "slot": "7", - "type": "t_uint256" - }, - { - "astId": 3019, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "minPriorityFee", - "offset": 0, - "slot": "8", - "type": "t_uint256" - }, - { - "astId": 3023, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "keep3rV2", - "offset": 0, - "slot": "9", - "type": "t_address" - }, - { - "astId": 3028, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "kp3rWethPool", - "offset": 0, - "slot": "10", - "type": "t_struct(TokenOraclePool)12960_storage" - }, - { - "astId": 9749, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "oracle", - "offset": 0, - "slot": "11", - "type": "t_mapping(t_address,t_address)" - }, - { - "astId": 9754, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "wethUSDPool", - "offset": 0, - "slot": "12", - "type": "t_struct(TokenOraclePool)12960_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_mapping(t_address,t_address)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => address)", - "numberOfBytes": "32", - "value": "t_address" - }, - "t_struct(TokenOraclePool)12960_storage": { - "encoding": "inplace", - "label": "struct IKeep3rHelperParameters.TokenOraclePool", - "members": [ - { - "astId": 12957, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "poolAddress", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 12959, - "contract": "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol:Keep3rHelperSidechainForTestnet", - "label": "isTKNToken0", - "offset": 20, - "slot": "0", - "type": "t_bool" - } - ], - "numberOfBytes": "32" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "encoding": "inplace", - "label": "uint32", - "numberOfBytes": "4" - } - } - } -} \ No newline at end of file diff --git a/deployments/optimisticGoerli/Keep3rSidechainForTestnet.json b/deployments/optimisticGoerli/Keep3rSidechainForTestnet.json index d7405b8..3624b52 100644 --- a/deployments/optimisticGoerli/Keep3rSidechainForTestnet.json +++ b/deployments/optimisticGoerli/Keep3rSidechainForTestnet.json @@ -1,5 +1,5 @@ { - "address": "0x3C9636ab56aced6C845d6D13805901A0a0B13b51", + "address": "0x85063437C02Ba7F4f82F898859e4992380DEd3bb", "abi": [ { "inputs": [ @@ -2415,9 +2415,9 @@ "name": "virtualReserves", "outputs": [ { - "internalType": "uint256", + "internalType": "int256", "name": "_virtualReserves", - "type": "uint256" + "type": "int256" } ], "stateMutability": "view", @@ -2557,33 +2557,33 @@ "type": "function" } ], - "transactionHash": "0x37e0b510264277cc817ad2bb1d831d717f9e68e1c123f6b28811c12c44fe3e6a", + "transactionHash": "0x7810e51483be33da70766b089564ba82b91df4e2a2a495a9fe469a6e5b90cbdf", "receipt": { "to": null, "from": "0x258b180E741157763236F5277619D71ECf00B906", - "contractAddress": "0x3C9636ab56aced6C845d6D13805901A0a0B13b51", + "contractAddress": "0x85063437C02Ba7F4f82F898859e4992380DEd3bb", "transactionIndex": 0, - "gasUsed": "5525737", + "gasUsed": "5495089", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc3ad037a6eaa96cf15da36899cdab8688e2aa65ebeecc8ae6ae01e9550886da2", - "transactionHash": "0x37e0b510264277cc817ad2bb1d831d717f9e68e1c123f6b28811c12c44fe3e6a", + "blockHash": "0x4d4275f7be655158e81490cc1eb942343cefaeaa7bb9b823445967e630f7e36c", + "transactionHash": "0x7810e51483be33da70766b089564ba82b91df4e2a2a495a9fe469a6e5b90cbdf", "logs": [], - "blockNumber": 3073574, - "cumulativeGasUsed": "5525737", + "blockNumber": 3238159, + "cumulativeGasUsed": "5495089", "status": 1, "byzantium": true }, "args": [ "0x258b180E741157763236F5277619D71ECf00B906", - "0xaE0A8A7634C6Ba5BE83135cA92C2e598c75f1bb7", - "0x68Db1c8d85C09d546097C65ec7DCBFF4D6497CbF", - "0xb4A7137B024d4C0531b0164fCb6E8fc20e6777Ae" + "0x399394ca069dCDE2C4d2a32E00a06C3D5fE17E3A", + "0x3Db593146464816F10d4eBA4743C76A5A4D08425", + "0xBa4A759E41cCA14980bE4106792cdAC5F7BeDF83" ], - "numDeployments": 2, - "solcInputHash": "a2dd8c00aab95ba5d841446478d867fa", - "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyAJob\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyAKeeper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Deprecated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Disputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasNotInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientJobTokenCredits\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityLessThanMin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationImpossible\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenCreditsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MinRewardPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDisputer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySlasher\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenUnallowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Activation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"BondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Bonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"Dispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"DustSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"FeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"InflationPeriodChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOwner\",\"type\":\"address\"}],\"name\":\"JobAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationSuccessful\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipAssent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_pendingOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashLiquidity\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"Keep3rHelperChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"Keep3rV1Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"Keep3rV1ProxyChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"KeeperRevoke\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"KeeperSlash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperValidation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_credit\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperWork\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityApproval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsForced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsReward\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"LiquidityMinimumChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityRevocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_resolver\",\"type\":\"address\"}],\"name\":\"Resolve\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"RewardPeriodTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"UnbondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeperOrJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_unbonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Unbonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"acceptJobMigration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"acceptJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"activate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"addDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"addJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addLiquidityToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"addSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addTokenCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"approveLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"approvedLiquidities\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"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\":[],\"name\":\"bondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"}],\"name\":\"bondedPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canActivateAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canWithdrawAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"changeJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"directTokenPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"dispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"firstSeen\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"forceLiquidityCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"hasBonded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"inflationPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minBond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_earned\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_age\",\"type\":\"uint256\"}],\"name\":\"isBondedKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isBondedKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"isKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobLiquidityCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobPendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobPeriodCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCreditsAddedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"jobs\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rHelper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1Proxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keepers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"liquidityAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidityMinimum\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"migrateJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"observeLiquidity\",\"outputs\":[{\"components\":[{\"internalType\":\"int56\",\"name\":\"current\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"difference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"}],\"internalType\":\"struct IKeep3rJobFundableLiquidity.TickCache\",\"name\":\"_tickCache\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingJobMigrations\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingUnbonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"quoteLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"removeDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"removeSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"resolve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"revoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"revokeLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardPeriodTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"rewardedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sendDust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"setBondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"setInflationPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"setKeep3rHelper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"setKeep3rV1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"setKeep3rV1Proxy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"setLiquidityMinimum\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"setRewardPeriodTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"setUnbondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bonded\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_bondAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_unbondAmount\",\"type\":\"uint256\"}],\"name\":\"slash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashTokenFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"slashers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"totalJobCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_credits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbondLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unbondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"virtualReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_virtualReserves\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawTokenCreditsFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workCompleted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"worked\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_usdPerGasUnit\",\"type\":\"uint256\"}],\"name\":\"worked\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptJobMigration(address,address)\":{\"details\":\"Unbond/withdraw process doesn't get migrated\",\"params\":{\"_fromJob\":\"The address of the job that requested to migrate\",\"_toJob\":\"The address to which the job wants to migrate to\"}},\"acceptJobOwnership(address)\":{\"params\":{\"_job\":\"The address of the job\"}},\"activate(address)\":{\"params\":{\"_bonding\":\"The asset being activated as bond collateral\"}},\"addJob(address)\":{\"params\":{\"_job\":\"Address of the contract for which work should be performed\"}},\"addLiquidityToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity tokens to add\",\"_job\":\"The address of the job to assign liquidity to\",\"_liquidity\":\"The liquidity being added\"}},\"addTokenCreditsToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of credit being added\",\"_job\":\"The address of the job being credited\",\"_token\":\"The address of the token being credited\"}},\"approveLiquidity(address)\":{\"details\":\"Function should be called after setting an oracle in Keep3rHelperSidechain\",\"params\":{\"_liquidity\":\"Address of the liquidity token being approved\"}},\"approvedLiquidities()\":{\"returns\":{\"_list\":\"An array of addresses with all the approved liquidity pairs\"}},\"bond(address,uint256)\":{\"params\":{\"_amount\":\"The amount of bonding asset being bonded\",\"_bonding\":\"The asset being bonded\"}},\"bondedPayment(address,uint256)\":{\"details\":\"Pays the keeper that performs the work with KP3R\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\",\"_payment\":\"The reward that should be allocated for the job\"}},\"changeJobOwnership(address,address)\":{\"params\":{\"_job\":\"The address of the job\",\"_newOwner\":\"The address of the proposed new owner\"}},\"directTokenPayment(address,address,uint256)\":{\"details\":\"Pays the keeper that performs the work with a specific token\",\"params\":{\"_amount\":\"The reward that should be allocated\",\"_keeper\":\"Address of the keeper that performed the work\",\"_token\":\"The asset being awarded to the keeper\"}},\"dispute(address)\":{\"params\":{\"_jobOrKeeper\":\"The address in dispute\"}},\"forceLiquidityCreditsToJob(address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity credits to gift\",\"_job\":\"The address of the job being credited\"}},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"details\":\"Should be used for protected functions\",\"params\":{\"_age\":\"The minimum keeper age required\",\"_bond\":\"The bond token being evaluated\",\"_earned\":\"The minimum funds earned in the keepers lifetime\",\"_keeper\":\"The keeper to check\",\"_minBond\":\"The minimum amount of bonded tokens\"},\"returns\":{\"_isBondedKeeper\":\"Whether the `_keeper` meets the given requirements\"}},\"isKeeper(address)\":{\"details\":\"Can be used for general (non critical) functions\",\"params\":{\"_keeper\":\"The keeper being investigated\"},\"returns\":{\"_isKeeper\":\"Whether the address passed as a parameter is a keeper or not\"}},\"jobLiquidityCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the liquidity credits\"},\"returns\":{\"_liquidityCredits\":\"The liquidity credits of a given job\"}},\"jobPeriodCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the period credits\"},\"returns\":{\"_periodCredits\":\"The credits the given job has at the current period\"}},\"jobs()\":{\"returns\":{\"_list\":\"Array with all the jobs in _jobs\"}},\"keepers()\":{\"returns\":{\"_list\":\"Array with all the keepers in _keepers\"}},\"migrateJob(address,address)\":{\"params\":{\"_fromJob\":\"The address of the job that is requesting to migrate\",\"_toJob\":\"The address at which the job is requesting to migrate\"}},\"observeLiquidity(address)\":{\"params\":{\"_liquidity\":\"Address of the liquidity token being observed\"}},\"quoteLiquidity(address,uint256)\":{\"details\":\"_periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\",\"params\":{\"_amount\":\"The amount of liquidity to provide\",\"_liquidity\":\"The address of the liquidity to provide\"},\"returns\":{\"_periodCredits\":\"The amount of KP3R periodically minted for the given liquidity\"}},\"resolve(address)\":{\"params\":{\"_jobOrKeeper\":\"The address cleared\"}},\"revoke(address)\":{\"params\":{\"_keeper\":\"The address being slashed\"}},\"revokeLiquidity(address)\":{\"params\":{\"_liquidity\":\"The liquidity no longer accepted\"}},\"sendDust(address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of the token that will be transferred\",\"_to\":\"The address that will receive the idle funds\",\"_token\":\"The token that will be transferred\"}},\"setBondTime(uint256)\":{\"params\":{\"_bond\":\"The new bond time\"}},\"setFee(uint256)\":{\"params\":{\"_fee\":\"The new fee\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setInflationPeriod(uint256)\":{\"params\":{\"_inflationPeriod\":\"The new inflation period\"}},\"setKeep3rHelper(address)\":{\"params\":{\"_keep3rHelper\":\"The Keep3rHelper address\"}},\"setKeep3rV1(address)\":{\"params\":{\"_keep3rV1\":\"The Keep3rV1 address\"}},\"setKeep3rV1Proxy(address)\":{\"params\":{\"_keep3rV1Proxy\":\"The Keep3rV1Proxy address\"}},\"setLiquidityMinimum(uint256)\":{\"params\":{\"_liquidityMinimum\":\"The new minimum amount of liquidity\"}},\"setRewardPeriodTime(uint256)\":{\"params\":{\"_rewardPeriodTime\":\"The new amount of time required to pass between rewards\"}},\"setUnbondTime(uint256)\":{\"params\":{\"_unbond\":\"The new unbond time\"}},\"slash(address,address,uint256,uint256)\":{\"params\":{\"_bondAmount\":\"The bonded amount being slashed\",\"_bonded\":\"The asset being slashed\",\"_keeper\":\"The address being slashed\",\"_unbondAmount\":\"The pending unbond amount being slashed\"}},\"slashLiquidityFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity that will be slashed\",\"_job\":\"The address being slashed\",\"_liquidity\":\"The address of the liquidity that will be slashed\"}},\"slashTokenFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of the token that will be slashed\",\"_job\":\"The address of the job from which the token will be slashed\",\"_token\":\"The address of the token that will be slashed\"}},\"totalJobCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the total credits\"},\"returns\":{\"_credits\":\"The total credits of the given job\"}},\"unbond(address,uint256)\":{\"params\":{\"_amount\":\"Allows for partial unbonding\",\"_bonding\":\"The asset being unbonded\"}},\"unbondLiquidityFromJob(address,address,uint256)\":{\"details\":\"Can only be called by the job's owner\",\"params\":{\"_amount\":\"The amount of liquidity being removed\",\"_job\":\"The address of the job being unbonded from\",\"_liquidity\":\"The liquidity being unbonded\"}},\"virtualReserves()\":{\"returns\":{\"_virtualReserves\":\"The surplus amount of wKP3Rs in escrow contract\"}},\"withdraw(address)\":{\"params\":{\"_bonding\":\"The asset to withdraw from the bonding pool\"}},\"withdrawLiquidityFromJob(address,address,address)\":{\"params\":{\"_job\":\"The address of the job being withdrawn from\",\"_liquidity\":\"The liquidity being withdrawn\",\"_receiver\":\"The address that will receive the withdrawn liquidity\"}},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of token to be withdrawn\",\"_job\":\"The address of the job from which the credits are withdrawn\",\"_receiver\":\"The user that will receive tokens\",\"_token\":\"The address of the token being withdrawn\"}},\"worked(address)\":{\"details\":\"Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\"},\"worked(address,uint256)\":{\"details\":\"Uses a USD per gas unit payment mechanism\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\",\"_usdPerGasUnit\":\"Units of USD (in wei) per gas unit that should be rewarded to the keeper\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"AlreadyAJob()\":[{\"notice\":\"Throws when the address that is trying to register as a job is already a job\"}],\"AlreadyAKeeper()\":[{\"notice\":\"Throws when the address that is trying to register as a keeper is already a keeper\"}],\"AlreadyDisputed()\":[{\"notice\":\"Throws when a job or keeper is already disputed\"}],\"BondsLocked()\":[{\"notice\":\"Throws if the time required to bond an asset has not passed yet\"}],\"BondsUnexistent()\":[{\"notice\":\"Throws if there are no bonded assets\"}],\"Deprecated()\":[{\"notice\":\"Throws when job contract calls deprecated worked(address) function\"}],\"Disputed()\":[{\"notice\":\"Throws if either a job or a keeper is disputed\"}],\"DisputerExistent()\":[{\"notice\":\"Throws if the address is already a registered disputer\"}],\"DisputerUnexistent()\":[{\"notice\":\"Throws if caller is not a registered disputer\"}],\"GasNotInitialized()\":[{\"notice\":\"Throws if work method was called without calling isKeeper or isBondedKeeper\"}],\"InsufficientFunds()\":[{\"notice\":\"Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\"}],\"InsufficientJobTokenCredits()\":[{\"notice\":\"Throws when the user tries to withdraw more tokens than it has\"}],\"JobAlreadyAdded()\":[{\"notice\":\"Throws when trying to add a job that has already been added\"}],\"JobDisputed()\":[{\"notice\":\"Throws when an action that requires an undisputed job is applied on a disputed job\"}],\"JobLiquidityInsufficient()\":[{\"notice\":\"Throws when trying to remove more liquidity than the job has\"}],\"JobLiquidityLessThanMin()\":[{\"notice\":\"Throws when trying to add less liquidity than the minimum liquidity required\"}],\"JobLiquidityUnexistent()\":[{\"notice\":\"Throws when the job doesn't have the requested liquidity\"}],\"JobMigrationImpossible()\":[{\"notice\":\"Throws when the address of the job that requests to migrate wants to migrate to its same address\"}],\"JobMigrationLocked()\":[{\"notice\":\"Throws when cooldown between migrations has not yet passed\"}],\"JobMigrationUnavailable()\":[{\"notice\":\"Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\"}],\"JobTokenCreditsLocked()\":[{\"notice\":\"Throws when the token withdraw cooldown has not yet passed\"}],\"JobTokenInsufficient()\":[{\"notice\":\"Throws when someone tries to slash more tokens than the job has\"}],\"JobTokenUnexistent()\":[{\"notice\":\"Throws when the token trying to be slashed doesn't exist\"}],\"JobUnapproved()\":[{\"notice\":\"Throws if the address claiming to be a job is not in the list of approved jobs\"}],\"JobUnavailable()\":[{\"notice\":\"Throws when an address is passed as a job, but that address is not a job\"}],\"LiquidityPairApproved()\":[{\"notice\":\"Throws when the liquidity being approved has already been approved\"}],\"LiquidityPairUnapproved()\":[{\"notice\":\"Throws when trying to add liquidity to an unapproved pool\"}],\"LiquidityPairUnexistent()\":[{\"notice\":\"Throws when the liquidity being removed has not been approved\"}],\"MinRewardPeriod()\":[{\"notice\":\"Throws if the reward period is less than the minimum reward period time\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"NotDisputed()\":[{\"notice\":\"Throws when a job or keeper is not disputed and someone tries to resolve the dispute\"}],\"OnlyDisputer()\":[{\"notice\":\"Throws if the msg.sender is not a disputer or is not a part of governance\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the job owner\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"OnlyPendingJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the pending job owner\"}],\"OnlySlasher()\":[{\"notice\":\"Throws if the msg.sender is not a slasher or is not a part of governance\"}],\"SlasherExistent()\":[{\"notice\":\"Throws if the address is already a registered slasher\"}],\"SlasherUnexistent()\":[{\"notice\":\"Throws if caller is not a registered slasher\"}],\"TokenUnallowed()\":[{\"notice\":\"Throws when the token is KP3R, as it should not be used for direct token payments\"}],\"UnbondsLocked()\":[{\"notice\":\"Throws if the time required to withdraw the bonds has not passed yet\"}],\"UnbondsUnexistent()\":[{\"notice\":\"Throws if there are no bonds to withdraw\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"Activation(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#activate is called\"},\"BondTimeChange(uint256)\":{\"notice\":\"Emitted when bondTime is changed\"},\"Bonding(address,address,uint256)\":{\"notice\":\"Emitted when the bonding process of a new keeper begins\"},\"Dispute(address,address)\":{\"notice\":\"Emitted when a keeper or a job is disputed\"},\"DisputerAdded(address)\":{\"notice\":\"Emitted when a disputer is added\"},\"DisputerRemoved(address)\":{\"notice\":\"Emitted when a disputer is removed\"},\"DustSent(address,uint256,address)\":{\"notice\":\"Emitted when dust is sent\"},\"FeeChange(uint256)\":{\"notice\":\"Emitted when the fee is changed\"},\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"InflationPeriodChange(uint256)\":{\"notice\":\"Emitted when the inflationPeriod is changed\"},\"JobAddition(address,address)\":{\"notice\":\"Emitted when Keep3rJobManager#addJob is called\"},\"JobMigrationRequested(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#migrateJob function is called\"},\"JobMigrationSuccessful(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#acceptJobMigration function is called\"},\"JobOwnershipAssent(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\"},\"JobOwnershipChange(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#changeJobOwnership is called\"},\"JobSlashLiquidity(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\"},\"JobSlashToken(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashTokenFromJob is called\"},\"Keep3rHelperChange(address)\":{\"notice\":\"Emitted when the Keep3rHelper address is changed\"},\"Keep3rV1Change(address)\":{\"notice\":\"Emitted when the Keep3rV1 address is changed\"},\"Keep3rV1ProxyChange(address)\":{\"notice\":\"Emitted when the Keep3rV1Proxy address is changed\"},\"KeeperRevoke(address,address)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#revoke is called\"},\"KeeperSlash(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#slash is called\"},\"KeeperValidation(uint256)\":{\"notice\":\"Emitted when a keeper is validated before a job\"},\"KeeperWork(address,address,address,uint256,uint256)\":{\"notice\":\"Emitted when a keeper works a job\"},\"LiquidityAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityApproval(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\"},\"LiquidityCreditsForced(address,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\"},\"LiquidityCreditsReward(address,uint256,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityMinimumChange(uint256)\":{\"notice\":\"Emitted when _liquidityMinimum is changed\"},\"LiquidityRevocation(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\"},\"LiquidityWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\"},\"Resolve(address,address)\":{\"notice\":\"Emitted when a dispute is resolved\"},\"RewardPeriodTimeChange(uint256)\":{\"notice\":\"Emitted when _rewardPeriodTime is changed\"},\"SlasherAdded(address)\":{\"notice\":\"Emitted when a slasher is added\"},\"SlasherRemoved(address)\":{\"notice\":\"Emitted when a slasher is removed\"},\"TokenCreditAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\"},\"TokenCreditWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\"},\"UnbondTimeChange(uint256)\":{\"notice\":\"Emitted when _unbondTime is changed\"},\"Unbonding(address,address,uint256)\":{\"notice\":\"Emitted when a keeper or job begins the unbonding process to withdraw the funds\"},\"Withdrawal(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#withdraw is called\"}},\"kind\":\"user\",\"methods\":{\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"acceptJobMigration(address,address)\":{\"notice\":\"Completes the migration process for a job\"},\"acceptJobOwnership(address)\":{\"notice\":\"The proposed address accepts to be the owner of the job\"},\"activate(address)\":{\"notice\":\"End of the bonding process after bonding time has passed\"},\"addDisputer(address)\":{\"notice\":\"Registers a disputer by updating the disputers mapping\"},\"addJob(address)\":{\"notice\":\"Allows any caller to add a new job\"},\"addLiquidityToJob(address,address,uint256)\":{\"notice\":\"Allows anyone to fund a job with liquidity\"},\"addSlasher(address)\":{\"notice\":\"Registers a slasher by updating the slashers mapping\"},\"addTokenCreditsToJob(address,address,uint256)\":{\"notice\":\"Add credit to a job to be paid out for work\"},\"approveLiquidity(address)\":{\"notice\":\"Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\"},\"approvedLiquidities()\":{\"notice\":\"Lists liquidity pairs\"},\"bond(address,uint256)\":{\"notice\":\"Beginning of the bonding process\"},\"bondTime()\":{\"notice\":\"The amount of time required to pass after a keeper has bonded assets for it to be able to activate\"},\"bondedPayment(address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"bonds(address,address)\":{\"notice\":\"Mapping (job => bonding => amount)\"},\"canActivateAfter(address,address)\":{\"notice\":\"Tracks when a bonding for a keeper can be activated\"},\"canWithdrawAfter(address,address)\":{\"notice\":\"Tracks when keeper bonds are ready to be withdrawn\"},\"changeJobOwnership(address,address)\":{\"notice\":\"Proposes a new address to be the owner of the job\"},\"directTokenPayment(address,address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"dispute(address)\":{\"notice\":\"Allows governance to create a dispute for a given keeper/job\"},\"disputers(address)\":{\"notice\":\"Tracks whether the address is a disputer or not\"},\"disputes(address)\":{\"notice\":\"Tracks if a keeper or job has a pending dispute\"},\"fee()\":{\"notice\":\"The fee to be sent to governance when a user adds liquidity to a job\"},\"firstSeen(address)\":{\"notice\":\"Tracks when a keeper was first registered\"},\"forceLiquidityCreditsToJob(address,uint256)\":{\"notice\":\"Gifts liquidity credits to the specified job\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"hasBonded(address)\":{\"notice\":\"Checks whether the address has ever bonded an asset\"},\"inflationPeriod()\":{\"notice\":\"The inflation period is the denominator used to regulate the emission of KP3R\"},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"notice\":\"Confirms if the current keeper is registered and has a minimum bond of any asset.\"},\"isKeeper(address)\":{\"notice\":\"Confirms if the current keeper is registered\"},\"jobLiquidityCredits(address)\":{\"notice\":\"Returns the liquidity credits of a given job\"},\"jobOwner(address)\":{\"notice\":\"Maps the job to the owner of the job\"},\"jobPendingOwner(address)\":{\"notice\":\"Maps the job to its pending owner\"},\"jobPeriodCredits(address)\":{\"notice\":\"Returns the credits of a given job for the current period\"},\"jobTokenCredits(address,address)\":{\"notice\":\"The current token credits available for a job\"},\"jobTokenCreditsAddedAt(address,address)\":{\"notice\":\"Last block where tokens were added to the job\"},\"jobs()\":{\"notice\":\"Lists all jobs\"},\"keep3rHelper()\":{\"notice\":\"Address of Keep3rHelper's contract\"},\"keep3rV1()\":{\"notice\":\"Address of Keep3rV1's contract\"},\"keep3rV1Proxy()\":{\"notice\":\"Address of Keep3rV1Proxy's contract\"},\"keepers()\":{\"notice\":\"Lists all keepers\"},\"liquidityAmount(address,address)\":{\"notice\":\"Amount of liquidity in a specified job\"},\"liquidityMinimum()\":{\"notice\":\"The minimum amount of liquidity required to fund a job per liquidity\"},\"migrateJob(address,address)\":{\"notice\":\"Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\"},\"observeLiquidity(address)\":{\"notice\":\"Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\"},\"pendingBonds(address,address)\":{\"notice\":\"Tracks the amount of assets deposited in pending bonds\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"pendingJobMigrations(address)\":{\"notice\":\"Maps the jobs that have requested a migration to the address they have requested to migrate to\"},\"pendingUnbonds(address,address)\":{\"notice\":\"Tracks how much keeper bonds are to be withdrawn\"},\"quoteLiquidity(address,uint256)\":{\"notice\":\"Calculates how many credits should be rewarded periodically for a given liquidity amount\"},\"removeDisputer(address)\":{\"notice\":\"Removes a disputer by updating the disputers mapping\"},\"removeSlasher(address)\":{\"notice\":\"Removes a slasher by updating the slashers mapping\"},\"resolve(address)\":{\"notice\":\"Allows governance to resolve a dispute on a keeper/job\"},\"revoke(address)\":{\"notice\":\"Blacklists a keeper from participating in the network\"},\"revokeLiquidity(address)\":{\"notice\":\"Revoke a liquidity pair from being accepted in future\"},\"rewardPeriodTime()\":{\"notice\":\"The amount of time between each scheduled credits reward given to a job\"},\"rewardedAt(address)\":{\"notice\":\"Last time the job was rewarded liquidity credits\"},\"sendDust(address,uint256,address)\":{\"notice\":\"Allows an authorized user to transfer the tokens or eth that may have been left in a contract\"},\"setBondTime(uint256)\":{\"notice\":\"Sets the bond time required to activate as a keeper\"},\"setFee(uint256)\":{\"notice\":\"Sets the new fee\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setInflationPeriod(uint256)\":{\"notice\":\"Sets the new inflation period\"},\"setKeep3rHelper(address)\":{\"notice\":\"Sets the Keep3rHelper address\"},\"setKeep3rV1(address)\":{\"notice\":\"Sets the Keep3rV1 address\"},\"setKeep3rV1Proxy(address)\":{\"notice\":\"Sets the Keep3rV1Proxy address\"},\"setLiquidityMinimum(uint256)\":{\"notice\":\"Sets the minimum amount of liquidity required to fund a job\"},\"setRewardPeriodTime(uint256)\":{\"notice\":\"Sets the time required to pass between rewards for jobs\"},\"setUnbondTime(uint256)\":{\"notice\":\"Sets the unbond time required unbond what has been bonded\"},\"slash(address,address,uint256,uint256)\":{\"notice\":\"Allows governance to slash a keeper based on a dispute\"},\"slashLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Allows governance or a slasher to slash liquidity from a job\"},\"slashTokenFromJob(address,address,uint256)\":{\"notice\":\"Allows governance or slasher to slash a job specific token\"},\"slashers(address)\":{\"notice\":\"Tracks whether the address is a slasher or not\"},\"totalJobCredits(address)\":{\"notice\":\"Calculates the total credits of a given job\"},\"unbond(address,uint256)\":{\"notice\":\"Beginning of the unbonding process\"},\"unbondLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Unbond liquidity for a job\"},\"unbondTime()\":{\"notice\":\"The amount of time required to pass before a keeper can unbond what he has bonded\"},\"withdraw(address)\":{\"notice\":\"Withdraw funds after unbonding has finished\"},\"withdrawLiquidityFromJob(address,address,address)\":{\"notice\":\"Withdraw liquidity from a job\"},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"notice\":\"Withdraw credit from a job\"},\"workCompleted(address)\":{\"notice\":\"Tracks the total KP3R earnings of a keeper since it started working\"},\"worked(address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"workedAt(address)\":{\"notice\":\"Last time the job was worked\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/testnet/Keep3rSidechainForTestnet.sol\":\"Keep3rSidechainForTestnet\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"solidity/contracts/Keep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2003\\u2003\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2003\\u2003\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../interfaces/IKeep3r.sol';\\nimport './peripherals/jobs/Keep3rJobs.sol';\\nimport './peripherals/keepers/Keep3rKeepers.sol';\\nimport './peripherals/DustCollector.sol';\\n\\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\\n constructor(\\n address _governance,\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\\n}\\n\",\"keccak256\":\"0x0254310b27d0d227544ad1aff272b58e15ae9dc1e62ec290a46ab1b681612f6f\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/DustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '../../contracts/peripherals/Governable.sol';\\nimport '../../interfaces/peripherals/IDustCollector.sol';\\n\\nabstract contract DustCollector is IDustCollector, Governable {\\n using SafeERC20 for IERC20;\\n\\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external override onlyGovernance {\\n if (_to == address(0)) revert ZeroAddress();\\n if (_token == _ETH_ADDRESS) {\\n payable(_to).transfer(_amount);\\n } else {\\n IERC20(_token).safeTransfer(_to, _amount);\\n }\\n emit DustSent(_token, _amount, _to);\\n }\\n}\\n\",\"keccak256\":\"0x246ac2c4057520bb627ea8040367549786f4477a04fd79358927cd607952bc2f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\\nimport './Keep3rRoles.sol';\\n\\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @notice List of all enabled keepers\\n EnumerableSet.AddressSet internal _keepers;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override workCompleted;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override firstSeen;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override disputes;\\n\\n /// @inheritdoc IKeep3rAccountance\\n /// @notice Mapping (job => bonding => amount)\\n mapping(address => mapping(address => uint256)) public override bonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\\n\\n /// @notice The current liquidity credits available for a job\\n mapping(address => uint256) internal _jobLiquidityCredits;\\n\\n /// @notice Map the address of a job to its correspondent periodCredits\\n mapping(address => uint256) internal _jobPeriodCredits;\\n\\n /// @notice Enumerable array of Job Tokens for Credits\\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\\n\\n /// @notice List of liquidities that a job has (job => liquidities)\\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\\n\\n /// @notice Liquidity pool to observe\\n mapping(address => address) internal _liquidityPool;\\n\\n /// @notice Tracks if a pool has KP3R as token0\\n mapping(address => bool) internal _isKP3RToken0;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingBonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override hasBonded;\\n\\n /// @notice List of all enabled jobs\\n EnumerableSet.AddressSet internal _jobs;\\n\\n /// @inheritdoc IKeep3rAccountance\\n function jobs() external view override returns (address[] memory _list) {\\n _list = _jobs.values();\\n }\\n\\n /// @inheritdoc IKeep3rAccountance\\n function keepers() external view override returns (address[] memory _list) {\\n _list = _keepers.values();\\n }\\n}\\n\",\"keccak256\":\"0xf60c57efe1660d3eb37b4c35de90b6d69336fe53a4e129fe942c2dd6c9024b68\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rParameters.sol';\\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\\n\\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\\n /// @inheritdoc IKeep3rDisputable\\n function dispute(address _jobOrKeeper) external override onlyDisputer {\\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\\n disputes[_jobOrKeeper] = true;\\n emit Dispute(_jobOrKeeper, msg.sender);\\n }\\n\\n /// @inheritdoc IKeep3rDisputable\\n function resolve(address _jobOrKeeper) external override onlyDisputer {\\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\\n disputes[_jobOrKeeper] = false;\\n emit Resolve(_jobOrKeeper, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x664b54040aa4e734f68a01fcfb5bf67cbb1a70efd03862cd3a456457536b1fb4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/IKeep3rHelper.sol';\\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\\nimport './Keep3rAccountance.sol';\\n\\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1Proxy;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rHelper;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override bondTime = 3 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override unbondTime = 14 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override liquidityMinimum = 3 ether;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override rewardPeriodTime = 5 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override inflationPeriod = 34 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override fee = 30;\\n\\n /// @notice The base that will be used to calculate the fee\\n uint256 internal constant _BASE = 10_000;\\n\\n /// @notice The minimum reward period\\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\\n\\n constructor(\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) {\\n keep3rHelper = _keep3rHelper;\\n keep3rV1 = _keep3rV1;\\n keep3rV1Proxy = _keep3rV1Proxy;\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\\n if (_keep3rHelper == address(0)) revert ZeroAddress();\\n keep3rHelper = _keep3rHelper;\\n emit Keep3rHelperChange(_keep3rHelper);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1(address _keep3rV1) external override onlyGovernance {\\n if (_keep3rV1 == address(0)) revert ZeroAddress();\\n keep3rV1 = _keep3rV1;\\n emit Keep3rV1Change(_keep3rV1);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\\n keep3rV1Proxy = _keep3rV1Proxy;\\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\\n bondTime = _bondTime;\\n emit BondTimeChange(_bondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\\n unbondTime = _unbondTime;\\n emit UnbondTimeChange(_unbondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\\n liquidityMinimum = _liquidityMinimum;\\n emit LiquidityMinimumChange(_liquidityMinimum);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n // TODO: check what happens to credit minting when changing this. Shouldn't we update the cached ticks?\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\\n rewardPeriodTime = _rewardPeriodTime;\\n emit RewardPeriodTimeChange(_rewardPeriodTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\\n inflationPeriod = _inflationPeriod;\\n emit InflationPeriodChange(_inflationPeriod);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setFee(uint256 _fee) external override onlyGovernance {\\n fee = _fee;\\n emit FeeChange(_fee);\\n }\\n}\\n\",\"keccak256\":\"0xdad90e204120f4cfdac480a7fa2e52d656d2943e9c4016935f68a3cd1cb00d22\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport './DustCollector.sol';\\nimport './Governable.sol';\\n\\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override slashers;\\n\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override disputers;\\n\\n constructor(address _governance) Governable(_governance) DustCollector() {}\\n\\n /// @inheritdoc IKeep3rRoles\\n function addSlasher(address _slasher) external override onlyGovernance {\\n if (_slasher == address(0)) revert ZeroAddress();\\n if (slashers[_slasher]) revert SlasherExistent();\\n slashers[_slasher] = true;\\n emit SlasherAdded(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeSlasher(address _slasher) external override onlyGovernance {\\n if (!slashers[_slasher]) revert SlasherUnexistent();\\n delete slashers[_slasher];\\n emit SlasherRemoved(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function addDisputer(address _disputer) external override onlyGovernance {\\n if (_disputer == address(0)) revert ZeroAddress();\\n if (disputers[_disputer]) revert DisputerExistent();\\n disputers[_disputer] = true;\\n emit DisputerAdded(_disputer);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeDisputer(address _disputer) external override onlyGovernance {\\n if (!disputers[_disputer]) revert DisputerUnexistent();\\n delete disputers[_disputer];\\n emit DisputerRemoved(_disputer);\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a slasher or governance\\n modifier onlySlasher {\\n if (!slashers[msg.sender]) revert OnlySlasher();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a disputer or governance\\n modifier onlyDisputer {\\n if (!disputers[msg.sender]) revert OnlyDisputer();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x61a1cf0d52db8fe78fa8cfb76d9b02f93ef3adc23e6655969bc1a4bb83ea9a95\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\nimport '../Keep3rDisputable.sol';\\n\\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\\n\\n try IERC20(_token).transfer(governance, _amount) {} catch {}\\n jobTokenCredits[_job][_token] -= _amount;\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit JobSlashToken(_job, _token, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x86cdbf44dfa46c6b6e184e48e11cb8571e26cf50c793b6b07227c29e743da397\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice Cooldown between withdrawals\\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n // KP3R shouldn't be used for direct token payments\\n if (_token == keep3rV1) revert TokenUnallowed();\\n uint256 _before = IERC20(_token).balanceOf(address(this));\\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\\n uint256 _tokenFee = (_received * fee) / _BASE;\\n jobTokenCredits[_job][_token] += _received - _tokenFee;\\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\\n IERC20(_token).safeTransfer(governance, _tokenFee);\\n _jobTokens[_job].add(_token);\\n\\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external override nonReentrant onlyJobOwner(_job) {\\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\\n if (disputes[_job]) revert JobDisputed();\\n\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xb600d18903a008a1ca03743de7cef8330c2d5e66db52c900822551a4be75f7a5\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/IPairManager.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '../../libraries/FullMath.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice List of liquidities that are accepted in the system\\n EnumerableSet.AddressSet internal _approvedLiquidities;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override rewardedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override workedAt;\\n\\n /// @notice Tracks an address and returns its TickCache\\n mapping(address => TickCache) internal _tick;\\n\\n // Views\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approvedLiquidities() external view override returns (address[] memory _list) {\\n _list = _approvedLiquidities.values();\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n _periodCredits += _getReward(\\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\\n );\\n }\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n\\n // If the job was rewarded in the past 1 period time\\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\\n // If the job has period credits, update minted job credits to new twap\\n _liquidityCredits = _periodCredits > 0\\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\\n } else {\\n // Else return a full period worth of credits if current credits have expired\\n _liquidityCredits = _periodCredits;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n uint256 _cooldown = block.timestamp;\\n\\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\\n // Will calculate cooldown if it outdated\\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will calculate cooldown from last reward reference in this period\\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\\n } else {\\n // Will calculate cooldown from last reward timestamp\\n _cooldown -= rewardedAt[_job];\\n }\\n } else {\\n // Will calculate cooldown from period start if expired\\n _cooldown -= _period(block.timestamp);\\n }\\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\\n if (_tick[_liquidity].period == _period(block.timestamp)) {\\n // Will return cached twaps if liquidity is updated\\n _tickCache = _tick[_liquidity];\\n } else {\\n bool success;\\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\\n\\n if (_tick[_liquidity].period == lastPeriod) {\\n // Will only ask for current period accumulator if liquidity is outdated\\n uint32[] memory _secondsAgo = new uint32[](1);\\n int56 previousTick = _tick[_liquidity].current;\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n\\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - previousTick;\\n } else if (_tick[_liquidity].period < lastPeriod) {\\n // Will ask for 2 accumulators if liquidity is expired\\n uint32[] memory _secondsAgo = new uint32[](2);\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\\n\\n int56 _tickCumulative2;\\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - _tickCumulative2;\\n }\\n if (success) {\\n _tickCache.period = _period(block.timestamp);\\n } else {\\n delete _tickCache.period;\\n }\\n }\\n }\\n\\n // Methods\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n _settleJobAccountance(_job);\\n _jobLiquidityCredits[_job] += _amount;\\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n emit LiquidityApproval(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\\n delete _liquidityPool[_liquidity];\\n delete _isKP3RToken0[_liquidity];\\n delete _tick[_liquidity];\\n\\n emit LiquidityRevocation(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n\\n _jobLiquidities[_job].add(_liquidity);\\n\\n _settleJobAccountance(_job);\\n\\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\\n liquidityAmount[_job][_liquidity] += _amount;\\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlyJobOwner(_job) {\\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\\n pendingUnbonds[_job][_liquidity] += _amount;\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n\\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit Unbonding(_job, _liquidity, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external override onlyJobOwner(_job) {\\n if (_receiver == address(0)) revert ZeroAddress();\\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[_job]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[_job][_liquidity];\\n\\n delete pendingUnbonds[_job][_liquidity];\\n delete canWithdrawAfter[_job][_liquidity];\\n\\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\\n }\\n\\n // Internal functions\\n\\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\\n if (rewardedAt[_job] < _period(block.timestamp)) {\\n // Will exit function if job has been rewarded in current period\\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\\n // Will reset job to period syncronicity if a full period passed without rewards\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] = _period(block.timestamp);\\n _rewarded = true;\\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will reset job's syncronicity if last reward was more than epoch ago\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] += rewardPeriodTime;\\n _rewarded = true;\\n } else if (workedAt[_job] < _period(block.timestamp)) {\\n // First keeper on period has to update job accountance to current twaps\\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\\n // Updating job accountance does not reward job\\n }\\n }\\n }\\n\\n /// @notice Only called if _jobLiquidityCredits < payment\\n function _rewardJobCredits(address _job) internal {\\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\\n rewardedAt[_job] = block.timestamp;\\n }\\n\\n /// @notice Updates accountance for _jobPeriodCredits\\n function _updateJobPeriod(address _job) internal {\\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\\n }\\n\\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n if (_tick[_liquidity].period != _period(block.timestamp)) {\\n // Updates liquidity cache only if needed\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n }\\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\\n }\\n }\\n }\\n\\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\\n function _unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) internal nonReentrant {\\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\\n\\n // Ensures current twaps in job liquidities\\n _updateJobPeriod(_job);\\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\\n\\n // A liquidity can be revoked causing a job to have 0 periodCredits\\n if (_jobPeriodCredits[_job] > 0) {\\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\\n }\\n\\n liquidityAmount[_job][_liquidity] -= _amount;\\n if (liquidityAmount[_job][_liquidity] == 0) {\\n _jobLiquidities[_job].remove(_liquidity);\\n }\\n }\\n\\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\\n if (_timePassed < rewardPeriodTime) {\\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\\n } else _result = _multiplier;\\n }\\n\\n /// @notice Returns the start of the period of the provided timestamp\\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\\n return _timestamp - (_timestamp % rewardPeriodTime);\\n }\\n\\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\\n }\\n\\n /// @notice Returns underlying KP3R amount for a given liquidity amount\\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\\n if (_tick[_liquidity].period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\\n }\\n }\\n\\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\\n /// @dev Ensures a maximum of 1 period of credits\\n function _settleJobAccountance(address _job) internal virtual {\\n _updateJobCreditsIfNeeded(_job);\\n _rewardJobCredits(_job);\\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n}\\n\",\"keccak256\":\"0xe3b244460364baf1ea293db6f6feba8365fd376320ad77ae6d6813ed65b52929\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @inheritdoc IKeep3rJobManager\\n function addJob(address _job) external override {\\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\\n if (hasBonded[_job]) revert AlreadyAKeeper();\\n _jobs.add(_job);\\n jobOwner[_job] = msg.sender;\\n emit JobAddition(_job, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xf6e1577a6a34b674ca34a6d7530dc81349e3ad13d321281c37e0b25b7325d013\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\n\\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n mapping(address => address) public override pendingJobMigrations;\\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\\n if (_fromJob == _toJob) revert JobMigrationImpossible();\\n\\n pendingJobMigrations[_fromJob] = _toJob;\\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\\n\\n emit JobMigrationRequested(_fromJob, _toJob);\\n }\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\\n\\n // force job credits update for both jobs\\n _settleJobAccountance(_fromJob);\\n _settleJobAccountance(_toJob);\\n\\n // migrate tokens\\n while (_jobTokens[_fromJob].length() > 0) {\\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\\n _jobTokens[_fromJob].remove(_tokenToMigrate);\\n _jobTokens[_toJob].add(_tokenToMigrate);\\n }\\n\\n // migrate liquidities\\n while (_jobLiquidities[_fromJob].length() > 0) {\\n address _liquidity = _jobLiquidities[_fromJob].at(0);\\n\\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\\n delete liquidityAmount[_fromJob][_liquidity];\\n\\n _jobLiquidities[_toJob].add(_liquidity);\\n _jobLiquidities[_fromJob].remove(_liquidity);\\n }\\n\\n // migrate job balances\\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\\n delete _jobPeriodCredits[_fromJob];\\n\\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\\n delete _jobLiquidityCredits[_fromJob];\\n\\n // stop _fromJob from being a job\\n delete rewardedAt[_fromJob];\\n _jobs.remove(_fromJob);\\n\\n // delete unused data slots\\n delete jobOwner[_fromJob];\\n delete jobPendingOwner[_fromJob];\\n delete _migrationCreatedAt[_fromJob][_toJob];\\n delete pendingJobMigrations[_fromJob];\\n\\n emit JobMigrationSuccessful(_fromJob, _toJob);\\n }\\n}\\n\",\"keccak256\":\"0xd46c3c9ce970098d8d75f11966894a341824aceb40583fcfbbc0ebda93d869f9\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobPendingOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\\n jobPendingOwner[_job] = _newOwner;\\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\\n }\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\\n address _previousOwner = jobOwner[_job];\\n\\n jobOwner[_job] = jobPendingOwner[_job];\\n delete jobPendingOwner[_job];\\n\\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\\n }\\n\\n modifier onlyJobOwner(address _job) {\\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\\n _;\\n }\\n\\n modifier onlyPendingJobOwner(address _job) {\\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xa837590ade9cd5d25690e3f2d8b9a63e7202f7179b32e42eab4fa4c4324b9728\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobMigration.sol';\\nimport '../../../interfaces/IKeep3rHelper.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n uint256 internal _initialGas;\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\\n _initialGas = _getGasLeft();\\n if (_keepers.contains(_keeper)) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external override returns (bool _isBondedKeeper) {\\n _initialGas = _getGasLeft();\\n if (\\n _keepers.contains(_keeper) &&\\n bonds[_keeper][_bond] >= _minBond &&\\n workCompleted[_keeper] >= _earned &&\\n block.timestamp - firstSeen[_keeper] >= _age\\n ) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function worked(address _keeper) external virtual override {\\n if (_initialGas == 0) revert GasNotInitialized();\\n address _job = msg.sender;\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\\n\\n uint256 _gasLeft = _getGasLeft();\\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n _gasLeft = _getGasLeft();\\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n delete _initialGas;\\n\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function bondedPayment(address _keeper, uint256 _payment) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (disputes[_keeper]) revert Disputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_keeper, _amount);\\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\\n }\\n\\n function _bondedPayment(\\n address _job,\\n address _keeper,\\n uint256 _payment\\n ) internal {\\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\\n\\n workedAt[_job] = block.timestamp;\\n _jobLiquidityCredits[_job] -= _payment;\\n bonds[_keeper][keep3rV1] += _payment;\\n workCompleted[_keeper] += _payment;\\n }\\n\\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\\n /// @param _gasLeft Amount of gas left after working the job\\n /// @param _extraGas Amount of expected unaccounted gas\\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\\n /// @return _payment Amount to be payed in KP3R tokens\\n function _calculatePayment(\\n uint256 _gasLeft,\\n uint256 _extraGas,\\n uint256 _oneEthQuote,\\n uint256 _boost\\n ) internal view returns (uint256 _payment) {\\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\\n }\\n\\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\\n _gasLeft = (gasleft() * 64) / 63;\\n }\\n}\\n\",\"keccak256\":\"0x62a300e427311e067163104171046d2d48fce03fe3e0fa72cc39a92a8132e398\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobManager.sol';\\nimport './Keep3rJobWorkable.sol';\\nimport './Keep3rJobDisputable.sol';\\n\\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\\n\",\"keccak256\":\"0x882e1a19891795de04c4c891dc58d50034ca0a32c8b61651aaf0f47d0bc321d4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rKeeperFundable.sol';\\nimport '../Keep3rDisputable.sol';\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function revoke(address _keeper) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _keepers.remove(_keeper);\\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\\n emit KeeperRevoke(_keeper, msg.sender);\\n }\\n\\n function _slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) internal {\\n if (_bonded != keep3rV1) {\\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\\n }\\n bonds[_keeper][_bonded] -= _bondAmount;\\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\\n }\\n}\\n\",\"keccak256\":\"0xa15b13218af4331d1fb3e8cfdfa9b69117f291ac9a462ede6b1b4fb5be8967de\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\nimport '../../../interfaces/external/IKeep3rV1Proxy.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\\n if (disputes[msg.sender]) revert Disputed();\\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\\n\\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\\n\\n hasBonded[msg.sender] = true;\\n pendingBonds[msg.sender][_bonding] += _amount;\\n\\n emit Bonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function activate(address _bonding) external override {\\n address _keeper = msg.sender;\\n if (disputes[_keeper]) revert Disputed();\\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\\n if (_canActivateAfter == 0) revert BondsUnexistent();\\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\\n\\n if (firstSeen[_keeper] == 0) {\\n firstSeen[_keeper] = block.timestamp;\\n }\\n _keepers.add(_keeper);\\n\\n uint256 _amount = pendingBonds[_keeper][_bonding];\\n delete pendingBonds[_keeper][_bonding];\\n\\n _activate(_keeper, _bonding, _amount);\\n emit Activation(_keeper, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function unbond(address _bonding, uint256 _amount) external override {\\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\\n bonds[msg.sender][_bonding] -= _amount;\\n pendingUnbonds[msg.sender][_bonding] += _amount;\\n\\n emit Unbonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function withdraw(address _bonding) external override nonReentrant {\\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[msg.sender]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\\n\\n delete pendingUnbonds[msg.sender][_bonding];\\n delete canWithdrawAfter[msg.sender][_bonding];\\n\\n if (_bonding == keep3rV1) _mint(_amount);\\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\\n\\n emit Withdrawal(msg.sender, _bonding, _amount);\\n }\\n\\n function _mint(uint256 _amount) internal virtual {\\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\\n }\\n\\n function _activate(\\n address _keeper,\\n address _bonding,\\n uint256 _amount\\n ) internal virtual {\\n // bond provided tokens\\n bonds[_keeper][_bonding] += _amount;\\n if (_bonding == keep3rV1) {\\n IKeep3rV1(keep3rV1).burn(_amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8c5f69de1175d4059adb988929f93cad1d91f1110e72daefd7011be7fd1c4ac5\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\nimport './Keep3rKeeperDisputable.sol';\\n\\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\\n\",\"keccak256\":\"0xfc762d9fd6ff478acba446c3ab6fc19c7d49a85de097dc35f02c56e928153c5e\",\"license\":\"MIT\"},\"solidity/contracts/sidechain/Keep3rSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2003\\u2003\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2003\\u2003\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3r.sol';\\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\\n\\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @param _governance Address of governance\\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\\n constructor(\\n address _governance, // governance\\n address _keep3rHelperSidechain, // helper\\n address _wrappedKP3R, // keep3rV1\\n address _keep3rEscrow // keep3rV1Proxy\\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\\n\\n // Keep3rSidechainAccountance\\n\\n /// @inheritdoc IKeep3rSidechainAccountance\\n uint256 public override totalBonds;\\n\\n /// @inheritdoc IKeep3rSidechainAccountance\\n function virtualReserves() external view override returns (uint256 _virtualReserves) {\\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\\n return IERC20(keep3rV1).balanceOf(keep3rV1Proxy) - totalBonds;\\n }\\n\\n // Keep3rJobFundableLiquidity\\n\\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\\n /// @param _liquidity Address of the liquidity token being approved\\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n emit LiquidityApproval(_liquidity);\\n }\\n\\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\\n /// @param _liquidity Address of the liquidity token being observed\\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\\n if (_tick[_liquidity].period == _period(block.timestamp)) {\\n // Will return cached twaps if liquidity is updated\\n _tickCache = _tick[_liquidity];\\n } else {\\n bool success;\\n\\n // Will always ask for 2 accumulators in sidechain\\n uint32[] memory _secondsAgo = new uint32[](2);\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\\n\\n int56 _tickCumulative2;\\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - _tickCumulative2;\\n\\n if (success) {\\n _tickCache.period = _period(block.timestamp);\\n } else {\\n delete _tickCache.period;\\n }\\n }\\n }\\n\\n // Keep3rJobsWorkable\\n\\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\\n function worked(address) external pure override {\\n revert Deprecated();\\n }\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Uses a USD per gas unit payment mechanism\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\\n if (_initialGas == 0) revert GasNotInitialized();\\n // Gas used for quote calculations & payment is not rewarded\\n uint256 _gasRecord = _getGasLeft();\\n\\n address _job = msg.sender;\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n uint256 _boost = IKeep3rHelper(keep3rHelper).getRewardBoostFor(bonds[_keeper][keep3rV1]);\\n uint256 _ratedPayment = (_usdPerGasUnit * (_initialGas - _gasRecord) * _boost) / _BASE;\\n\\n uint256 _ethPayment = IKeep3rHelperSidechain(keep3rHelper).quoteUsdToEth(_ratedPayment);\\n uint256 _kp3rPayment = IKeep3rHelper(keep3rHelper).quote(_ethPayment);\\n\\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n totalBonds += _kp3rPayment;\\n _bondedPayment(_job, _keeper, _kp3rPayment);\\n delete _initialGas;\\n\\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasRecord);\\n }\\n\\n // Keep3rKeeperFundable\\n\\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\\n function _activate(\\n address _keeper,\\n address _bonding,\\n uint256 _amount\\n ) internal virtual override {\\n // bond provided tokens\\n bonds[_keeper][_bonding] += _amount;\\n if (_bonding == keep3rV1) {\\n totalBonds += _amount;\\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\\n }\\n }\\n\\n function _mint(uint256 _amount) internal virtual override {\\n totalBonds -= _amount;\\n super._mint(_amount);\\n }\\n}\\n\",\"keccak256\":\"0xbc10fb2c0d3087fe3e2e170e469f0d4c87687c61bd12a87e48a6b2fe7fdafaca\",\"license\":\"MIT\"},\"solidity/for-test/testnet/Keep3rSidechainForTestnet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\\n\\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\\n constructor(\\n address _governance,\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\\n bondTime = 0; // allows keepers to instantly register\\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\\n liquidityMinimum = 1; // allows job providers to add low liquidity\\n rewardPeriodTime = 1 days; // reduces twap calculation period\\n inflationPeriod = 5 days; // increases credit mintint\\n }\\n}\\n\",\"keccak256\":\"0xf561208315bacfcbd4d9e8ca7e020b8ed5a4a14ff7510bb78e1a82093dc66ece\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct TokenOraclePool {\\n address poolAddress;\\n bool isTKNToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0x76f99ca04361c0459fc9e99f0387ddb76da18cc470ec5bc744e7dc3bf6e9d334\",\"license\":\"MIT\"},\"solidity/interfaces/IPairManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n/// @title Pair Manager interface\\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\\ninterface IPairManager is IERC20Metadata {\\n /// @notice Address of the factory from which the pair manager was created\\n /// @return _factory The address of the PairManager Factory\\n function factory() external view returns (address _factory);\\n\\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\\n /// @return _pool The address of the pool\\n function pool() external view returns (address _pool);\\n\\n /// @notice Token0 of the pool\\n /// @return _token0 The address of token0\\n function token0() external view returns (address _token0);\\n\\n /// @notice Token1 of the pool\\n /// @return _token1 The address of token1\\n function token1() external view returns (address _token1);\\n}\\n\",\"keccak256\":\"0x345c312b340c5775fb8f68d89ce851c7f75522940bd9bc64f2301a3f8312636a\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IGovernable.sol';\\n\\ninterface IKeep3rV1Proxy is IGovernable {\\n // Structs\\n struct Recipient {\\n address recipient;\\n uint256 caps;\\n }\\n\\n // Variables\\n function keep3rV1() external view returns (address);\\n\\n function minter() external view returns (address);\\n\\n function next(address) external view returns (uint256);\\n\\n function caps(address) external view returns (uint256);\\n\\n function recipients() external view returns (address[] memory);\\n\\n function recipientsCaps() external view returns (Recipient[] memory);\\n\\n // Errors\\n error Cooldown();\\n error NoDrawableAmount();\\n error ZeroAddress();\\n error OnlyMinter();\\n\\n // Methods\\n function addRecipient(address recipient, uint256 amount) external;\\n\\n function removeRecipient(address recipient) external;\\n\\n function draw() external returns (uint256 _amount);\\n\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n function setMinter(address _minter) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function mint(address _account, uint256 _amount) external;\\n\\n function setKeep3rV1Governance(address _governance) external;\\n\\n function acceptKeep3rV1Governance() external;\\n\\n function dispute(address _keeper) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function addJob(address _job) external;\\n\\n function removeJob(address _job) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n}\\n\",\"keccak256\":\"0xfb2e81fe347b39aabce849ef2d42c6df846b7ef0ed5ae952c85bbb708da99408\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0x060f701c6991d323bcf360738568714956013b17b3e3443ea21d825a70c3947c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IMintable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IGovernable.sol';\\nimport './IBaseErrors.sol';\\n\\n/// @title Mintable contract\\n/// @notice Manages the minter role\\ninterface IMintable is IBaseErrors, IGovernable {\\n // Events\\n\\n /// @notice Emitted when governance sets a new minter\\n /// @param _minter Address of the new minter\\n event MinterSet(address _minter);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not the minter\\n error OnlyMinter();\\n\\n // Variables\\n\\n /// @notice Stores the minter address\\n /// @return _minter The minter addresss\\n function minter() external view returns (address _minter);\\n\\n // Methods\\n\\n /// @notice Sets a new address to be the minter\\n /// @param _minter The address set as the minter\\n function setMinter(address _minter) external;\\n}\\n\",\"keccak256\":\"0x255f4ed4b7c4ddf4fcff9db7524365ef734806583acca7c7912e867f110d9c81\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\nimport '../peripherals/IMintable.sol';\\n\\n/// @title Keep3rEscrow contract\\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\\ninterface IKeep3rEscrow is IMintable {\\n /// @notice Emitted when Keep3rEscrow#deposit function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _sender The address that called the function\\n /// @param _amount The amount of wKP3R the user deposited\\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#mint function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _recipient The address that will received the newly minted wKP3R\\n /// @param _amount The amount of wKP3R minted to the recipient\\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\\n /// @param _newWKP3R The address of the wKP3R contract\\n event wKP3RSet(address _newWKP3R);\\n\\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\\n error InsufficientBalance();\\n\\n /// @notice Lists the address of the wKP3R contract\\n /// @return _wKP3RAddress The address of wKP3R\\n function wKP3R() external view returns (address _wKP3RAddress);\\n\\n /// @notice Deposits wKP3R into the contract\\n /// @param _amount The amount of wKP3R to deposit\\n function deposit(uint256 _amount) external;\\n\\n /// @notice mints wKP3R to the recipient\\n /// @param _amount The amount of wKP3R to mint\\n function mint(uint256 _amount) external;\\n\\n /// @notice sets the wKP3R address\\n /// @param _wKP3R the wKP3R address\\n function setWKP3R(address _wKP3R) external;\\n}\\n\",\"keccak256\":\"0xf4796dde1afba7f50805aeae92ac0a4848525aeca8355d9b1c6b36c15cca4322\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../IKeep3rHelper.sol';\\n\\n/// @title Keep3rHelperSidechain contract\\n/// @notice Contains all the helper functions for sidechain keep3r implementations\\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\\n // Events\\n\\n /// @notice The oracle for a liquidity has been saved\\n /// @param _liquidity The address of the given liquidity\\n /// @param _oraclePool The address of the oracle pool\\n event OracleSet(address _liquidity, address _oraclePool);\\n\\n /// @notice Emitted when the WETH USD pool is changed\\n /// @param _address Address of the new WETH USD pool\\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\\n\\n /// Variables\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n /// @return _weth Address of WETH token\\n // solhint-disable func-name-mixedcase\\n function WETH() external view returns (address _weth);\\n\\n /// @return _oracle The address of the observable pool for given liquidity\\n function oracle(address _liquidity) external view returns (address _oracle);\\n\\n /// @notice WETH-USD pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice Quotes USD to ETH\\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\\n /// @param _usd The amount of USD to quote to ETH\\n /// @return _eth The resulting amount of ETH after quoting the USD\\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\\n\\n /// Methods\\n\\n /// @notice Sets an oracle for a given liquidity\\n /// @param _liquidity The address of the liquidity\\n /// @param _oracle The address of the pool used to quote the liquidity from\\n /// @dev The oracle must contain KP3R as either token0 or token1\\n function setOracle(address _liquidity, address _oracle) external;\\n\\n /// @notice Sets an oracle for querying WETH/USD quote\\n /// @param _poolAddress The address of the pool used as oracle\\n /// @dev The oracle must contain WETH as either token0 or token1\\n function setWethUsdPool(address _poolAddress) external;\\n}\\n\",\"keccak256\":\"0xb6d5459e8a47ab09a052e1acac1c28304f9f0762d20f01819559b4d39729c987\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IKeep3rJobs.sol';\\n\\n/// @title Keep3rJobWorkableRated contract\\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\\n /// @notice Throws when job contract calls deprecated worked(address) function\\n error Deprecated();\\n\\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\\n}\\n\",\"keccak256\":\"0xce2c2721f1df7d944bf3ae20331cb628d38247e667c47bf4a33a90f0b5753884\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title IKeep3rSidechainAccountance interface\\n/// @notice Implements a view to get the amount of credits that can be withdrawn\\ninterface IKeep3rSidechainAccountance {\\n /// @return _totalBonds The total amount of bonded wKP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\\n function virtualReserves() external view returns (uint256 _virtualReserves);\\n}\\n\",\"keccak256\":\"0xd797a7e26ab56cec9204c1801652563973e63c549138d3572cf6dd38e03f49cd\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040526203f480601e5562127500601f556729a2241af62c000060205562069780602155622cd300602255601e6023553480156200003e57600080fd5b50604051620060c0380380620060c0833981016040819052620000619162000133565b6001600055838383838383838382828286806001600160a01b0381166200009a5760405162b293ed60e81b815260040160405180910390fd5b600380546001600160a01b03199081166001600160a01b0393841617909155601d8054821696831696909617909555601b805486169482169490941790935550601c8054909316911617905550506000601e819055601f5550506001602055505062015180602155505062069780602255506200019092505050565b80516001600160a01b03811681146200012e57600080fd5b919050565b600080600080608085870312156200014a57600080fd5b620001558562000116565b9350620001656020860162000116565b9250620001756040860162000116565b9150620001856060860162000116565b905092959194509250565b615f2080620001a06000396000f3fe608060405234801561001057600080fd5b50600436106104075760003560e01c8063966abd0011610228578063c5198abc1161013c578063ec8ca643116100be578063ec8ca64314610add578063f0f346b914610b06578063f11a1d1a14610b19578063f136a09d14610b2c578063f25e311b14610b4c578063f263c47014610b5f578063f39c38a014610b68578063f75f9f7b14610b7b578063f9d46cf214610b8e578063fc253d2b14610ba1578063fe75bc4614610baa57600080fd5b8063c5198abc146109f1578063c7ae40d014610a04578063cb4be2bb14610a17578063cb54694d14610a2a578063cd22af1b14610a3d578063d55995fe14610a68578063dd2080d614610a7b578063ddca3f4314610a8e578063e326ac4314610a97578063ebbb619414610ab7578063ec00cdfc14610aca57600080fd5b8063966abd001461080457806398e90a0f146108175780639d5c33d814610840578063a214580914610853578063a39744b514610866578063a515366a14610891578063a5d059ca146108a4578063a676f9ff146108b7578063a7d2e784146108d7578063aac6aa9c146108e0578063ab033ea9146108f3578063af320e8114610906578063b0103b1a14610919578063b0f328f11461093c578063b239223314610944578063b440027f14610957578063b600702a14610982578063b70362b914610995578063b7e77340146109a8578063b87fcbff146109bb578063c20297f0146109de57600080fd5b80635aa6e6751161031f5780635aa6e6751461066b5780635ebe23f01461067e5780635feeb79414610687578063633fb68f1461069a57806364bb43ee146106a357806368a9f19c146106b6578063694798e6146106c957806369fe0e2d146106f45780636ba42aaa146107075780636cf262bc1461071a5780636e2a9ca61461072d57806372da828a1461074057806374a8f10314610753578063768b5d90146107665780637c8fce231461076f578063878c723e146107775780638bb6dfa8146107a05780638cb22b76146107b35780638fe204dd146107d657806390a4684e146107e9578063951dc22c146107fc57600080fd5b8063034d4c611461040c57806307b435c2146104325780630c620bce1461045d5780630d6a1f87146104725780631101eb411461048557806311466d721461049a57806315006b82146104ad578063165e62e7146104d8578063168f92e7146105155780631b44555e146105405780631c5a9d9c146105605780631ef94b911461057357806321040b0114610593578063238efcbc146105be578063274a8db4146105c657806351cff8d9146105f957806352a4de291461060c57806355ea6c471461061f578063575288bf14610632578063594a3a931461064557806359a2255e14610658575b600080fd5b61041f61041a3660046158a2565b610bbd565b6040519081526020015b60405180910390f35b61041f6104403660046158dc565b601660209081526000928352604080842090915290825290205481565b610465610cc3565b6040516104299190615c23565b61041f610480366004615a8b565b610cd4565b610498610493366004615960565b610dda565b005b6104986104a8366004615a8b565b610f34565b61041f6104bb3660046158dc565b601460209081526000928352604080842090915290825290205481565b6104eb6104e63660046158a2565b6110c3565b604080518251600690810b825260208085015190910b908201529181015190820152606001610429565b61041f6105233660046158dc565b600d60209081526000928352604080842090915290825290205481565b61041f61054e3660046158a2565b60096020526000908152604090205481565b61049861056e3660046158a2565b6112f0565b601b54610586906001600160a01b031681565b6040516104299190615b9a565b61041f6105a13660046158dc565b601760209081526000928352604080842090915290825290205481565b610498611454565b6105e96105d43660046158a2565b60066020526000908152604090205460ff1681565b6040519015158152602001610429565b6104986106073660046158a2565b6114e0565b61049861061a366004615960565b611678565b61049861062d3660046158a2565b6118aa565b610498610640366004615960565b61195e565b6104986106533660046158dc565b611c21565b6104986106663660046158a2565b611cc6565b600354610586906001600160a01b031681565b61041f601e5481565b6104986106953660046158a2565b611d78565b61041f60205481565b6104986106b13660046158a2565b611d91565b6104986106c43660046158a2565b611e72565b61041f6106d73660046158dc565b602760209081526000928352604080842090915290825290205481565b610498610702366004615b4c565b611f51565b6105e96107153660046158a2565b611fb1565b61041f6107283660046158a2565b612011565b61049861073b366004615960565b612147565b61049861074e3660046158a2565b612296565b6104986107613660046158a2565b612333565b61041f60215481565b61046561242e565b6105866107853660046158a2565b6001602052600090815260409020546001600160a01b031681565b61041f6107ae3660046158a2565b61243a565b6105e96107c13660046158a2565b60186020526000908152604090205460ff1681565b6104986107e4366004615b4c565b6124dd565b6104986107f73660046158dc565b61253d565b61046561262b565b610498610812366004615ab7565b612637565b6105866108253660046158a2565b6002602052600090815260409020546001600160a01b031681565b61049861084e3660046158a2565b61274d565b610498610861366004615915565b61282c565b61041f6108743660046158dc565b600c60209081526000928352604080842090915290825290205481565b61049861089f366004615a8b565b6129fc565b6104986108b2366004615a8b565b612c5d565b61041f6108c53660046158a2565b60286020526000908152604090205481565b61041f601f5481565b6104986108ee3660046158a2565b612d37565b6104986109013660046158a2565b612deb565b6104986109143660046158dc565b612e61565b6105e96109273660046158a2565b600b6020526000908152604090205460ff1681565b61041f6132e0565b610498610952366004615b4c565b613376565b61041f6109653660046158dc565b602460209081526000928352604080842090915290825290205481565b6104986109903660046158a2565b6133d6565b6104986109a3366004615a8b565b613644565b6104986109b6366004615b4c565b6139fa565b6105e96109c93660046158a2565b60056020526000908152604090205460ff1681565b6104986109ec3660046159f4565b613a5a565b6104986109ff3660046158a2565b613b13565b601c54610586906001600160a01b031681565b610498610a253660046158a2565b613bd9565b610498610a38366004615b4c565b613c76565b61041f610a4b3660046158dc565b601560209081526000928352604080842090915290825290205481565b610498610a763660046159a1565b613cfa565b610498610a89366004615960565b613f31565b61041f60235481565b61041f610aa53660046158a2565b600a6020526000908152604090205481565b610498610ac5366004615b4c565b6140ae565b610498610ad83660046158a2565b61410c565b610586610aeb3660046158a2565b602b602052600090815260409020546001600160a01b031681565b610498610b143660046158a2565b6141a9565b601d54610586906001600160a01b031681565b61041f610b3a3660046158a2565b60296020526000908152604090205481565b610498610b5a366004615960565b61425d565b61041f602e5481565b600454610586906001600160a01b031681565b610498610b893660046158a2565b6144a2565b6105e9610b9c366004615a3a565b61455a565b61041f60225481565b610498610bb8366004615a8b565b614643565b600080610bc983612011565b6021549091504290610be490610bdf9083615da4565b614733565b6001600160a01b0385166000908152602860205260409020541115610c88576021546001600160a01b038516600090815260286020526040902054610c299042615da4565b10610c65576021546001600160a01b038516600090815260286020526040902054610c549190615d09565b610c5e9082615da4565b9050610c9e565b6001600160a01b038416600090815260286020526040902054610c5e9082615da4565b610c9142614733565b610c9b9082615da4565b90505b610ca8818361474d565b610cb18561243a565b610cbb9190615d09565b949350505050565b6060610ccf6025614777565b905090565b6000610ce160258461478b565b15610dd4576000610cf1846110c3565b90508060400151600014610dd2576001600160a01b03841660009081526013602052604081205460ff16610d32578160200151610d2d90615e16565b610d38565b81602001515b601d5460215460405163a0d2710760e01b8152929350610dc9926001600160a01b039092169163a0d2710791610d749189918791600401615cda565b60206040518083038186803b158015610d8c57600080fd5b505afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190615b65565b6147ad565b92505050610dd4565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610e1657604051636efb4f4160e11b815260040160405180910390fd5b601f54610e239042615d09565b6001600160a01b03808616600081815260166020908152604080832094891680845294825280832095909555918152601782528381209281529190529081208054849290610e72908490615d09565b90915550610e8390508484846147be565b6001600160a01b038085166000908152602760209081526040808320938716835292905220548015801590610ec25750602054610ec082866149cc565b105b15610ee057604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de85604051610f2591815260200190565b60405180910390a35050505050565b336000818152600b602052604090205460ff1615610f655760405163ad2fdf3b60e01b815260040160405180910390fd5b610f7060198261478b565b610f8c5760405162941a5760e11b815260040160405180910390fd5b610f9581614aea565b15610ff0576001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615ecb83398151915293610fe79390929091615cf3565b60405180910390a25b6001600160a01b0381166000908152600e602052604090205482111561106f5761101981614cc0565b6001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615ecb833981519152936110669390929091615cf3565b60405180910390a25b61107a818484614d4e565b601b546001600160a01b03808516918382169116600080516020615eab833981519152856110a6614e32565b6040805192835260208301919091520160405180910390a4505050565b60408051606081018252600080825260208201819052918101919091526110e942614733565b6001600160a01b0383166000908152602a6020526040902060010154141561115f57506001600160a01b03166000908152602a602090815260409182902082516060810184528154600681810b810b810b8352600160381b909104810b810b900b92810192909252600101549181019190915290565b6040805160028082526060820183526000928392919060208301908036833701905050905061118d42614733565b6111979042615da4565b816000815181106111aa576111aa615e7f565b602002602001019063ffffffff16908163ffffffff16815250506021546111d042614733565b6111da9042615da4565b6111e49190615d09565b816001815181106111f7576111f7615e7f565b63ffffffff909216602092830291909101820152601d546001600160a01b0386811660009081526012909352604080842054905163dc686d9160e01b81529282169263dc686d919261124f9216908690600401615bae565b60606040518083038186803b15801561126757600080fd5b505afa15801561127b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129f9190615b09565b600692830b90920b80875291945091506112ba908290615d54565b600690810b900b602085015282156112df576112d542614733565b60408501526112e7565b600060408501525b5050505b919050565b336000818152600b602052604090205460ff1615611321576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b038082166000908152601560209081526040808320938616835292905220548061136557604051636258f48160e01b815260040160405180910390fd5b42811061138557604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600a60205260409020546113be576001600160a01b0382166000908152600a602052604090204290555b6113c9600783614e4c565b506001600160a01b03828116600090815260146020908152604080832093871683529290529081208054919055611401838583614e61565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a758360405161144691815260200190565b60405180910390a350505050565b6004546001600160a01b0316331461147f57604051637ef5703160e11b815260040160405180910390fd5b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b6916114d691615b9a565b60405180910390a1565b6002600054141561150c5760405162461bcd60e51b815260040161150390615ca3565b60405180910390fd5b600260009081553381526017602090815260408083206001600160a01b03851684529091529020546115515760405163184c088160e21b815260040160405180910390fd5b3360009081526016602090815260408083206001600160a01b03851684529091529020544211611594576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600b602052604090205460ff16156115c5576040516362e6201d60e01b815260040160405180910390fd5b3360008181526017602090815260408083206001600160a01b038681168086529184528285208054908690559585526016845282852082865290935290832092909255601b5416141561161b5761161b81614fb7565b61162f6001600160a01b0383163383614fdb565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b6002600054141561169b5760405162461bcd60e51b815260040161150390615ca3565b60026000556116ab60258361478b565b6116c85760405163e0b6aead60e01b815260040160405180910390fd5b6116d360198461478b565b6116f057604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526011602052604090206117129083614e4c565b5061171c83615031565b602080546001600160a01b0380861660009081526027845260408082209287168252919093529091205461175b90611755908490615d09565b846149cc565b101561177a57604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615ecb833981519152936117c79390929091615cf3565b60405180910390a26117e46001600160a01b03831633308461508f565b6001600160a01b0380841660009081526027602090815260408083209386168352929052908120805483929061181b908490615d09565b9091555061182e9050610dc482846149cc565b6001600160a01b0384166000908152600f602052604081208054909190611856908490615d09565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff166118da57604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff16611913576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600b6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b600260005414156119815760405162461bcd60e51b815260040161150390615ca3565b600260005561199160198461478b565b6119ae57604051636211d34960e01b815260040160405180910390fd5b601b546001600160a01b03838116911614156119dc5760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038416906370a0823190611a0b903090600401615b9a565b60206040518083038186803b158015611a2357600080fd5b505afa158015611a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5b9190615b65565b9050611a726001600160a01b03841633308561508f565b600081846001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611aa19190615b9a565b60206040518083038186803b158015611ab957600080fd5b505afa158015611acd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af19190615b65565b611afb9190615da4565b9050600061271060235483611b109190615d35565b611b1a9190615d21565b9050611b268183615da4565b6001600160a01b038088166000908152600d60209081526040808320938a1683529290529081208054909190611b5d908490615d09565b90915550506001600160a01b0380871660009081526024602090815260408083208985168085529252909120429055600354611b9a921683614fdb565b6001600160a01b0386166000908152601060205260409020611bbc9086614e4c565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611c0c91815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611c5d57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611d025760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b6040516331cee75f60e21b815260040160405180910390fd5b6003546001600160a01b03163314611dbc576040516354348f0360e01b815260040160405180910390fd5b611dc76025826150cd565b611de457604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600090815260126020908152604080832080546001600160a01b031916905560138252808320805460ff19169055602a90915280822080546001600160701b031916815560010191909155517f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e5690611e67908390615b9a565b60405180910390a150565b6003546001600160a01b03163314611e9d576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116611ec45760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff1615611efe5760405163546da66560e11b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b90611e67908390615b9a565b6003546001600160a01b03163314611f7c576040516354348f0360e01b815260040160405180910390fd5b60238190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d90602001611e67565b6000611fbb614e32565b602d55611fc960078361478b565b156112eb577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602d5460405161200191815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b0383166000908152601160205260409020612036906150e2565b811015612141576001600160a01b038316600090815260116020526040812061205f90836150ec565b905061206c60258261478b565b1561212e57600061207c826110c3565b9050806040015160001461212c576001600160a01b03821660009081526013602052604081205460ff166120bd5781602001516120b890615e16565b6120c3565b81602001515b601d546001600160a01b03888116600090815260276020908152604080832089851684529091529081902054602154915163a0d2710760e01b815294955061211e94929093169263a0d2710792610d74928791600401615cda565b6121289086615d09565b9450505b505b508061213981615de7565b915050612015565b50919050565b3360009081526005602052604090205460ff1661217757604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff166121b0576040516310cec38560e21b815260040160405180910390fd5b6121bb8383836147be565b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb926121ef92909116908590600401615c0a565b602060405180830381600087803b15801561220957600080fd5b505af1925050508015612239575060408051601f3d908101601f1916820190925261223691810190615aee565b60015b61224257612244565b505b336001600160a01b0316836001600160a01b03167f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e8484604051612289929190615c0a565b60405180910390a3505050565b6003546001600160a01b031633146122c1576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166122e85760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383161790556040517f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b090611e67908390615b9a565b3360009081526005602052604090205460ff1661236357604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff1661239c576040516310cec38560e21b815260040160405180910390fd5b6123a76007826150cd565b50601b546001600160a01b038083166000818152600c60209081526040808320949095168083529381528482205492825260178152848220848352905292909220546123f5928492916150f8565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610ccf6019614777565b60008061244683612011565b6021546001600160a01b038516600090815260286020526040902054919250906124709042615da4565b1015610dd4576000811161249c576001600160a01b0383166000908152600e60205260409020546124d6565b6001600160a01b0383166000908152600f6020908152604080832054600e909252909120546124cc908390615d35565b6124d69190615d21565b9150612141565b6003546001600160a01b03163314612508576040516354348f0360e01b815260040160405180910390fd5b601f8190556040518181527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee290602001611e67565b6001600160a01b03828116600090815260016020526040902054839116331461257957604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156125ac5760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602b6020908152604080832080546001600160a01b0319169588169586179055602c825280832094835293905282902042905590517fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c9061261e908590615b9a565b60405180910390a2505050565b6060610ccf6007614777565b6003546001600160a01b03163314612662576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166126895760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156126ea576040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156126e4573d6000803e3d6000fd5b506126fe565b6126fe6001600160a01b0384168284614fdb565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b03163314612778576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661279f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff16156127d95760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19166001179055517f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f90611e67908390615b9a565b6001600160a01b03838116600090815260016020526040902054849116331461286857604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03821661288f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038085166000908152601760209081526040808320938716835292905220546128d25760405163184c088160e21b815260040160405180910390fd5b6001600160a01b038085166000908152601660209081526040808320938716835292905220544211612917576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600b602052604090205460ff1615612951576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b038085166000818152601760209081526040808320948816808452948252808320805490849055938352601682528083208584529091528120559061299e908483614fdb565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca7928862846040516129ed91815260200190565b60405180910390a45050505050565b60026000541415612a1f5760405162461bcd60e51b815260040161150390615ca3565b60026000908155338152600b602052604090205460ff1615612a54576040516362e6201d60e01b815260040160405180910390fd5b612a5f60193361478b565b15612a7d5760405163d7229c4360e01b815260040160405180910390fd5b601e54612a8a9042615d09565b3360009081526015602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81529091906370a0823190612ad5903090600401615b9a565b60206040518083038186803b158015612aed57600080fd5b505afa158015612b01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b259190615b65565b9050612b3c6001600160a01b03841633308561508f565b6040516370a0823160e01b815281906001600160a01b038516906370a0823190612b6a903090600401615b9a565b60206040518083038186803b158015612b8257600080fd5b505afa158015612b96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bba9190615b65565b612bc49190615da4565b336000908152601860209081526040808320805460ff19166001179055601482528083206001600160a01b0388168452909152812080549294508492909190612c0e908490615d09565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b601f54612c6a9042615d09565b3360008181526016602090815260408083206001600160a01b03881680855290835281842095909555928252600c81528282209382529290925281208054839290612cb6908490615da4565b90915550503360009081526017602090815260408083206001600160a01b038616845290915281208054839290612cee908490615d09565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b03163314612d62576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16612d9b576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19169055517f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d02590611e67908390615b9a565b6003546001600160a01b03163314612e16576040516354348f0360e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90611e67908390615b9a565b6001600160a01b038181166000908152600160205260409020548291163314612e9d57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff1680612edc57506001600160a01b0382166000908152600b602052604090205460ff165b15612efa5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602b6020526040902054811690831614612f3757604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602c6020908152604080832093861683529290522054612f6990603c90615d09565b421015612f89576040516356248e9760e01b815260040160405180910390fd5b612f9283615031565b612f9b82615031565b6001600160a01b0383166000908152601060205260408120612fbc906150e2565b111561309e576001600160a01b0383166000908152601060205260408120612fe490826150ec565b6001600160a01b038086166000908152600d6020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613032908490615d09565b90915550506001600160a01b038085166000818152600d60209081526040808320948616835293815283822082905591815260109091522061307490826150cd565b506001600160a01b03831660009081526010602052604090206130979082614e4c565b5050612f9b565b6001600160a01b03831660009081526011602052604081206130bf906150e2565b11156131a1576001600160a01b03831660009081526011602052604081206130e790826150ec565b6001600160a01b03808616600090815260276020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613135908490615d09565b90915550506001600160a01b03808516600090815260276020908152604080832085851684528252808320839055928616825260119052206131779082614e4c565b506001600160a01b038416600090815260116020526040902061319a90826150cd565b505061309e565b6001600160a01b038084166000908152600f6020526040808220549285168252812080549091906131d3908490615d09565b90915550506001600160a01b038084166000908152600f60209081526040808320839055600e90915280822054928516825281208054909190613217908490615d09565b90915550506001600160a01b0383166000908152600e60209081526040808320839055602890915281205561324d6019846150cd565b506001600160a01b03808416600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602c8352818420958816808552958352818420849055938352602b909152908190208054909216909155517f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f29061261e908690615b9a565b602e54601b54601c546040516370a0823160e01b8152600093926001600160a01b03908116926370a082319261331c9290911690600401615b9a565b60206040518083038186803b15801561333457600080fd5b505afa158015613348573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336c9190615b65565b610ccf9190615da4565b6003546001600160a01b031633146133a1576040516354348f0360e01b815260040160405180910390fd5b60228190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb6990602001611e67565b6003546001600160a01b03163314613401576040516354348f0360e01b815260040160405180910390fd5b61340c602582614e4c565b6134295760405163f25e6b9f60e01b815260040160405180910390fd5b601d5460405163eb37d34960e01b81526001600160a01b039091169063eb37d34990613459908490600401615b9a565b60206040518083038186803b15801561347157600080fd5b505afa158015613485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a991906158bf565b6001600160a01b03828116600090815260126020526040902080546001600160a01b0319169290911691821790556134f45760405163d92e233d60e01b815260040160405180910390fd5b601d546001600160a01b038281166000908152601260205260409081902054905163696a437b60e01b81529282169263696a437b92613537921690600401615b9a565b60206040518083038186803b15801561354f57600080fd5b505afa158015613563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135879190615aee565b6001600160a01b0382166000908152601360205260409020805460ff19169115159190911790556135b7816110c3565b6001600160a01b0382166000908152602a60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b161791909117815591810151600190920191909155517fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b90611e67908390615b9a565b602d5461366457604051630262ab9b60e61b815260040160405180910390fd5b600061366e614e32565b336000818152600b60205260409020549192509060ff16156136a35760405163ad2fdf3b60e01b815260040160405180910390fd5b6136ae60198261478b565b6136ca5760405162941a5760e11b815260040160405180910390fd5b6136d381614aea565b1561372e576001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615ecb833981519152936137259390929091615cf3565b60405180910390a25b601d546001600160a01b038581166000908152600c60209081526040808320601b548516845290915280822054905163516c332360e01b815260048101919091529092919091169063516c33239060240160206040518083038186803b15801561379757600080fd5b505afa1580156137ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cf9190615b65565b905060006127108285602d546137e59190615da4565b6137ef9088615d35565b6137f99190615d35565b6138039190615d21565b601d54604051633b67c3bd60e01b8152600481018390529192506000916001600160a01b0390911690633b67c3bd90602401602060405180830381600087803b15801561384f57600080fd5b505af1158015613863573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138879190615b65565b601d54604051633b46f5db60e21b8152600481018390529192506000916001600160a01b039091169063ed1bd76c9060240160206040518083038186803b1580156138d157600080fd5b505afa1580156138e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139099190615b65565b6001600160a01b0386166000908152600e602052604090205490915081111561398b5761393585614cc0565b6001600160a01b038516600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615ecb833981519152936139829390929091615cf3565b60405180910390a25b80602e600082825461399d9190615d09565b909155506139ae9050858983614d4e565b6000602d55601b5460408051838152602081018990526001600160a01b038b81169389821693911691600080516020615eab833981519152910160405180910390a45050505050505050565b6003546001600160a01b03163314613a25576040516354348f0360e01b815260040160405180910390fd5b601e8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b4390602001611e67565b3360009081526005602052604090205460ff16613a8a57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600b602052604090205460ff16613ac3576040516310cec38560e21b815260040160405180910390fd5b613acf848484846150f8565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613b058486615d09565b604051908152602001611446565b613b1e60198261478b565b15613b3c57604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526018602052604090205460ff1615613b7657604051632f3d320560e01b815260040160405180910390fd5b613b81601982614e4c565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613c04576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116613c2b5760405163d92e233d60e01b815260040160405180910390fd5b601c80546001600160a01b0319166001600160a01b0383161790556040517feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae25090611e67908390615b9a565b6003546001600160a01b03163314613ca1576040516354348f0360e01b815260040160405180910390fd5b62015180811015613cc557604051633f384aad60e21b815260040160405180910390fd5b60218190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d990602001611e67565b60026000541415613d1d5760405162461bcd60e51b815260040161150390615ca3565b600260009081556001600160a01b03858116825260016020526040909120548591163314613d5e57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260246020908152604080832093881683529290522054613d9090603c90615d09565b4211613daf57604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600d6020908152604080832093881683529290522054831115613df55760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600b602052604090205460ff1615613e2f5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600d6020908152604080832093881683529290529081208054859290613e66908490615da4565b90915550613e8090506001600160a01b0385168385614fdb565b6001600160a01b038086166000908152600d6020908152604080832093881683529290522054613ece576001600160a01b0385166000908152601060205260409020613ecc90856150cd565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613f1d91815260200190565b60405180910390a450506001600055505050565b336000818152600b602052604090205460ff1615613f625760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff1615613f9c576040516362e6201d60e01b815260040160405180910390fd5b613fa760198261478b565b613fc35760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600d60209081526040808320938816835292905220548211156140095760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600d6020908152604080832093881683529290529081208054849290614040908490615da4565b9091555061405a90506001600160a01b0385168484614fdb565b826001600160a01b0316816001600160a01b0316856001600160a01b0316600080516020615eab83398151915285614090614e32565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b031633146140d9576040516354348f0360e01b815260040160405180910390fd5b60208181556040518281527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e79101611e67565b6003546001600160a01b03163314614137576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661415e5760405163d92e233d60e01b815260040160405180910390fd5b601b80546001600160a01b0319166001600160a01b0383161790556040517f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf90611e67908390615b9a565b6003546001600160a01b031633146141d4576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1661420d57604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19169055517f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e90611e67908390615b9a565b3360009081526005602052604090205460ff1661428d57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff166142c6576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b03831660009081526010602052604090206142e8908361478b565b61430557604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600d602090815260408083209386168352929052205481111561434a5760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261437e92909116908590600401615c0a565b602060405180830381600087803b15801561439857600080fd5b505af19250505080156143c8575060408051601f3d908101601f191682019092526143c591810190615aee565b60015b6143d1576143d3565b505b6001600160a01b038084166000908152600d602090815260408083209386168352929052908120805483929061440a908490615da4565b90915550506001600160a01b038084166000908152600d602090815260408083209386168352929052205461445d576001600160a01b038316600090815260106020526040902061445b90836150cd565b505b336001600160a01b0316836001600160a01b03167f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d3183331048484604051612289929190615c0a565b3360009081526006602052604090205460ff166144d257604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff161561450c576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600b6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b6000614564614e32565b602d5561457260078761478b565b80156145a357506001600160a01b038087166000908152600c60209081526040808320938916835292905220548411155b80156145c757506001600160a01b0386166000908152600960205260409020548311155b80156145f657506001600160a01b0386166000908152600a602052604090205482906145f39042615da4565b10155b1561463a577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602d5460405161462e91815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b0316331461466e576040516354348f0360e01b815260040160405180910390fd5b61467960198361478b565b61469657604051636211d34960e01b815260040160405180910390fd5b61469f82615031565b6001600160a01b0382166000908152600e6020526040812080548392906146c7908490615d09565b90915550506001600160a01b038216600081815260286020908152604080832054600e909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d192614727928252602082015260400190565b60405180910390a25050565b6000602154826147439190615e02565b610dd49083615da4565b6000602154831015612141576021546147668385615d35565b6147709190615d21565b9050610dd4565b606060006147848361524e565b9392505050565b6001600160a01b03811660009081526001830160205260408120541515614784565b6000610dd4826021546022546152aa565b600260005414156147e15760405162461bcd60e51b815260040161150390615ca3565b600260009081556001600160a01b0384168152601160205260409020614807908361478b565b614823576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b038084166000908152602760209081526040808320938616835292905220548111156148695760405163435b562560e01b815260040160405180910390fd5b61487283615358565b6000614881610dc483856149cc565b6001600160a01b0385166000908152600f602052604090205490915015614937576001600160a01b0384166000908152600f6020908152604080832054600e909252909120546148d2908390615d35565b6148dc9190615d21565b6001600160a01b0385166000908152600e602052604081208054909190614904908490615da4565b90915550506001600160a01b0384166000908152600f602052604081208054839290614931908490615da4565b90915550505b6001600160a01b0380851660009081526027602090815260408083209387168352929052908120805484929061496e908490615da4565b90915550506001600160a01b038085166000908152602760209081526040808320938716835292905220546149c1576001600160a01b03841660009081526011602052604090206149bf90846150cd565b505b505060016000555050565b6001600160a01b0381166000908152602a602052604081206001015415610dd4576001600160a01b03821660009081526013602052604081205460ff16614a3e576001600160a01b0383166000908152602a6020526040902054614a3990600160381b900460060b615e16565b614a62565b6001600160a01b0383166000908152602a6020526040902054600160381b900460060b5b601d5460215460405163a0d2710760e01b81529293506001600160a01b039091169163a0d2710791614a9a9188918691600401615cda565b60206040518083038186803b158015614ab257600080fd5b505afa158015614ac6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbb9190615b65565b6000614af542614733565b6001600160a01b03831660009081526028602052604090205410156112eb57614b2560215442610bdf9190615da4565b6001600160a01b03831660009081526028602052604090205411614b9b57614b4c82615358565b6001600160a01b0382166000908152600f6020908152604080832054600e90925290912055614b7a42614733565b6001600160a01b038316600090815260286020526040902055506001919050565b6021546001600160a01b038316600090815260286020526040902054614bc19042615da4565b10614c1d57614bcf82615358565b6001600160a01b0382166000908152600f6020908152604080832054600e83528184205560215460289092528220805491929091614c0e908490615d09565b90915550600191506112eb9050565b614c2642614733565b6001600160a01b03831660009081526029602052604090205410156112eb576001600160a01b0382166000908152600f6020526040902054614c6783615358565b6001600160a01b0383166000908152600f6020908152604080832054600e909252909120548291614c9791615d35565b614ca19190615d21565b6001600160a01b0384166000908152600e602052604090205550919050565b6001600160a01b038116600090815260286020526040902054614d0590614ce79042615da4565b6001600160a01b0383166000908152600f602052604090205461474d565b6001600160a01b0382166000908152600e602052604081208054909190614d2d908490615d09565b90915550506001600160a01b03166000908152602860205260409020429055565b6001600160a01b0383166000908152600e6020526040902054811115614d875760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602960209081526040808320429055600e90915281208054839290614dbc908490615da4565b90915550506001600160a01b038083166000908152600c60209081526040808320601b5490941683529290529081208054839290614dfb908490615d09565b90915550506001600160a01b03821660009081526009602052604081208054839290614e28908490615d09565b9091555050505050565b6000603f5a614e42906040615d35565b610ccf9190615d21565b6000614784836001600160a01b03841661537d565b6001600160a01b038084166000908152600c6020908152604080832093861683529290529081208054839290614e98908490615d09565b9091555050601b546001600160a01b0383811691161415614fb25780602e6000828254614ec59190615d09565b9091555050601b54601c5460405163095ea7b360e01b81526001600160a01b039283169263095ea7b392614f00929116908590600401615c0a565b602060405180830381600087803b158015614f1a57600080fd5b505af1158015614f2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f529190615aee565b50601c5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f2590602401600060405180830381600087803b158015614f9957600080fd5b505af1158015614fad573d6000803e3d6000fd5b505050505b505050565b80602e6000828254614fc99190615da4565b90915550614fd89050816153cc565b50565b614fb28363a9059cbb60e01b8484604051602401614ffa929190615c0a565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261542d565b61503a81614aea565b5061504481614cc0565b6001600160a01b0381166000908152600e6020908152604080832054600f9092529091205461507391906154ff565b6001600160a01b039091166000908152600e6020526040902055565b6040516001600160a01b03808516602483015283166044820152606481018290526150c79085906323b872dd60e01b90608401614ffa565b50505050565b6000614784836001600160a01b038416615515565b6000610dd4825490565b60006147848383615608565b601b546001600160a01b038481169116146151d0576003546001600160a01b038085169163a9059cbb911661512d8486615d09565b6040518363ffffffff1660e01b815260040161514a929190615c0a565b602060405180830381600087803b15801561516457600080fd5b505af1925050508015615194575060408051601f3d908101601f1916820190925261519191810190615aee565b60015b6151ce573d8080156151c2576040519150601f19603f3d011682016040523d82523d6000602084013e6151c7565b606091505b50506151d0565b505b6001600160a01b038085166000908152600c6020908152604080832093871683529290529081208054849290615207908490615da4565b90915550506001600160a01b03808516600090815260176020908152604080832093871683529290529081208054839290615243908490615da4565b909155505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561529e57602002820191906000526020600020905b81548152602001906001019080831161528a575b50505050509050919050565b6000808060001985870985870292508281108382030391505080600014156152e457600084116152d957600080fd5b508290049050614784565b8084116152f057600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b61536181615632565b6001600160a01b039091166000908152600f6020526040902055565b60008181526001830160205260408120546153c457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610dd4565b506000610dd4565b601c5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401600060405180830381600087803b15801561541257600080fd5b505af1158015615426573d6000803e3d6000fd5b5050505050565b6000615482826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166157759092919063ffffffff16565b805190915015614fb257808060200190518101906154a09190615aee565b614fb25760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611503565b600081831061550e5781614784565b5090919050565b600081815260018301602052604081205480156155fe576000615539600183615da4565b855490915060009061554d90600190615da4565b90508181146155b257600086600001828154811061556d5761556d615e7f565b906000526020600020015490508087600001848154811061559057615590615e7f565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806155c3576155c3615e69565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610dd4565b6000915050610dd4565b600082600001828154811061561f5761561f615e7f565b9060005260206000200154905092915050565b6000805b6001600160a01b0383166000908152601160205260409020615657906150e2565b811015612141576001600160a01b038316600090815260116020526040812061568090836150ec565b905061568d60258261478b565b156157625761569b42614733565b6001600160a01b0382166000908152602a602052604090206001015414615721576156c5816110c3565b6001600160a01b0382166000908152602a60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b16179190911781559101516001909101555b6001600160a01b0380851660009081526027602090815260408083209385168352929052205461575590610dc490836149cc565b61575f9084615d09565b92505b508061576d81615de7565b915050615636565b6060610cbb848460008585843b6157ce5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611503565b600080866001600160a01b031685876040516157ea9190615b7e565b60006040518083038185875af1925050503d8060008114615827576040519150601f19603f3d011682016040523d82523d6000602084013e61582c565b606091505b509150915061583c828286615847565b979650505050505050565b60608315615856575081614784565b8251156158665782518084602001fd5b8160405162461bcd60e51b81526004016115039190615c70565b805180151581146112eb57600080fd5b8051600681900b81146112eb57600080fd5b6000602082840312156158b457600080fd5b813561478481615e95565b6000602082840312156158d157600080fd5b815161478481615e95565b600080604083850312156158ef57600080fd5b82356158fa81615e95565b9150602083013561590a81615e95565b809150509250929050565b60008060006060848603121561592a57600080fd5b833561593581615e95565b9250602084013561594581615e95565b9150604084013561595581615e95565b809150509250925092565b60008060006060848603121561597557600080fd5b833561598081615e95565b9250602084013561599081615e95565b929592945050506040919091013590565b600080600080608085870312156159b757600080fd5b84356159c281615e95565b935060208501356159d281615e95565b92506040850135915060608501356159e981615e95565b939692955090935050565b60008060008060808587031215615a0a57600080fd5b8435615a1581615e95565b93506020850135615a2581615e95565b93969395505050506040820135916060013590565b600080600080600060a08688031215615a5257600080fd5b8535615a5d81615e95565b94506020860135615a6d81615e95565b94979496505050506040830135926060810135926080909101359150565b60008060408385031215615a9e57600080fd5b8235615aa981615e95565b946020939093013593505050565b600080600060608486031215615acc57600080fd5b8335615ad781615e95565b925060208401359150604084013561595581615e95565b600060208284031215615b0057600080fd5b61478482615880565b600080600060608486031215615b1e57600080fd5b615b2784615890565b9250615b3560208501615890565b9150615b4360408501615880565b90509250925092565b600060208284031215615b5e57600080fd5b5035919050565b600060208284031215615b7757600080fd5b5051919050565b60008251615b90818460208701615dbb565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615bfd57845163ffffffff1683529383019391830191600101615bdb565b5090979650505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015615c645783516001600160a01b031683529284019291840191600101615c3f565b50909695505050505050565b6020815260008251806020840152615c8f816040850160208701615dbb565b601f01601f19169190910160400192915050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b92835260069190910b6020830152604082015260600190565b9283526020830191909152604082015260600190565b60008219821115615d1c57615d1c615e3d565b500190565b600082615d3057615d30615e53565b500490565b6000816000190483118215151615615d4f57615d4f615e3d565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615d7f57615d7f615e3d565b81667fffffffffffff018313811615615d9a57615d9a615e3d565b5090039392505050565b600082821015615db657615db6615e3d565b500390565b60005b83811015615dd6578181015183820152602001615dbe565b838111156150c75750506000910152565b6000600019821415615dfb57615dfb615e3d565b5060010190565b600082615e1157615e11615e53565b500690565b60008160060b667fffffffffffff19811415615e3457615e34615e3d565b60000392915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114614fd857600080fdfe46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfaee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a2646970667358221220ec681c5589ef99141a8259fe0a15909fb5951d0f57ea12ebe2f275ea961af1f064736f6c63430008070033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106104075760003560e01c8063966abd0011610228578063c5198abc1161013c578063ec8ca643116100be578063ec8ca64314610add578063f0f346b914610b06578063f11a1d1a14610b19578063f136a09d14610b2c578063f25e311b14610b4c578063f263c47014610b5f578063f39c38a014610b68578063f75f9f7b14610b7b578063f9d46cf214610b8e578063fc253d2b14610ba1578063fe75bc4614610baa57600080fd5b8063c5198abc146109f1578063c7ae40d014610a04578063cb4be2bb14610a17578063cb54694d14610a2a578063cd22af1b14610a3d578063d55995fe14610a68578063dd2080d614610a7b578063ddca3f4314610a8e578063e326ac4314610a97578063ebbb619414610ab7578063ec00cdfc14610aca57600080fd5b8063966abd001461080457806398e90a0f146108175780639d5c33d814610840578063a214580914610853578063a39744b514610866578063a515366a14610891578063a5d059ca146108a4578063a676f9ff146108b7578063a7d2e784146108d7578063aac6aa9c146108e0578063ab033ea9146108f3578063af320e8114610906578063b0103b1a14610919578063b0f328f11461093c578063b239223314610944578063b440027f14610957578063b600702a14610982578063b70362b914610995578063b7e77340146109a8578063b87fcbff146109bb578063c20297f0146109de57600080fd5b80635aa6e6751161031f5780635aa6e6751461066b5780635ebe23f01461067e5780635feeb79414610687578063633fb68f1461069a57806364bb43ee146106a357806368a9f19c146106b6578063694798e6146106c957806369fe0e2d146106f45780636ba42aaa146107075780636cf262bc1461071a5780636e2a9ca61461072d57806372da828a1461074057806374a8f10314610753578063768b5d90146107665780637c8fce231461076f578063878c723e146107775780638bb6dfa8146107a05780638cb22b76146107b35780638fe204dd146107d657806390a4684e146107e9578063951dc22c146107fc57600080fd5b8063034d4c611461040c57806307b435c2146104325780630c620bce1461045d5780630d6a1f87146104725780631101eb411461048557806311466d721461049a57806315006b82146104ad578063165e62e7146104d8578063168f92e7146105155780631b44555e146105405780631c5a9d9c146105605780631ef94b911461057357806321040b0114610593578063238efcbc146105be578063274a8db4146105c657806351cff8d9146105f957806352a4de291461060c57806355ea6c471461061f578063575288bf14610632578063594a3a931461064557806359a2255e14610658575b600080fd5b61041f61041a3660046158a2565b610bbd565b6040519081526020015b60405180910390f35b61041f6104403660046158dc565b601660209081526000928352604080842090915290825290205481565b610465610cc3565b6040516104299190615c23565b61041f610480366004615a8b565b610cd4565b610498610493366004615960565b610dda565b005b6104986104a8366004615a8b565b610f34565b61041f6104bb3660046158dc565b601460209081526000928352604080842090915290825290205481565b6104eb6104e63660046158a2565b6110c3565b604080518251600690810b825260208085015190910b908201529181015190820152606001610429565b61041f6105233660046158dc565b600d60209081526000928352604080842090915290825290205481565b61041f61054e3660046158a2565b60096020526000908152604090205481565b61049861056e3660046158a2565b6112f0565b601b54610586906001600160a01b031681565b6040516104299190615b9a565b61041f6105a13660046158dc565b601760209081526000928352604080842090915290825290205481565b610498611454565b6105e96105d43660046158a2565b60066020526000908152604090205460ff1681565b6040519015158152602001610429565b6104986106073660046158a2565b6114e0565b61049861061a366004615960565b611678565b61049861062d3660046158a2565b6118aa565b610498610640366004615960565b61195e565b6104986106533660046158dc565b611c21565b6104986106663660046158a2565b611cc6565b600354610586906001600160a01b031681565b61041f601e5481565b6104986106953660046158a2565b611d78565b61041f60205481565b6104986106b13660046158a2565b611d91565b6104986106c43660046158a2565b611e72565b61041f6106d73660046158dc565b602760209081526000928352604080842090915290825290205481565b610498610702366004615b4c565b611f51565b6105e96107153660046158a2565b611fb1565b61041f6107283660046158a2565b612011565b61049861073b366004615960565b612147565b61049861074e3660046158a2565b612296565b6104986107613660046158a2565b612333565b61041f60215481565b61046561242e565b6105866107853660046158a2565b6001602052600090815260409020546001600160a01b031681565b61041f6107ae3660046158a2565b61243a565b6105e96107c13660046158a2565b60186020526000908152604090205460ff1681565b6104986107e4366004615b4c565b6124dd565b6104986107f73660046158dc565b61253d565b61046561262b565b610498610812366004615ab7565b612637565b6105866108253660046158a2565b6002602052600090815260409020546001600160a01b031681565b61049861084e3660046158a2565b61274d565b610498610861366004615915565b61282c565b61041f6108743660046158dc565b600c60209081526000928352604080842090915290825290205481565b61049861089f366004615a8b565b6129fc565b6104986108b2366004615a8b565b612c5d565b61041f6108c53660046158a2565b60286020526000908152604090205481565b61041f601f5481565b6104986108ee3660046158a2565b612d37565b6104986109013660046158a2565b612deb565b6104986109143660046158dc565b612e61565b6105e96109273660046158a2565b600b6020526000908152604090205460ff1681565b61041f6132e0565b610498610952366004615b4c565b613376565b61041f6109653660046158dc565b602460209081526000928352604080842090915290825290205481565b6104986109903660046158a2565b6133d6565b6104986109a3366004615a8b565b613644565b6104986109b6366004615b4c565b6139fa565b6105e96109c93660046158a2565b60056020526000908152604090205460ff1681565b6104986109ec3660046159f4565b613a5a565b6104986109ff3660046158a2565b613b13565b601c54610586906001600160a01b031681565b610498610a253660046158a2565b613bd9565b610498610a38366004615b4c565b613c76565b61041f610a4b3660046158dc565b601560209081526000928352604080842090915290825290205481565b610498610a763660046159a1565b613cfa565b610498610a89366004615960565b613f31565b61041f60235481565b61041f610aa53660046158a2565b600a6020526000908152604090205481565b610498610ac5366004615b4c565b6140ae565b610498610ad83660046158a2565b61410c565b610586610aeb3660046158a2565b602b602052600090815260409020546001600160a01b031681565b610498610b143660046158a2565b6141a9565b601d54610586906001600160a01b031681565b61041f610b3a3660046158a2565b60296020526000908152604090205481565b610498610b5a366004615960565b61425d565b61041f602e5481565b600454610586906001600160a01b031681565b610498610b893660046158a2565b6144a2565b6105e9610b9c366004615a3a565b61455a565b61041f60225481565b610498610bb8366004615a8b565b614643565b600080610bc983612011565b6021549091504290610be490610bdf9083615da4565b614733565b6001600160a01b0385166000908152602860205260409020541115610c88576021546001600160a01b038516600090815260286020526040902054610c299042615da4565b10610c65576021546001600160a01b038516600090815260286020526040902054610c549190615d09565b610c5e9082615da4565b9050610c9e565b6001600160a01b038416600090815260286020526040902054610c5e9082615da4565b610c9142614733565b610c9b9082615da4565b90505b610ca8818361474d565b610cb18561243a565b610cbb9190615d09565b949350505050565b6060610ccf6025614777565b905090565b6000610ce160258461478b565b15610dd4576000610cf1846110c3565b90508060400151600014610dd2576001600160a01b03841660009081526013602052604081205460ff16610d32578160200151610d2d90615e16565b610d38565b81602001515b601d5460215460405163a0d2710760e01b8152929350610dc9926001600160a01b039092169163a0d2710791610d749189918791600401615cda565b60206040518083038186803b158015610d8c57600080fd5b505afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190615b65565b6147ad565b92505050610dd4565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610e1657604051636efb4f4160e11b815260040160405180910390fd5b601f54610e239042615d09565b6001600160a01b03808616600081815260166020908152604080832094891680845294825280832095909555918152601782528381209281529190529081208054849290610e72908490615d09565b90915550610e8390508484846147be565b6001600160a01b038085166000908152602760209081526040808320938716835292905220548015801590610ec25750602054610ec082866149cc565b105b15610ee057604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de85604051610f2591815260200190565b60405180910390a35050505050565b336000818152600b602052604090205460ff1615610f655760405163ad2fdf3b60e01b815260040160405180910390fd5b610f7060198261478b565b610f8c5760405162941a5760e11b815260040160405180910390fd5b610f9581614aea565b15610ff0576001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615ecb83398151915293610fe79390929091615cf3565b60405180910390a25b6001600160a01b0381166000908152600e602052604090205482111561106f5761101981614cc0565b6001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615ecb833981519152936110669390929091615cf3565b60405180910390a25b61107a818484614d4e565b601b546001600160a01b03808516918382169116600080516020615eab833981519152856110a6614e32565b6040805192835260208301919091520160405180910390a4505050565b60408051606081018252600080825260208201819052918101919091526110e942614733565b6001600160a01b0383166000908152602a6020526040902060010154141561115f57506001600160a01b03166000908152602a602090815260409182902082516060810184528154600681810b810b810b8352600160381b909104810b810b900b92810192909252600101549181019190915290565b6040805160028082526060820183526000928392919060208301908036833701905050905061118d42614733565b6111979042615da4565b816000815181106111aa576111aa615e7f565b602002602001019063ffffffff16908163ffffffff16815250506021546111d042614733565b6111da9042615da4565b6111e49190615d09565b816001815181106111f7576111f7615e7f565b63ffffffff909216602092830291909101820152601d546001600160a01b0386811660009081526012909352604080842054905163dc686d9160e01b81529282169263dc686d919261124f9216908690600401615bae565b60606040518083038186803b15801561126757600080fd5b505afa15801561127b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129f9190615b09565b600692830b90920b80875291945091506112ba908290615d54565b600690810b900b602085015282156112df576112d542614733565b60408501526112e7565b600060408501525b5050505b919050565b336000818152600b602052604090205460ff1615611321576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b038082166000908152601560209081526040808320938616835292905220548061136557604051636258f48160e01b815260040160405180910390fd5b42811061138557604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600a60205260409020546113be576001600160a01b0382166000908152600a602052604090204290555b6113c9600783614e4c565b506001600160a01b03828116600090815260146020908152604080832093871683529290529081208054919055611401838583614e61565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a758360405161144691815260200190565b60405180910390a350505050565b6004546001600160a01b0316331461147f57604051637ef5703160e11b815260040160405180910390fd5b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b6916114d691615b9a565b60405180910390a1565b6002600054141561150c5760405162461bcd60e51b815260040161150390615ca3565b60405180910390fd5b600260009081553381526017602090815260408083206001600160a01b03851684529091529020546115515760405163184c088160e21b815260040160405180910390fd5b3360009081526016602090815260408083206001600160a01b03851684529091529020544211611594576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600b602052604090205460ff16156115c5576040516362e6201d60e01b815260040160405180910390fd5b3360008181526017602090815260408083206001600160a01b038681168086529184528285208054908690559585526016845282852082865290935290832092909255601b5416141561161b5761161b81614fb7565b61162f6001600160a01b0383163383614fdb565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b6002600054141561169b5760405162461bcd60e51b815260040161150390615ca3565b60026000556116ab60258361478b565b6116c85760405163e0b6aead60e01b815260040160405180910390fd5b6116d360198461478b565b6116f057604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526011602052604090206117129083614e4c565b5061171c83615031565b602080546001600160a01b0380861660009081526027845260408082209287168252919093529091205461175b90611755908490615d09565b846149cc565b101561177a57604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615ecb833981519152936117c79390929091615cf3565b60405180910390a26117e46001600160a01b03831633308461508f565b6001600160a01b0380841660009081526027602090815260408083209386168352929052908120805483929061181b908490615d09565b9091555061182e9050610dc482846149cc565b6001600160a01b0384166000908152600f602052604081208054909190611856908490615d09565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff166118da57604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff16611913576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600b6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b600260005414156119815760405162461bcd60e51b815260040161150390615ca3565b600260005561199160198461478b565b6119ae57604051636211d34960e01b815260040160405180910390fd5b601b546001600160a01b03838116911614156119dc5760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038416906370a0823190611a0b903090600401615b9a565b60206040518083038186803b158015611a2357600080fd5b505afa158015611a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5b9190615b65565b9050611a726001600160a01b03841633308561508f565b600081846001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611aa19190615b9a565b60206040518083038186803b158015611ab957600080fd5b505afa158015611acd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af19190615b65565b611afb9190615da4565b9050600061271060235483611b109190615d35565b611b1a9190615d21565b9050611b268183615da4565b6001600160a01b038088166000908152600d60209081526040808320938a1683529290529081208054909190611b5d908490615d09565b90915550506001600160a01b0380871660009081526024602090815260408083208985168085529252909120429055600354611b9a921683614fdb565b6001600160a01b0386166000908152601060205260409020611bbc9086614e4c565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611c0c91815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611c5d57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611d025760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b6040516331cee75f60e21b815260040160405180910390fd5b6003546001600160a01b03163314611dbc576040516354348f0360e01b815260040160405180910390fd5b611dc76025826150cd565b611de457604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600090815260126020908152604080832080546001600160a01b031916905560138252808320805460ff19169055602a90915280822080546001600160701b031916815560010191909155517f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e5690611e67908390615b9a565b60405180910390a150565b6003546001600160a01b03163314611e9d576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116611ec45760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff1615611efe5760405163546da66560e11b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b90611e67908390615b9a565b6003546001600160a01b03163314611f7c576040516354348f0360e01b815260040160405180910390fd5b60238190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d90602001611e67565b6000611fbb614e32565b602d55611fc960078361478b565b156112eb577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602d5460405161200191815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b0383166000908152601160205260409020612036906150e2565b811015612141576001600160a01b038316600090815260116020526040812061205f90836150ec565b905061206c60258261478b565b1561212e57600061207c826110c3565b9050806040015160001461212c576001600160a01b03821660009081526013602052604081205460ff166120bd5781602001516120b890615e16565b6120c3565b81602001515b601d546001600160a01b03888116600090815260276020908152604080832089851684529091529081902054602154915163a0d2710760e01b815294955061211e94929093169263a0d2710792610d74928791600401615cda565b6121289086615d09565b9450505b505b508061213981615de7565b915050612015565b50919050565b3360009081526005602052604090205460ff1661217757604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff166121b0576040516310cec38560e21b815260040160405180910390fd5b6121bb8383836147be565b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb926121ef92909116908590600401615c0a565b602060405180830381600087803b15801561220957600080fd5b505af1925050508015612239575060408051601f3d908101601f1916820190925261223691810190615aee565b60015b61224257612244565b505b336001600160a01b0316836001600160a01b03167f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e8484604051612289929190615c0a565b60405180910390a3505050565b6003546001600160a01b031633146122c1576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166122e85760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383161790556040517f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b090611e67908390615b9a565b3360009081526005602052604090205460ff1661236357604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff1661239c576040516310cec38560e21b815260040160405180910390fd5b6123a76007826150cd565b50601b546001600160a01b038083166000818152600c60209081526040808320949095168083529381528482205492825260178152848220848352905292909220546123f5928492916150f8565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610ccf6019614777565b60008061244683612011565b6021546001600160a01b038516600090815260286020526040902054919250906124709042615da4565b1015610dd4576000811161249c576001600160a01b0383166000908152600e60205260409020546124d6565b6001600160a01b0383166000908152600f6020908152604080832054600e909252909120546124cc908390615d35565b6124d69190615d21565b9150612141565b6003546001600160a01b03163314612508576040516354348f0360e01b815260040160405180910390fd5b601f8190556040518181527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee290602001611e67565b6001600160a01b03828116600090815260016020526040902054839116331461257957604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156125ac5760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602b6020908152604080832080546001600160a01b0319169588169586179055602c825280832094835293905282902042905590517fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c9061261e908590615b9a565b60405180910390a2505050565b6060610ccf6007614777565b6003546001600160a01b03163314612662576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166126895760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156126ea576040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156126e4573d6000803e3d6000fd5b506126fe565b6126fe6001600160a01b0384168284614fdb565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b03163314612778576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661279f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff16156127d95760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19166001179055517f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f90611e67908390615b9a565b6001600160a01b03838116600090815260016020526040902054849116331461286857604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03821661288f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038085166000908152601760209081526040808320938716835292905220546128d25760405163184c088160e21b815260040160405180910390fd5b6001600160a01b038085166000908152601660209081526040808320938716835292905220544211612917576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600b602052604090205460ff1615612951576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b038085166000818152601760209081526040808320948816808452948252808320805490849055938352601682528083208584529091528120559061299e908483614fdb565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca7928862846040516129ed91815260200190565b60405180910390a45050505050565b60026000541415612a1f5760405162461bcd60e51b815260040161150390615ca3565b60026000908155338152600b602052604090205460ff1615612a54576040516362e6201d60e01b815260040160405180910390fd5b612a5f60193361478b565b15612a7d5760405163d7229c4360e01b815260040160405180910390fd5b601e54612a8a9042615d09565b3360009081526015602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81529091906370a0823190612ad5903090600401615b9a565b60206040518083038186803b158015612aed57600080fd5b505afa158015612b01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b259190615b65565b9050612b3c6001600160a01b03841633308561508f565b6040516370a0823160e01b815281906001600160a01b038516906370a0823190612b6a903090600401615b9a565b60206040518083038186803b158015612b8257600080fd5b505afa158015612b96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bba9190615b65565b612bc49190615da4565b336000908152601860209081526040808320805460ff19166001179055601482528083206001600160a01b0388168452909152812080549294508492909190612c0e908490615d09565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b601f54612c6a9042615d09565b3360008181526016602090815260408083206001600160a01b03881680855290835281842095909555928252600c81528282209382529290925281208054839290612cb6908490615da4565b90915550503360009081526017602090815260408083206001600160a01b038616845290915281208054839290612cee908490615d09565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b03163314612d62576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16612d9b576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19169055517f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d02590611e67908390615b9a565b6003546001600160a01b03163314612e16576040516354348f0360e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90611e67908390615b9a565b6001600160a01b038181166000908152600160205260409020548291163314612e9d57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff1680612edc57506001600160a01b0382166000908152600b602052604090205460ff165b15612efa5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602b6020526040902054811690831614612f3757604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602c6020908152604080832093861683529290522054612f6990603c90615d09565b421015612f89576040516356248e9760e01b815260040160405180910390fd5b612f9283615031565b612f9b82615031565b6001600160a01b0383166000908152601060205260408120612fbc906150e2565b111561309e576001600160a01b0383166000908152601060205260408120612fe490826150ec565b6001600160a01b038086166000908152600d6020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613032908490615d09565b90915550506001600160a01b038085166000818152600d60209081526040808320948616835293815283822082905591815260109091522061307490826150cd565b506001600160a01b03831660009081526010602052604090206130979082614e4c565b5050612f9b565b6001600160a01b03831660009081526011602052604081206130bf906150e2565b11156131a1576001600160a01b03831660009081526011602052604081206130e790826150ec565b6001600160a01b03808616600090815260276020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613135908490615d09565b90915550506001600160a01b03808516600090815260276020908152604080832085851684528252808320839055928616825260119052206131779082614e4c565b506001600160a01b038416600090815260116020526040902061319a90826150cd565b505061309e565b6001600160a01b038084166000908152600f6020526040808220549285168252812080549091906131d3908490615d09565b90915550506001600160a01b038084166000908152600f60209081526040808320839055600e90915280822054928516825281208054909190613217908490615d09565b90915550506001600160a01b0383166000908152600e60209081526040808320839055602890915281205561324d6019846150cd565b506001600160a01b03808416600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602c8352818420958816808552958352818420849055938352602b909152908190208054909216909155517f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f29061261e908690615b9a565b602e54601b54601c546040516370a0823160e01b8152600093926001600160a01b03908116926370a082319261331c9290911690600401615b9a565b60206040518083038186803b15801561333457600080fd5b505afa158015613348573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336c9190615b65565b610ccf9190615da4565b6003546001600160a01b031633146133a1576040516354348f0360e01b815260040160405180910390fd5b60228190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb6990602001611e67565b6003546001600160a01b03163314613401576040516354348f0360e01b815260040160405180910390fd5b61340c602582614e4c565b6134295760405163f25e6b9f60e01b815260040160405180910390fd5b601d5460405163eb37d34960e01b81526001600160a01b039091169063eb37d34990613459908490600401615b9a565b60206040518083038186803b15801561347157600080fd5b505afa158015613485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a991906158bf565b6001600160a01b03828116600090815260126020526040902080546001600160a01b0319169290911691821790556134f45760405163d92e233d60e01b815260040160405180910390fd5b601d546001600160a01b038281166000908152601260205260409081902054905163696a437b60e01b81529282169263696a437b92613537921690600401615b9a565b60206040518083038186803b15801561354f57600080fd5b505afa158015613563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135879190615aee565b6001600160a01b0382166000908152601360205260409020805460ff19169115159190911790556135b7816110c3565b6001600160a01b0382166000908152602a60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b161791909117815591810151600190920191909155517fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b90611e67908390615b9a565b602d5461366457604051630262ab9b60e61b815260040160405180910390fd5b600061366e614e32565b336000818152600b60205260409020549192509060ff16156136a35760405163ad2fdf3b60e01b815260040160405180910390fd5b6136ae60198261478b565b6136ca5760405162941a5760e11b815260040160405180910390fd5b6136d381614aea565b1561372e576001600160a01b038116600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615ecb833981519152936137259390929091615cf3565b60405180910390a25b601d546001600160a01b038581166000908152600c60209081526040808320601b548516845290915280822054905163516c332360e01b815260048101919091529092919091169063516c33239060240160206040518083038186803b15801561379757600080fd5b505afa1580156137ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cf9190615b65565b905060006127108285602d546137e59190615da4565b6137ef9088615d35565b6137f99190615d35565b6138039190615d21565b601d54604051633b67c3bd60e01b8152600481018390529192506000916001600160a01b0390911690633b67c3bd90602401602060405180830381600087803b15801561384f57600080fd5b505af1158015613863573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138879190615b65565b601d54604051633b46f5db60e21b8152600481018390529192506000916001600160a01b039091169063ed1bd76c9060240160206040518083038186803b1580156138d157600080fd5b505afa1580156138e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139099190615b65565b6001600160a01b0386166000908152600e602052604090205490915081111561398b5761393585614cc0565b6001600160a01b038516600081815260286020908152604080832054600e835281842054600f90935292819020549051600080516020615ecb833981519152936139829390929091615cf3565b60405180910390a25b80602e600082825461399d9190615d09565b909155506139ae9050858983614d4e565b6000602d55601b5460408051838152602081018990526001600160a01b038b81169389821693911691600080516020615eab833981519152910160405180910390a45050505050505050565b6003546001600160a01b03163314613a25576040516354348f0360e01b815260040160405180910390fd5b601e8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b4390602001611e67565b3360009081526005602052604090205460ff16613a8a57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600b602052604090205460ff16613ac3576040516310cec38560e21b815260040160405180910390fd5b613acf848484846150f8565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613b058486615d09565b604051908152602001611446565b613b1e60198261478b565b15613b3c57604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526018602052604090205460ff1615613b7657604051632f3d320560e01b815260040160405180910390fd5b613b81601982614e4c565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613c04576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116613c2b5760405163d92e233d60e01b815260040160405180910390fd5b601c80546001600160a01b0319166001600160a01b0383161790556040517feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae25090611e67908390615b9a565b6003546001600160a01b03163314613ca1576040516354348f0360e01b815260040160405180910390fd5b62015180811015613cc557604051633f384aad60e21b815260040160405180910390fd5b60218190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d990602001611e67565b60026000541415613d1d5760405162461bcd60e51b815260040161150390615ca3565b600260009081556001600160a01b03858116825260016020526040909120548591163314613d5e57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260246020908152604080832093881683529290522054613d9090603c90615d09565b4211613daf57604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600d6020908152604080832093881683529290522054831115613df55760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600b602052604090205460ff1615613e2f5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600d6020908152604080832093881683529290529081208054859290613e66908490615da4565b90915550613e8090506001600160a01b0385168385614fdb565b6001600160a01b038086166000908152600d6020908152604080832093881683529290522054613ece576001600160a01b0385166000908152601060205260409020613ecc90856150cd565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613f1d91815260200190565b60405180910390a450506001600055505050565b336000818152600b602052604090205460ff1615613f625760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff1615613f9c576040516362e6201d60e01b815260040160405180910390fd5b613fa760198261478b565b613fc35760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600d60209081526040808320938816835292905220548211156140095760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600d6020908152604080832093881683529290529081208054849290614040908490615da4565b9091555061405a90506001600160a01b0385168484614fdb565b826001600160a01b0316816001600160a01b0316856001600160a01b0316600080516020615eab83398151915285614090614e32565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b031633146140d9576040516354348f0360e01b815260040160405180910390fd5b60208181556040518281527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e79101611e67565b6003546001600160a01b03163314614137576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661415e5760405163d92e233d60e01b815260040160405180910390fd5b601b80546001600160a01b0319166001600160a01b0383161790556040517f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf90611e67908390615b9a565b6003546001600160a01b031633146141d4576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1661420d57604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19169055517f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e90611e67908390615b9a565b3360009081526005602052604090205460ff1661428d57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600b602052604090205460ff166142c6576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b03831660009081526010602052604090206142e8908361478b565b61430557604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600d602090815260408083209386168352929052205481111561434a5760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261437e92909116908590600401615c0a565b602060405180830381600087803b15801561439857600080fd5b505af19250505080156143c8575060408051601f3d908101601f191682019092526143c591810190615aee565b60015b6143d1576143d3565b505b6001600160a01b038084166000908152600d602090815260408083209386168352929052908120805483929061440a908490615da4565b90915550506001600160a01b038084166000908152600d602090815260408083209386168352929052205461445d576001600160a01b038316600090815260106020526040902061445b90836150cd565b505b336001600160a01b0316836001600160a01b03167f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d3183331048484604051612289929190615c0a565b3360009081526006602052604090205460ff166144d257604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff161561450c576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600b6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b6000614564614e32565b602d5561457260078761478b565b80156145a357506001600160a01b038087166000908152600c60209081526040808320938916835292905220548411155b80156145c757506001600160a01b0386166000908152600960205260409020548311155b80156145f657506001600160a01b0386166000908152600a602052604090205482906145f39042615da4565b10155b1561463a577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602d5460405161462e91815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b0316331461466e576040516354348f0360e01b815260040160405180910390fd5b61467960198361478b565b61469657604051636211d34960e01b815260040160405180910390fd5b61469f82615031565b6001600160a01b0382166000908152600e6020526040812080548392906146c7908490615d09565b90915550506001600160a01b038216600081815260286020908152604080832054600e909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d192614727928252602082015260400190565b60405180910390a25050565b6000602154826147439190615e02565b610dd49083615da4565b6000602154831015612141576021546147668385615d35565b6147709190615d21565b9050610dd4565b606060006147848361524e565b9392505050565b6001600160a01b03811660009081526001830160205260408120541515614784565b6000610dd4826021546022546152aa565b600260005414156147e15760405162461bcd60e51b815260040161150390615ca3565b600260009081556001600160a01b0384168152601160205260409020614807908361478b565b614823576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b038084166000908152602760209081526040808320938616835292905220548111156148695760405163435b562560e01b815260040160405180910390fd5b61487283615358565b6000614881610dc483856149cc565b6001600160a01b0385166000908152600f602052604090205490915015614937576001600160a01b0384166000908152600f6020908152604080832054600e909252909120546148d2908390615d35565b6148dc9190615d21565b6001600160a01b0385166000908152600e602052604081208054909190614904908490615da4565b90915550506001600160a01b0384166000908152600f602052604081208054839290614931908490615da4565b90915550505b6001600160a01b0380851660009081526027602090815260408083209387168352929052908120805484929061496e908490615da4565b90915550506001600160a01b038085166000908152602760209081526040808320938716835292905220546149c1576001600160a01b03841660009081526011602052604090206149bf90846150cd565b505b505060016000555050565b6001600160a01b0381166000908152602a602052604081206001015415610dd4576001600160a01b03821660009081526013602052604081205460ff16614a3e576001600160a01b0383166000908152602a6020526040902054614a3990600160381b900460060b615e16565b614a62565b6001600160a01b0383166000908152602a6020526040902054600160381b900460060b5b601d5460215460405163a0d2710760e01b81529293506001600160a01b039091169163a0d2710791614a9a9188918691600401615cda565b60206040518083038186803b158015614ab257600080fd5b505afa158015614ac6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbb9190615b65565b6000614af542614733565b6001600160a01b03831660009081526028602052604090205410156112eb57614b2560215442610bdf9190615da4565b6001600160a01b03831660009081526028602052604090205411614b9b57614b4c82615358565b6001600160a01b0382166000908152600f6020908152604080832054600e90925290912055614b7a42614733565b6001600160a01b038316600090815260286020526040902055506001919050565b6021546001600160a01b038316600090815260286020526040902054614bc19042615da4565b10614c1d57614bcf82615358565b6001600160a01b0382166000908152600f6020908152604080832054600e83528184205560215460289092528220805491929091614c0e908490615d09565b90915550600191506112eb9050565b614c2642614733565b6001600160a01b03831660009081526029602052604090205410156112eb576001600160a01b0382166000908152600f6020526040902054614c6783615358565b6001600160a01b0383166000908152600f6020908152604080832054600e909252909120548291614c9791615d35565b614ca19190615d21565b6001600160a01b0384166000908152600e602052604090205550919050565b6001600160a01b038116600090815260286020526040902054614d0590614ce79042615da4565b6001600160a01b0383166000908152600f602052604090205461474d565b6001600160a01b0382166000908152600e602052604081208054909190614d2d908490615d09565b90915550506001600160a01b03166000908152602860205260409020429055565b6001600160a01b0383166000908152600e6020526040902054811115614d875760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602960209081526040808320429055600e90915281208054839290614dbc908490615da4565b90915550506001600160a01b038083166000908152600c60209081526040808320601b5490941683529290529081208054839290614dfb908490615d09565b90915550506001600160a01b03821660009081526009602052604081208054839290614e28908490615d09565b9091555050505050565b6000603f5a614e42906040615d35565b610ccf9190615d21565b6000614784836001600160a01b03841661537d565b6001600160a01b038084166000908152600c6020908152604080832093861683529290529081208054839290614e98908490615d09565b9091555050601b546001600160a01b0383811691161415614fb25780602e6000828254614ec59190615d09565b9091555050601b54601c5460405163095ea7b360e01b81526001600160a01b039283169263095ea7b392614f00929116908590600401615c0a565b602060405180830381600087803b158015614f1a57600080fd5b505af1158015614f2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f529190615aee565b50601c5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f2590602401600060405180830381600087803b158015614f9957600080fd5b505af1158015614fad573d6000803e3d6000fd5b505050505b505050565b80602e6000828254614fc99190615da4565b90915550614fd89050816153cc565b50565b614fb28363a9059cbb60e01b8484604051602401614ffa929190615c0a565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261542d565b61503a81614aea565b5061504481614cc0565b6001600160a01b0381166000908152600e6020908152604080832054600f9092529091205461507391906154ff565b6001600160a01b039091166000908152600e6020526040902055565b6040516001600160a01b03808516602483015283166044820152606481018290526150c79085906323b872dd60e01b90608401614ffa565b50505050565b6000614784836001600160a01b038416615515565b6000610dd4825490565b60006147848383615608565b601b546001600160a01b038481169116146151d0576003546001600160a01b038085169163a9059cbb911661512d8486615d09565b6040518363ffffffff1660e01b815260040161514a929190615c0a565b602060405180830381600087803b15801561516457600080fd5b505af1925050508015615194575060408051601f3d908101601f1916820190925261519191810190615aee565b60015b6151ce573d8080156151c2576040519150601f19603f3d011682016040523d82523d6000602084013e6151c7565b606091505b50506151d0565b505b6001600160a01b038085166000908152600c6020908152604080832093871683529290529081208054849290615207908490615da4565b90915550506001600160a01b03808516600090815260176020908152604080832093871683529290529081208054839290615243908490615da4565b909155505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561529e57602002820191906000526020600020905b81548152602001906001019080831161528a575b50505050509050919050565b6000808060001985870985870292508281108382030391505080600014156152e457600084116152d957600080fd5b508290049050614784565b8084116152f057600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b61536181615632565b6001600160a01b039091166000908152600f6020526040902055565b60008181526001830160205260408120546153c457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610dd4565b506000610dd4565b601c5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401600060405180830381600087803b15801561541257600080fd5b505af1158015615426573d6000803e3d6000fd5b5050505050565b6000615482826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166157759092919063ffffffff16565b805190915015614fb257808060200190518101906154a09190615aee565b614fb25760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611503565b600081831061550e5781614784565b5090919050565b600081815260018301602052604081205480156155fe576000615539600183615da4565b855490915060009061554d90600190615da4565b90508181146155b257600086600001828154811061556d5761556d615e7f565b906000526020600020015490508087600001848154811061559057615590615e7f565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806155c3576155c3615e69565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610dd4565b6000915050610dd4565b600082600001828154811061561f5761561f615e7f565b9060005260206000200154905092915050565b6000805b6001600160a01b0383166000908152601160205260409020615657906150e2565b811015612141576001600160a01b038316600090815260116020526040812061568090836150ec565b905061568d60258261478b565b156157625761569b42614733565b6001600160a01b0382166000908152602a602052604090206001015414615721576156c5816110c3565b6001600160a01b0382166000908152602a60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b16179190911781559101516001909101555b6001600160a01b0380851660009081526027602090815260408083209385168352929052205461575590610dc490836149cc565b61575f9084615d09565b92505b508061576d81615de7565b915050615636565b6060610cbb848460008585843b6157ce5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611503565b600080866001600160a01b031685876040516157ea9190615b7e565b60006040518083038185875af1925050503d8060008114615827576040519150601f19603f3d011682016040523d82523d6000602084013e61582c565b606091505b509150915061583c828286615847565b979650505050505050565b60608315615856575081614784565b8251156158665782518084602001fd5b8160405162461bcd60e51b81526004016115039190615c70565b805180151581146112eb57600080fd5b8051600681900b81146112eb57600080fd5b6000602082840312156158b457600080fd5b813561478481615e95565b6000602082840312156158d157600080fd5b815161478481615e95565b600080604083850312156158ef57600080fd5b82356158fa81615e95565b9150602083013561590a81615e95565b809150509250929050565b60008060006060848603121561592a57600080fd5b833561593581615e95565b9250602084013561594581615e95565b9150604084013561595581615e95565b809150509250925092565b60008060006060848603121561597557600080fd5b833561598081615e95565b9250602084013561599081615e95565b929592945050506040919091013590565b600080600080608085870312156159b757600080fd5b84356159c281615e95565b935060208501356159d281615e95565b92506040850135915060608501356159e981615e95565b939692955090935050565b60008060008060808587031215615a0a57600080fd5b8435615a1581615e95565b93506020850135615a2581615e95565b93969395505050506040820135916060013590565b600080600080600060a08688031215615a5257600080fd5b8535615a5d81615e95565b94506020860135615a6d81615e95565b94979496505050506040830135926060810135926080909101359150565b60008060408385031215615a9e57600080fd5b8235615aa981615e95565b946020939093013593505050565b600080600060608486031215615acc57600080fd5b8335615ad781615e95565b925060208401359150604084013561595581615e95565b600060208284031215615b0057600080fd5b61478482615880565b600080600060608486031215615b1e57600080fd5b615b2784615890565b9250615b3560208501615890565b9150615b4360408501615880565b90509250925092565b600060208284031215615b5e57600080fd5b5035919050565b600060208284031215615b7757600080fd5b5051919050565b60008251615b90818460208701615dbb565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615bfd57845163ffffffff1683529383019391830191600101615bdb565b5090979650505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015615c645783516001600160a01b031683529284019291840191600101615c3f565b50909695505050505050565b6020815260008251806020840152615c8f816040850160208701615dbb565b601f01601f19169190910160400192915050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b92835260069190910b6020830152604082015260600190565b9283526020830191909152604082015260600190565b60008219821115615d1c57615d1c615e3d565b500190565b600082615d3057615d30615e53565b500490565b6000816000190483118215151615615d4f57615d4f615e3d565b500290565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615d7f57615d7f615e3d565b81667fffffffffffff018313811615615d9a57615d9a615e3d565b5090039392505050565b600082821015615db657615db6615e3d565b500390565b60005b83811015615dd6578181015183820152602001615dbe565b838111156150c75750506000910152565b6000600019821415615dfb57615dfb615e3d565b5060010190565b600082615e1157615e11615e53565b500690565b60008160060b667fffffffffffff19811415615e3457615e34615e3d565b60000392915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114614fd857600080fdfe46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfaee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a2646970667358221220ec681c5589ef99141a8259fe0a15909fb5951d0f57ea12ebe2f275ea961af1f064736f6c63430008070033", + "numDeployments": 1, + "solcInputHash": "7d006d28afea8f44b7106e2df679db88", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyAJob\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyAKeeper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Deprecated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Disputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasNotInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientJobTokenCredits\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityLessThanMin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationImpossible\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenCreditsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MinRewardPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoGovernanceZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDisputer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySlasher\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenUnallowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Activation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"BondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Bonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"Dispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"DustSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"FeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernance\",\"type\":\"address\"}],\"name\":\"GovernanceProposal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"GovernanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"InflationPeriodChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOwner\",\"type\":\"address\"}],\"name\":\"JobAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationSuccessful\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipAssent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_pendingOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashLiquidity\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"Keep3rHelperChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"Keep3rV1Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"Keep3rV1ProxyChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"KeeperRevoke\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"KeeperSlash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperValidation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_credit\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperWork\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityApproval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsForced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsReward\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"LiquidityMinimumChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityRevocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_resolver\",\"type\":\"address\"}],\"name\":\"Resolve\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"RewardPeriodTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"UnbondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeperOrJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_unbonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Unbonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"acceptJobMigration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"acceptJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"activate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"addDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"addJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addLiquidityToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"addSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addTokenCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"approveLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"approvedLiquidities\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"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\":[],\"name\":\"bondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"}],\"name\":\"bondedPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canActivateAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canWithdrawAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"changeJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"directTokenPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"dispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"firstSeen\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"forceLiquidityCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"hasBonded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"inflationPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minBond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_earned\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_age\",\"type\":\"uint256\"}],\"name\":\"isBondedKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isBondedKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"isKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobLiquidityCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobPendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobPeriodCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCreditsAddedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"jobs\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rHelper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1Proxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keepers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"liquidityAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidityMinimum\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"migrateJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"observeLiquidity\",\"outputs\":[{\"components\":[{\"internalType\":\"int56\",\"name\":\"current\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"difference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"}],\"internalType\":\"struct IKeep3rJobFundableLiquidity.TickCache\",\"name\":\"_tickCache\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernance\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingJobMigrations\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingUnbonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"quoteLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"removeDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"removeSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"resolve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"revoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"revokeLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardPeriodTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"rewardedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sendDust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"setBondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governance\",\"type\":\"address\"}],\"name\":\"setGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"setInflationPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"setKeep3rHelper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"setKeep3rV1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"setKeep3rV1Proxy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"setLiquidityMinimum\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"setRewardPeriodTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"setUnbondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bonded\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_bondAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_unbondAmount\",\"type\":\"uint256\"}],\"name\":\"slash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashTokenFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"slashers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"totalJobCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_credits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbondLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unbondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"virtualReserves\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"_virtualReserves\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawTokenCreditsFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workCompleted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"worked\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_usdPerGasUnit\",\"type\":\"uint256\"}],\"name\":\"worked\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptJobMigration(address,address)\":{\"details\":\"Unbond/withdraw process doesn't get migrated\",\"params\":{\"_fromJob\":\"The address of the job that requested to migrate\",\"_toJob\":\"The address to which the job wants to migrate to\"}},\"acceptJobOwnership(address)\":{\"params\":{\"_job\":\"The address of the job\"}},\"activate(address)\":{\"params\":{\"_bonding\":\"The asset being activated as bond collateral\"}},\"addJob(address)\":{\"params\":{\"_job\":\"Address of the contract for which work should be performed\"}},\"addLiquidityToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity tokens to add\",\"_job\":\"The address of the job to assign liquidity to\",\"_liquidity\":\"The liquidity being added\"}},\"addTokenCreditsToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of credit being added\",\"_job\":\"The address of the job being credited\",\"_token\":\"The address of the token being credited\"}},\"approveLiquidity(address)\":{\"details\":\"Function should be called after setting an oracle in Keep3rHelperSidechain\",\"params\":{\"_liquidity\":\"Address of the liquidity token being approved\"}},\"approvedLiquidities()\":{\"returns\":{\"_list\":\"An array of addresses with all the approved liquidity pairs\"}},\"bond(address,uint256)\":{\"params\":{\"_amount\":\"The amount of bonding asset being bonded\",\"_bonding\":\"The asset being bonded\"}},\"bondedPayment(address,uint256)\":{\"details\":\"Pays the keeper that performs the work with KP3R\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\",\"_payment\":\"The reward that should be allocated for the job\"}},\"changeJobOwnership(address,address)\":{\"params\":{\"_job\":\"The address of the job\",\"_newOwner\":\"The address of the proposed new owner\"}},\"directTokenPayment(address,address,uint256)\":{\"details\":\"Pays the keeper that performs the work with a specific token\",\"params\":{\"_amount\":\"The reward that should be allocated\",\"_keeper\":\"Address of the keeper that performed the work\",\"_token\":\"The asset being awarded to the keeper\"}},\"dispute(address)\":{\"params\":{\"_jobOrKeeper\":\"The address in dispute\"}},\"forceLiquidityCreditsToJob(address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity credits to gift\",\"_job\":\"The address of the job being credited\"}},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"details\":\"Should be used for protected functions\",\"params\":{\"_age\":\"The minimum keeper age required\",\"_bond\":\"The bond token being evaluated\",\"_earned\":\"The minimum funds earned in the keepers lifetime\",\"_keeper\":\"The keeper to check\",\"_minBond\":\"The minimum amount of bonded tokens\"},\"returns\":{\"_isBondedKeeper\":\"Whether the `_keeper` meets the given requirements\"}},\"isKeeper(address)\":{\"details\":\"Can be used for general (non critical) functions\",\"params\":{\"_keeper\":\"The keeper being investigated\"},\"returns\":{\"_isKeeper\":\"Whether the address passed as a parameter is a keeper or not\"}},\"jobLiquidityCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the liquidity credits\"},\"returns\":{\"_liquidityCredits\":\"The liquidity credits of a given job\"}},\"jobPeriodCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the period credits\"},\"returns\":{\"_periodCredits\":\"The credits the given job has at the current period\"}},\"jobs()\":{\"returns\":{\"_list\":\"Array with all the jobs in _jobs\"}},\"keepers()\":{\"returns\":{\"_list\":\"Array with all the keepers in _keepers\"}},\"migrateJob(address,address)\":{\"params\":{\"_fromJob\":\"The address of the job that is requesting to migrate\",\"_toJob\":\"The address at which the job is requesting to migrate\"}},\"observeLiquidity(address)\":{\"params\":{\"_liquidity\":\"Address of the liquidity token being observed\"}},\"quoteLiquidity(address,uint256)\":{\"details\":\"_periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\",\"params\":{\"_amount\":\"The amount of liquidity to provide\",\"_liquidity\":\"The address of the liquidity to provide\"},\"returns\":{\"_periodCredits\":\"The amount of KP3R periodically minted for the given liquidity\"}},\"resolve(address)\":{\"params\":{\"_jobOrKeeper\":\"The address cleared\"}},\"revoke(address)\":{\"params\":{\"_keeper\":\"The address being slashed\"}},\"revokeLiquidity(address)\":{\"params\":{\"_liquidity\":\"The liquidity no longer accepted\"}},\"sendDust(address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of the token that will be transferred\",\"_to\":\"The address that will receive the idle funds\",\"_token\":\"The token that will be transferred\"}},\"setBondTime(uint256)\":{\"params\":{\"_bond\":\"The new bond time\"}},\"setFee(uint256)\":{\"params\":{\"_fee\":\"The new fee\"}},\"setGovernance(address)\":{\"params\":{\"_governance\":\"The address being proposed as the new governance\"}},\"setInflationPeriod(uint256)\":{\"params\":{\"_inflationPeriod\":\"The new inflation period\"}},\"setKeep3rHelper(address)\":{\"params\":{\"_keep3rHelper\":\"The Keep3rHelper address\"}},\"setKeep3rV1(address)\":{\"params\":{\"_keep3rV1\":\"The Keep3rV1 address\"}},\"setKeep3rV1Proxy(address)\":{\"params\":{\"_keep3rV1Proxy\":\"The Keep3rV1Proxy address\"}},\"setLiquidityMinimum(uint256)\":{\"params\":{\"_liquidityMinimum\":\"The new minimum amount of liquidity\"}},\"setRewardPeriodTime(uint256)\":{\"params\":{\"_rewardPeriodTime\":\"The new amount of time required to pass between rewards\"}},\"setUnbondTime(uint256)\":{\"params\":{\"_unbond\":\"The new unbond time\"}},\"slash(address,address,uint256,uint256)\":{\"params\":{\"_bondAmount\":\"The bonded amount being slashed\",\"_bonded\":\"The asset being slashed\",\"_keeper\":\"The address being slashed\",\"_unbondAmount\":\"The pending unbond amount being slashed\"}},\"slashLiquidityFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity that will be slashed\",\"_job\":\"The address being slashed\",\"_liquidity\":\"The address of the liquidity that will be slashed\"}},\"slashTokenFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of the token that will be slashed\",\"_job\":\"The address of the job from which the token will be slashed\",\"_token\":\"The address of the token that will be slashed\"}},\"totalJobCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the total credits\"},\"returns\":{\"_credits\":\"The total credits of the given job\"}},\"unbond(address,uint256)\":{\"params\":{\"_amount\":\"Allows for partial unbonding\",\"_bonding\":\"The asset being unbonded\"}},\"unbondLiquidityFromJob(address,address,uint256)\":{\"details\":\"Can only be called by the job's owner\",\"params\":{\"_amount\":\"The amount of liquidity being removed\",\"_job\":\"The address of the job being unbonded from\",\"_liquidity\":\"The liquidity being unbonded\"}},\"virtualReserves()\":{\"returns\":{\"_virtualReserves\":\"The surplus amount of wKP3Rs in escrow contract\"}},\"withdraw(address)\":{\"params\":{\"_bonding\":\"The asset to withdraw from the bonding pool\"}},\"withdrawLiquidityFromJob(address,address,address)\":{\"params\":{\"_job\":\"The address of the job being withdrawn from\",\"_liquidity\":\"The liquidity being withdrawn\",\"_receiver\":\"The address that will receive the withdrawn liquidity\"}},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of token to be withdrawn\",\"_job\":\"The address of the job from which the credits are withdrawn\",\"_receiver\":\"The user that will receive tokens\",\"_token\":\"The address of the token being withdrawn\"}},\"worked(address)\":{\"details\":\"Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\"},\"worked(address,uint256)\":{\"details\":\"Uses a USD per gas unit payment mechanism\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\",\"_usdPerGasUnit\":\"Units of USD (in wei) per gas unit that should be rewarded to the keeper\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"AlreadyAJob()\":[{\"notice\":\"Throws when the address that is trying to register as a job is already a job\"}],\"AlreadyAKeeper()\":[{\"notice\":\"Throws when the address that is trying to register as a keeper is already a keeper\"}],\"AlreadyDisputed()\":[{\"notice\":\"Throws when a job or keeper is already disputed\"}],\"BondsLocked()\":[{\"notice\":\"Throws if the time required to bond an asset has not passed yet\"}],\"BondsUnexistent()\":[{\"notice\":\"Throws if there are no bonded assets\"}],\"Deprecated()\":[{\"notice\":\"Throws when job contract calls deprecated worked(address) function\"}],\"Disputed()\":[{\"notice\":\"Throws if either a job or a keeper is disputed\"}],\"DisputerExistent()\":[{\"notice\":\"Throws if the address is already a registered disputer\"}],\"DisputerUnexistent()\":[{\"notice\":\"Throws if caller is not a registered disputer\"}],\"GasNotInitialized()\":[{\"notice\":\"Throws if work method was called without calling isKeeper or isBondedKeeper\"}],\"InsufficientFunds()\":[{\"notice\":\"Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\"}],\"InsufficientJobTokenCredits()\":[{\"notice\":\"Throws when the user tries to withdraw more tokens than it has\"}],\"JobAlreadyAdded()\":[{\"notice\":\"Throws when trying to add a job that has already been added\"}],\"JobDisputed()\":[{\"notice\":\"Throws when an action that requires an undisputed job is applied on a disputed job\"}],\"JobLiquidityInsufficient()\":[{\"notice\":\"Throws when trying to remove more liquidity than the job has\"}],\"JobLiquidityLessThanMin()\":[{\"notice\":\"Throws when trying to add less liquidity than the minimum liquidity required\"}],\"JobLiquidityUnexistent()\":[{\"notice\":\"Throws when the job doesn't have the requested liquidity\"}],\"JobMigrationImpossible()\":[{\"notice\":\"Throws when the address of the job that requests to migrate wants to migrate to its same address\"}],\"JobMigrationLocked()\":[{\"notice\":\"Throws when cooldown between migrations has not yet passed\"}],\"JobMigrationUnavailable()\":[{\"notice\":\"Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\"}],\"JobTokenCreditsLocked()\":[{\"notice\":\"Throws when the token withdraw cooldown has not yet passed\"}],\"JobTokenInsufficient()\":[{\"notice\":\"Throws when someone tries to slash more tokens than the job has\"}],\"JobTokenUnexistent()\":[{\"notice\":\"Throws when the token trying to be slashed doesn't exist\"}],\"JobUnapproved()\":[{\"notice\":\"Throws if the address claiming to be a job is not in the list of approved jobs\"}],\"JobUnavailable()\":[{\"notice\":\"Throws when an address is passed as a job, but that address is not a job\"}],\"LiquidityPairApproved()\":[{\"notice\":\"Throws when the liquidity being approved has already been approved\"}],\"LiquidityPairUnapproved()\":[{\"notice\":\"Throws when trying to add liquidity to an unapproved pool\"}],\"LiquidityPairUnexistent()\":[{\"notice\":\"Throws when the liquidity being removed has not been approved\"}],\"MinRewardPeriod()\":[{\"notice\":\"Throws if the reward period is less than the minimum reward period time\"}],\"NoGovernanceZeroAddress()\":[{\"notice\":\"Throws if trying to set governance to zero address\"}],\"NotDisputed()\":[{\"notice\":\"Throws when a job or keeper is not disputed and someone tries to resolve the dispute\"}],\"OnlyDisputer()\":[{\"notice\":\"Throws if the msg.sender is not a disputer or is not a part of governance\"}],\"OnlyGovernance()\":[{\"notice\":\"Throws if the caller of the function is not governance\"}],\"OnlyJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the job owner\"}],\"OnlyPendingGovernance()\":[{\"notice\":\"Throws if the caller of the function is not pendingGovernance\"}],\"OnlyPendingJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the pending job owner\"}],\"OnlySlasher()\":[{\"notice\":\"Throws if the msg.sender is not a slasher or is not a part of governance\"}],\"SlasherExistent()\":[{\"notice\":\"Throws if the address is already a registered slasher\"}],\"SlasherUnexistent()\":[{\"notice\":\"Throws if caller is not a registered slasher\"}],\"TokenUnallowed()\":[{\"notice\":\"Throws when the token is KP3R, as it should not be used for direct token payments\"}],\"UnbondsLocked()\":[{\"notice\":\"Throws if the time required to withdraw the bonds has not passed yet\"}],\"UnbondsUnexistent()\":[{\"notice\":\"Throws if there are no bonds to withdraw\"}],\"ZeroAddress()\":[{\"notice\":\"Throws if a variable is assigned to the zero address\"}]},\"events\":{\"Activation(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#activate is called\"},\"BondTimeChange(uint256)\":{\"notice\":\"Emitted when bondTime is changed\"},\"Bonding(address,address,uint256)\":{\"notice\":\"Emitted when the bonding process of a new keeper begins\"},\"Dispute(address,address)\":{\"notice\":\"Emitted when a keeper or a job is disputed\"},\"DisputerAdded(address)\":{\"notice\":\"Emitted when a disputer is added\"},\"DisputerRemoved(address)\":{\"notice\":\"Emitted when a disputer is removed\"},\"DustSent(address,uint256,address)\":{\"notice\":\"Emitted when dust is sent\"},\"FeeChange(uint256)\":{\"notice\":\"Emitted when the fee is changed\"},\"GovernanceProposal(address)\":{\"notice\":\"Emitted when a new governance is proposed\"},\"GovernanceSet(address)\":{\"notice\":\"Emitted when pendingGovernance accepts to be governance\"},\"InflationPeriodChange(uint256)\":{\"notice\":\"Emitted when the inflationPeriod is changed\"},\"JobAddition(address,address)\":{\"notice\":\"Emitted when Keep3rJobManager#addJob is called\"},\"JobMigrationRequested(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#migrateJob function is called\"},\"JobMigrationSuccessful(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#acceptJobMigration function is called\"},\"JobOwnershipAssent(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\"},\"JobOwnershipChange(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#changeJobOwnership is called\"},\"JobSlashLiquidity(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\"},\"JobSlashToken(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashTokenFromJob is called\"},\"Keep3rHelperChange(address)\":{\"notice\":\"Emitted when the Keep3rHelper address is changed\"},\"Keep3rV1Change(address)\":{\"notice\":\"Emitted when the Keep3rV1 address is changed\"},\"Keep3rV1ProxyChange(address)\":{\"notice\":\"Emitted when the Keep3rV1Proxy address is changed\"},\"KeeperRevoke(address,address)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#revoke is called\"},\"KeeperSlash(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#slash is called\"},\"KeeperValidation(uint256)\":{\"notice\":\"Emitted when a keeper is validated before a job\"},\"KeeperWork(address,address,address,uint256,uint256)\":{\"notice\":\"Emitted when a keeper works a job\"},\"LiquidityAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityApproval(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\"},\"LiquidityCreditsForced(address,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\"},\"LiquidityCreditsReward(address,uint256,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityMinimumChange(uint256)\":{\"notice\":\"Emitted when _liquidityMinimum is changed\"},\"LiquidityRevocation(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\"},\"LiquidityWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\"},\"Resolve(address,address)\":{\"notice\":\"Emitted when a dispute is resolved\"},\"RewardPeriodTimeChange(uint256)\":{\"notice\":\"Emitted when _rewardPeriodTime is changed\"},\"SlasherAdded(address)\":{\"notice\":\"Emitted when a slasher is added\"},\"SlasherRemoved(address)\":{\"notice\":\"Emitted when a slasher is removed\"},\"TokenCreditAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\"},\"TokenCreditWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\"},\"UnbondTimeChange(uint256)\":{\"notice\":\"Emitted when _unbondTime is changed\"},\"Unbonding(address,address,uint256)\":{\"notice\":\"Emitted when a keeper or job begins the unbonding process to withdraw the funds\"},\"Withdrawal(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#withdraw is called\"}},\"kind\":\"user\",\"methods\":{\"acceptGovernance()\":{\"notice\":\"Changes the governance from the current governance to the previously proposed address\"},\"acceptJobMigration(address,address)\":{\"notice\":\"Completes the migration process for a job\"},\"acceptJobOwnership(address)\":{\"notice\":\"The proposed address accepts to be the owner of the job\"},\"activate(address)\":{\"notice\":\"End of the bonding process after bonding time has passed\"},\"addDisputer(address)\":{\"notice\":\"Registers a disputer by updating the disputers mapping\"},\"addJob(address)\":{\"notice\":\"Allows any caller to add a new job\"},\"addLiquidityToJob(address,address,uint256)\":{\"notice\":\"Allows anyone to fund a job with liquidity\"},\"addSlasher(address)\":{\"notice\":\"Registers a slasher by updating the slashers mapping\"},\"addTokenCreditsToJob(address,address,uint256)\":{\"notice\":\"Add credit to a job to be paid out for work\"},\"approveLiquidity(address)\":{\"notice\":\"Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\"},\"approvedLiquidities()\":{\"notice\":\"Lists liquidity pairs\"},\"bond(address,uint256)\":{\"notice\":\"Beginning of the bonding process\"},\"bondTime()\":{\"notice\":\"The amount of time required to pass after a keeper has bonded assets for it to be able to activate\"},\"bondedPayment(address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"bonds(address,address)\":{\"notice\":\"Mapping (job => bonding => amount)\"},\"canActivateAfter(address,address)\":{\"notice\":\"Tracks when a bonding for a keeper can be activated\"},\"canWithdrawAfter(address,address)\":{\"notice\":\"Tracks when keeper bonds are ready to be withdrawn\"},\"changeJobOwnership(address,address)\":{\"notice\":\"Proposes a new address to be the owner of the job\"},\"directTokenPayment(address,address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"dispute(address)\":{\"notice\":\"Allows governance to create a dispute for a given keeper/job\"},\"disputers(address)\":{\"notice\":\"Tracks whether the address is a disputer or not\"},\"disputes(address)\":{\"notice\":\"Tracks if a keeper or job has a pending dispute\"},\"fee()\":{\"notice\":\"The fee to be sent to governance when a user adds liquidity to a job\"},\"firstSeen(address)\":{\"notice\":\"Tracks when a keeper was first registered\"},\"forceLiquidityCreditsToJob(address,uint256)\":{\"notice\":\"Gifts liquidity credits to the specified job\"},\"governance()\":{\"notice\":\"Stores the governance address\"},\"hasBonded(address)\":{\"notice\":\"Checks whether the address has ever bonded an asset\"},\"inflationPeriod()\":{\"notice\":\"The inflation period is the denominator used to regulate the emission of KP3R\"},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"notice\":\"Confirms if the current keeper is registered and has a minimum bond of any asset.\"},\"isKeeper(address)\":{\"notice\":\"Confirms if the current keeper is registered\"},\"jobLiquidityCredits(address)\":{\"notice\":\"Returns the liquidity credits of a given job\"},\"jobOwner(address)\":{\"notice\":\"Maps the job to the owner of the job\"},\"jobPendingOwner(address)\":{\"notice\":\"Maps the job to its pending owner\"},\"jobPeriodCredits(address)\":{\"notice\":\"Returns the credits of a given job for the current period\"},\"jobTokenCredits(address,address)\":{\"notice\":\"The current token credits available for a job\"},\"jobTokenCreditsAddedAt(address,address)\":{\"notice\":\"Last block where tokens were added to the job\"},\"jobs()\":{\"notice\":\"Lists all jobs\"},\"keep3rHelper()\":{\"notice\":\"Address of Keep3rHelper's contract\"},\"keep3rV1()\":{\"notice\":\"Address of Keep3rV1's contract\"},\"keep3rV1Proxy()\":{\"notice\":\"Address of Keep3rV1Proxy's contract\"},\"keepers()\":{\"notice\":\"Lists all keepers\"},\"liquidityAmount(address,address)\":{\"notice\":\"Amount of liquidity in a specified job\"},\"liquidityMinimum()\":{\"notice\":\"The minimum amount of liquidity required to fund a job per liquidity\"},\"migrateJob(address,address)\":{\"notice\":\"Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\"},\"observeLiquidity(address)\":{\"notice\":\"Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\"},\"pendingBonds(address,address)\":{\"notice\":\"Tracks the amount of assets deposited in pending bonds\"},\"pendingGovernance()\":{\"notice\":\"Stores the pendingGovernance address\"},\"pendingJobMigrations(address)\":{\"notice\":\"Maps the jobs that have requested a migration to the address they have requested to migrate to\"},\"pendingUnbonds(address,address)\":{\"notice\":\"Tracks how much keeper bonds are to be withdrawn\"},\"quoteLiquidity(address,uint256)\":{\"notice\":\"Calculates how many credits should be rewarded periodically for a given liquidity amount\"},\"removeDisputer(address)\":{\"notice\":\"Removes a disputer by updating the disputers mapping\"},\"removeSlasher(address)\":{\"notice\":\"Removes a slasher by updating the slashers mapping\"},\"resolve(address)\":{\"notice\":\"Allows governance to resolve a dispute on a keeper/job\"},\"revoke(address)\":{\"notice\":\"Blacklists a keeper from participating in the network\"},\"revokeLiquidity(address)\":{\"notice\":\"Revoke a liquidity pair from being accepted in future\"},\"rewardPeriodTime()\":{\"notice\":\"The amount of time between each scheduled credits reward given to a job\"},\"rewardedAt(address)\":{\"notice\":\"Last time the job was rewarded liquidity credits\"},\"sendDust(address,uint256,address)\":{\"notice\":\"Allows an authorized user to transfer the tokens or eth that may have been left in a contract\"},\"setBondTime(uint256)\":{\"notice\":\"Sets the bond time required to activate as a keeper\"},\"setFee(uint256)\":{\"notice\":\"Sets the new fee\"},\"setGovernance(address)\":{\"notice\":\"Proposes a new address to be governance\"},\"setInflationPeriod(uint256)\":{\"notice\":\"Sets the new inflation period\"},\"setKeep3rHelper(address)\":{\"notice\":\"Sets the Keep3rHelper address\"},\"setKeep3rV1(address)\":{\"notice\":\"Sets the Keep3rV1 address\"},\"setKeep3rV1Proxy(address)\":{\"notice\":\"Sets the Keep3rV1Proxy address\"},\"setLiquidityMinimum(uint256)\":{\"notice\":\"Sets the minimum amount of liquidity required to fund a job\"},\"setRewardPeriodTime(uint256)\":{\"notice\":\"Sets the time required to pass between rewards for jobs\"},\"setUnbondTime(uint256)\":{\"notice\":\"Sets the unbond time required unbond what has been bonded\"},\"slash(address,address,uint256,uint256)\":{\"notice\":\"Allows governance to slash a keeper based on a dispute\"},\"slashLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Allows governance or a slasher to slash liquidity from a job\"},\"slashTokenFromJob(address,address,uint256)\":{\"notice\":\"Allows governance or slasher to slash a job specific token\"},\"slashers(address)\":{\"notice\":\"Tracks whether the address is a slasher or not\"},\"totalBonds()\":{\"notice\":\"Tracks the total amount of bonded KP3Rs in the contract\"},\"totalJobCredits(address)\":{\"notice\":\"Calculates the total credits of a given job\"},\"unbond(address,uint256)\":{\"notice\":\"Beginning of the unbonding process\"},\"unbondLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Unbond liquidity for a job\"},\"unbondTime()\":{\"notice\":\"The amount of time required to pass before a keeper can unbond what he has bonded\"},\"virtualReserves()\":{\"notice\":\"The surplus amount of wKP3Rs in escrow contract\"},\"withdraw(address)\":{\"notice\":\"Withdraw funds after unbonding has finished\"},\"withdrawLiquidityFromJob(address,address,address)\":{\"notice\":\"Withdraw liquidity from a job\"},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"notice\":\"Withdraw credit from a job\"},\"workCompleted(address)\":{\"notice\":\"Tracks the total KP3R earnings of a keeper since it started working\"},\"worked(address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"workedAt(address)\":{\"notice\":\"Last time the job was worked\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/for-test/testnet/Keep3rSidechainForTestnet.sol\":\"Keep3rSidechainForTestnet\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":33},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"solidity/contracts/Keep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../interfaces/IKeep3r.sol';\\nimport './peripherals/jobs/Keep3rJobs.sol';\\nimport './peripherals/keepers/Keep3rKeepers.sol';\\nimport './peripherals/DustCollector.sol';\\n\\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\\n constructor(\\n address _governance,\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\\n}\\n\",\"keccak256\":\"0x8b7a11409585a734b97d64773753921ea64b17ea6ee45d712d0478898990a8b0\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/DustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '../../contracts/peripherals/Governable.sol';\\nimport '../../interfaces/peripherals/IDustCollector.sol';\\n\\nabstract contract DustCollector is IDustCollector, Governable {\\n using SafeERC20 for IERC20;\\n\\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external override onlyGovernance {\\n if (_to == address(0)) revert ZeroAddress();\\n if (_token == _ETH_ADDRESS) {\\n payable(_to).transfer(_amount);\\n } else {\\n IERC20(_token).safeTransfer(_to, _amount);\\n }\\n emit DustSent(_token, _amount, _to);\\n }\\n}\\n\",\"keccak256\":\"0x246ac2c4057520bb627ea8040367549786f4477a04fd79358927cd607952bc2f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IGovernable.sol';\\n\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public override governance;\\n\\n /// @inheritdoc IGovernable\\n address public override pendingGovernance;\\n\\n constructor(address _governance) {\\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\\n governance = _governance;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setGovernance(address _governance) external override onlyGovernance {\\n pendingGovernance = _governance;\\n emit GovernanceProposal(_governance);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptGovernance() external override onlyPendingGovernance {\\n governance = pendingGovernance;\\n delete pendingGovernance;\\n emit GovernanceSet(governance);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governance\\n modifier onlyGovernance {\\n if (msg.sender != governance) revert OnlyGovernance();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernance\\n modifier onlyPendingGovernance {\\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5b6d7601a42d2229657a7f60021c7e2bfe890c3541ab0003f7d88e20a28d722b\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\\nimport './Keep3rRoles.sol';\\n\\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @notice List of all enabled keepers\\n EnumerableSet.AddressSet internal _keepers;\\n\\n /// @inheritdoc IKeep3rAccountance\\n uint256 public override totalBonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override workCompleted;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override firstSeen;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override disputes;\\n\\n /// @inheritdoc IKeep3rAccountance\\n /// @notice Mapping (job => bonding => amount)\\n mapping(address => mapping(address => uint256)) public override bonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\\n\\n /// @notice The current liquidity credits available for a job\\n mapping(address => uint256) internal _jobLiquidityCredits;\\n\\n /// @notice Map the address of a job to its correspondent periodCredits\\n mapping(address => uint256) internal _jobPeriodCredits;\\n\\n /// @notice Enumerable array of Job Tokens for Credits\\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\\n\\n /// @notice List of liquidities that a job has (job => liquidities)\\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\\n\\n /// @notice Liquidity pool to observe\\n mapping(address => address) internal _liquidityPool;\\n\\n /// @notice Tracks if a pool has KP3R as token0\\n mapping(address => bool) internal _isKP3RToken0;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingBonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override hasBonded;\\n\\n /// @notice List of all enabled jobs\\n EnumerableSet.AddressSet internal _jobs;\\n\\n /// @inheritdoc IKeep3rAccountance\\n function jobs() external view override returns (address[] memory _list) {\\n _list = _jobs.values();\\n }\\n\\n /// @inheritdoc IKeep3rAccountance\\n function keepers() external view override returns (address[] memory _list) {\\n _list = _keepers.values();\\n }\\n}\\n\",\"keccak256\":\"0xcd2a525e6567eea4f2a7f93e8eb686e484d2a078686f2744dde35a8383881730\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rParameters.sol';\\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\\n\\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\\n /// @inheritdoc IKeep3rDisputable\\n function dispute(address _jobOrKeeper) external override onlyDisputer {\\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\\n disputes[_jobOrKeeper] = true;\\n emit Dispute(_jobOrKeeper, msg.sender);\\n }\\n\\n /// @inheritdoc IKeep3rDisputable\\n function resolve(address _jobOrKeeper) external override onlyDisputer {\\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\\n disputes[_jobOrKeeper] = false;\\n emit Resolve(_jobOrKeeper, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x664b54040aa4e734f68a01fcfb5bf67cbb1a70efd03862cd3a456457536b1fb4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/IKeep3rHelper.sol';\\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\\nimport './Keep3rAccountance.sol';\\n\\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1Proxy;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rHelper;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override bondTime = 3 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override unbondTime = 14 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override liquidityMinimum = 3 ether;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override rewardPeriodTime = 5 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override inflationPeriod = 34 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override fee = 30;\\n\\n /// @notice The base that will be used to calculate the fee\\n uint256 internal constant _BASE = 10_000;\\n\\n /// @notice The minimum reward period\\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\\n\\n constructor(\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) {\\n keep3rHelper = _keep3rHelper;\\n keep3rV1 = _keep3rV1;\\n keep3rV1Proxy = _keep3rV1Proxy;\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\\n if (_keep3rHelper == address(0)) revert ZeroAddress();\\n keep3rHelper = _keep3rHelper;\\n emit Keep3rHelperChange(_keep3rHelper);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\\n if (_keep3rV1 == address(0)) revert ZeroAddress();\\n _mint(totalBonds);\\n\\n keep3rV1 = _keep3rV1;\\n emit Keep3rV1Change(_keep3rV1);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\\n keep3rV1Proxy = _keep3rV1Proxy;\\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\\n bondTime = _bondTime;\\n emit BondTimeChange(_bondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\\n unbondTime = _unbondTime;\\n emit UnbondTimeChange(_unbondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\\n liquidityMinimum = _liquidityMinimum;\\n emit LiquidityMinimumChange(_liquidityMinimum);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\\n rewardPeriodTime = _rewardPeriodTime;\\n emit RewardPeriodTimeChange(_rewardPeriodTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\\n inflationPeriod = _inflationPeriod;\\n emit InflationPeriodChange(_inflationPeriod);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setFee(uint256 _fee) external override onlyGovernance {\\n fee = _fee;\\n emit FeeChange(_fee);\\n }\\n\\n function _mint(uint256 _amount) internal {\\n totalBonds -= _amount;\\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\\n }\\n}\\n\",\"keccak256\":\"0x180349c0ff1fffec1566fba13b494595dcc5ca7eaf049d3f7a2a8d1c60de7d0f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport './DustCollector.sol';\\nimport './Governable.sol';\\n\\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override slashers;\\n\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override disputers;\\n\\n constructor(address _governance) Governable(_governance) DustCollector() {}\\n\\n /// @inheritdoc IKeep3rRoles\\n function addSlasher(address _slasher) external override onlyGovernance {\\n if (_slasher == address(0)) revert ZeroAddress();\\n if (slashers[_slasher]) revert SlasherExistent();\\n slashers[_slasher] = true;\\n emit SlasherAdded(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeSlasher(address _slasher) external override onlyGovernance {\\n if (!slashers[_slasher]) revert SlasherUnexistent();\\n delete slashers[_slasher];\\n emit SlasherRemoved(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function addDisputer(address _disputer) external override onlyGovernance {\\n if (_disputer == address(0)) revert ZeroAddress();\\n if (disputers[_disputer]) revert DisputerExistent();\\n disputers[_disputer] = true;\\n emit DisputerAdded(_disputer);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeDisputer(address _disputer) external override onlyGovernance {\\n if (!disputers[_disputer]) revert DisputerUnexistent();\\n delete disputers[_disputer];\\n emit DisputerRemoved(_disputer);\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a slasher or governance\\n modifier onlySlasher {\\n if (!slashers[msg.sender]) revert OnlySlasher();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a disputer or governance\\n modifier onlyDisputer {\\n if (!disputers[msg.sender]) revert OnlyDisputer();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x61a1cf0d52db8fe78fa8cfb76d9b02f93ef3adc23e6655969bc1a4bb83ea9a95\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\nimport '../Keep3rDisputable.sol';\\n\\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\\n\\n try IERC20(_token).transfer(governance, _amount) {} catch {}\\n jobTokenCredits[_job][_token] -= _amount;\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit JobSlashToken(_job, _token, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x86cdbf44dfa46c6b6e184e48e11cb8571e26cf50c793b6b07227c29e743da397\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice Cooldown between withdrawals\\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n // KP3R shouldn't be used for direct token payments\\n if (_token == keep3rV1) revert TokenUnallowed();\\n uint256 _before = IERC20(_token).balanceOf(address(this));\\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\\n uint256 _tokenFee = (_received * fee) / _BASE;\\n jobTokenCredits[_job][_token] += _received - _tokenFee;\\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\\n IERC20(_token).safeTransfer(governance, _tokenFee);\\n _jobTokens[_job].add(_token);\\n\\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external override nonReentrant onlyJobOwner(_job) {\\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\\n if (disputes[_job]) revert JobDisputed();\\n\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xb600d18903a008a1ca03743de7cef8330c2d5e66db52c900822551a4be75f7a5\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/IPairManager.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '../../libraries/FullMath.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice List of liquidities that are accepted in the system\\n EnumerableSet.AddressSet internal _approvedLiquidities;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override rewardedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override workedAt;\\n\\n /// @notice Tracks an address and returns its TickCache\\n mapping(address => TickCache) internal _tick;\\n\\n // Views\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approvedLiquidities() external view override returns (address[] memory _list) {\\n _list = _approvedLiquidities.values();\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n _periodCredits += _getReward(\\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\\n );\\n }\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n\\n // If the job was rewarded in the past 1 period time\\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\\n // If the job has period credits, update minted job credits to new twap\\n _liquidityCredits = _periodCredits > 0\\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\\n } else {\\n // Else return a full period worth of credits if current credits have expired\\n _liquidityCredits = _periodCredits;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n uint256 _cooldown = block.timestamp;\\n\\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\\n // Will calculate cooldown if it outdated\\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will calculate cooldown from last reward reference in this period\\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\\n } else {\\n // Will calculate cooldown from last reward timestamp\\n _cooldown -= rewardedAt[_job];\\n }\\n } else {\\n // Will calculate cooldown from period start if expired\\n _cooldown -= _period(block.timestamp);\\n }\\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\\n if (_tick[_liquidity].period == _period(block.timestamp)) {\\n // Will return cached twaps if liquidity is updated\\n _tickCache = _tick[_liquidity];\\n } else {\\n bool success;\\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\\n\\n if (_tick[_liquidity].period == lastPeriod) {\\n // Will only ask for current period accumulator if liquidity is outdated\\n uint32[] memory _secondsAgo = new uint32[](1);\\n int56 previousTick = _tick[_liquidity].current;\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n\\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - previousTick;\\n } else if (_tick[_liquidity].period < lastPeriod) {\\n // Will ask for 2 accumulators if liquidity is expired\\n uint32[] memory _secondsAgo = new uint32[](2);\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\\n\\n int56 _tickCumulative2;\\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - _tickCumulative2;\\n }\\n if (success) {\\n _tickCache.period = _period(block.timestamp);\\n } else {\\n delete _tickCache.period;\\n }\\n }\\n }\\n\\n // Methods\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n _settleJobAccountance(_job);\\n _jobLiquidityCredits[_job] += _amount;\\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n emit LiquidityApproval(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\\n delete _liquidityPool[_liquidity];\\n delete _isKP3RToken0[_liquidity];\\n delete _tick[_liquidity];\\n\\n emit LiquidityRevocation(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n\\n _jobLiquidities[_job].add(_liquidity);\\n\\n _settleJobAccountance(_job);\\n\\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\\n liquidityAmount[_job][_liquidity] += _amount;\\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlyJobOwner(_job) {\\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\\n pendingUnbonds[_job][_liquidity] += _amount;\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n\\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit Unbonding(_job, _liquidity, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external override onlyJobOwner(_job) {\\n if (_receiver == address(0)) revert ZeroAddress();\\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[_job]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[_job][_liquidity];\\n\\n delete pendingUnbonds[_job][_liquidity];\\n delete canWithdrawAfter[_job][_liquidity];\\n\\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\\n }\\n\\n // Internal functions\\n\\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\\n if (rewardedAt[_job] < _period(block.timestamp)) {\\n // Will exit function if job has been rewarded in current period\\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\\n // Will reset job to period syncronicity if a full period passed without rewards\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] = _period(block.timestamp);\\n _rewarded = true;\\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will reset job's syncronicity if last reward was more than epoch ago\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] += rewardPeriodTime;\\n _rewarded = true;\\n } else if (workedAt[_job] < _period(block.timestamp)) {\\n // First keeper on period has to update job accountance to current twaps\\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\\n // Updating job accountance does not reward job\\n }\\n }\\n }\\n\\n /// @notice Only called if _jobLiquidityCredits < payment\\n function _rewardJobCredits(address _job) internal {\\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\\n rewardedAt[_job] = block.timestamp;\\n }\\n\\n /// @notice Updates accountance for _jobPeriodCredits\\n function _updateJobPeriod(address _job) internal {\\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\\n }\\n\\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n if (_tick[_liquidity].period != _period(block.timestamp)) {\\n // Updates liquidity cache only if needed\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n }\\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\\n }\\n }\\n }\\n\\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\\n function _unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) internal nonReentrant {\\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\\n\\n // Ensures current twaps in job liquidities\\n _updateJobPeriod(_job);\\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\\n\\n // A liquidity can be revoked causing a job to have 0 periodCredits\\n if (_jobPeriodCredits[_job] > 0) {\\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\\n }\\n\\n liquidityAmount[_job][_liquidity] -= _amount;\\n if (liquidityAmount[_job][_liquidity] == 0) {\\n _jobLiquidities[_job].remove(_liquidity);\\n }\\n }\\n\\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\\n if (_timePassed < rewardPeriodTime) {\\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\\n } else _result = _multiplier;\\n }\\n\\n /// @notice Returns the start of the period of the provided timestamp\\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\\n return _timestamp - (_timestamp % rewardPeriodTime);\\n }\\n\\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\\n }\\n\\n /// @notice Returns underlying KP3R amount for a given liquidity amount\\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\\n if (_tick[_liquidity].period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\\n }\\n }\\n\\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\\n /// @dev Ensures a maximum of 1 period of credits\\n function _settleJobAccountance(address _job) internal virtual {\\n _updateJobCreditsIfNeeded(_job);\\n _rewardJobCredits(_job);\\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n}\\n\",\"keccak256\":\"0xe3b244460364baf1ea293db6f6feba8365fd376320ad77ae6d6813ed65b52929\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @inheritdoc IKeep3rJobManager\\n function addJob(address _job) external override {\\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\\n if (hasBonded[_job]) revert AlreadyAKeeper();\\n _jobs.add(_job);\\n jobOwner[_job] = msg.sender;\\n emit JobAddition(_job, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xf6e1577a6a34b674ca34a6d7530dc81349e3ad13d321281c37e0b25b7325d013\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\n\\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n mapping(address => address) public override pendingJobMigrations;\\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\\n if (_fromJob == _toJob) revert JobMigrationImpossible();\\n\\n pendingJobMigrations[_fromJob] = _toJob;\\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\\n\\n emit JobMigrationRequested(_fromJob, _toJob);\\n }\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\\n\\n // force job credits update for both jobs\\n _settleJobAccountance(_fromJob);\\n _settleJobAccountance(_toJob);\\n\\n // migrate tokens\\n while (_jobTokens[_fromJob].length() > 0) {\\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\\n _jobTokens[_fromJob].remove(_tokenToMigrate);\\n _jobTokens[_toJob].add(_tokenToMigrate);\\n }\\n\\n // migrate liquidities\\n while (_jobLiquidities[_fromJob].length() > 0) {\\n address _liquidity = _jobLiquidities[_fromJob].at(0);\\n\\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\\n delete liquidityAmount[_fromJob][_liquidity];\\n\\n _jobLiquidities[_toJob].add(_liquidity);\\n _jobLiquidities[_fromJob].remove(_liquidity);\\n }\\n\\n // migrate job balances\\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\\n delete _jobPeriodCredits[_fromJob];\\n\\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\\n delete _jobLiquidityCredits[_fromJob];\\n\\n // stop _fromJob from being a job\\n delete rewardedAt[_fromJob];\\n _jobs.remove(_fromJob);\\n\\n // delete unused data slots\\n delete jobOwner[_fromJob];\\n delete jobPendingOwner[_fromJob];\\n delete _migrationCreatedAt[_fromJob][_toJob];\\n delete pendingJobMigrations[_fromJob];\\n\\n emit JobMigrationSuccessful(_fromJob, _toJob);\\n }\\n}\\n\",\"keccak256\":\"0xd46c3c9ce970098d8d75f11966894a341824aceb40583fcfbbc0ebda93d869f9\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobPendingOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\\n jobPendingOwner[_job] = _newOwner;\\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\\n }\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\\n address _previousOwner = jobOwner[_job];\\n\\n jobOwner[_job] = jobPendingOwner[_job];\\n delete jobPendingOwner[_job];\\n\\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\\n }\\n\\n modifier onlyJobOwner(address _job) {\\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\\n _;\\n }\\n\\n modifier onlyPendingJobOwner(address _job) {\\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xa837590ade9cd5d25690e3f2d8b9a63e7202f7179b32e42eab4fa4c4324b9728\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobMigration.sol';\\nimport '../../../interfaces/IKeep3rHelper.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n uint256 internal _initialGas;\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\\n _initialGas = _getGasLeft();\\n if (_keepers.contains(_keeper)) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external override returns (bool _isBondedKeeper) {\\n _initialGas = _getGasLeft();\\n if (\\n _keepers.contains(_keeper) &&\\n bonds[_keeper][_bond] >= _minBond &&\\n workCompleted[_keeper] >= _earned &&\\n block.timestamp - firstSeen[_keeper] >= _age\\n ) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function worked(address _keeper) external virtual override {\\n if (_initialGas == 0) revert GasNotInitialized();\\n address _job = msg.sender;\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\\n\\n uint256 _gasLeft = _getGasLeft();\\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n _gasLeft = _getGasLeft();\\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n delete _initialGas;\\n\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function bondedPayment(address _keeper, uint256 _payment) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (disputes[_keeper]) revert Disputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_keeper, _amount);\\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\\n }\\n\\n function _bondedPayment(\\n address _job,\\n address _keeper,\\n uint256 _payment\\n ) internal {\\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\\n\\n workedAt[_job] = block.timestamp;\\n _jobLiquidityCredits[_job] -= _payment;\\n bonds[_keeper][keep3rV1] += _payment;\\n workCompleted[_keeper] += _payment;\\n totalBonds += _payment;\\n }\\n\\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\\n /// @param _gasLeft Amount of gas left after working the job\\n /// @param _extraGas Amount of expected unaccounted gas\\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\\n /// @return _payment Amount to be payed in KP3R tokens\\n function _calculatePayment(\\n uint256 _gasLeft,\\n uint256 _extraGas,\\n uint256 _oneEthQuote,\\n uint256 _boost\\n ) internal view returns (uint256 _payment) {\\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\\n }\\n\\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\\n _gasLeft = (gasleft() * 64) / 63;\\n }\\n}\\n\",\"keccak256\":\"0x7e113a0815d9125e760ee75c9d9c55fc93192ae2535afccdb8835984d17b510f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobManager.sol';\\nimport './Keep3rJobWorkable.sol';\\nimport './Keep3rJobDisputable.sol';\\n\\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\\n\",\"keccak256\":\"0x882e1a19891795de04c4c891dc58d50034ca0a32c8b61651aaf0f47d0bc321d4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rKeeperFundable.sol';\\nimport '../Keep3rDisputable.sol';\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function revoke(address _keeper) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _keepers.remove(_keeper);\\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\\n emit KeeperRevoke(_keeper, msg.sender);\\n }\\n\\n function _slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) internal {\\n if (_bonded != keep3rV1) {\\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\\n }\\n bonds[_keeper][_bonded] -= _bondAmount;\\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\\n }\\n}\\n\",\"keccak256\":\"0xa15b13218af4331d1fb3e8cfdfa9b69117f291ac9a462ede6b1b4fb5be8967de\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\\n if (disputes[msg.sender]) revert Disputed();\\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\\n\\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\\n\\n hasBonded[msg.sender] = true;\\n pendingBonds[msg.sender][_bonding] += _amount;\\n\\n emit Bonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function activate(address _bonding) external override {\\n address _keeper = msg.sender;\\n if (disputes[_keeper]) revert Disputed();\\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\\n if (_canActivateAfter == 0) revert BondsUnexistent();\\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\\n\\n if (firstSeen[_keeper] == 0) {\\n firstSeen[_keeper] = block.timestamp;\\n }\\n _keepers.add(_keeper);\\n\\n uint256 _amount = pendingBonds[_keeper][_bonding];\\n delete pendingBonds[_keeper][_bonding];\\n\\n // bond provided tokens\\n bonds[_keeper][_bonding] += _amount;\\n if (_bonding == keep3rV1) {\\n totalBonds += _amount;\\n _depositBonds(_amount);\\n }\\n\\n emit Activation(_keeper, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function unbond(address _bonding, uint256 _amount) external override {\\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\\n bonds[msg.sender][_bonding] -= _amount;\\n pendingUnbonds[msg.sender][_bonding] += _amount;\\n\\n emit Unbonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function withdraw(address _bonding) external override nonReentrant {\\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[msg.sender]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\\n\\n delete pendingUnbonds[msg.sender][_bonding];\\n delete canWithdrawAfter[msg.sender][_bonding];\\n\\n if (_bonding == keep3rV1) _mint(_amount);\\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\\n\\n emit Withdrawal(msg.sender, _bonding, _amount);\\n }\\n\\n function _depositBonds(uint256 _amount) internal virtual {\\n IKeep3rV1(keep3rV1).burn(_amount);\\n }\\n}\\n\",\"keccak256\":\"0x121dc11fa555731679912d54da3bb8282d26ad425deffae6d4d7085ef3c9290d\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\nimport './Keep3rKeeperDisputable.sol';\\n\\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\\n\",\"keccak256\":\"0xfc762d9fd6ff478acba446c3ab6fc19c7d49a85de097dc35f02c56e928153c5e\",\"license\":\"MIT\"},\"solidity/contracts/sidechain/Keep3rSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3r.sol';\\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\\n\\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @param _governance Address of governance\\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\\n constructor(\\n address _governance, // governance\\n address _keep3rHelperSidechain, // helper\\n address _wrappedKP3R, // keep3rV1\\n address _keep3rEscrow // keep3rV1Proxy\\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\\n\\n // Keep3rSidechainAccountance\\n\\n /// @inheritdoc IKeep3rSidechainAccountance\\n function virtualReserves() external view override returns (int256 _virtualReserves) {\\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\\n }\\n\\n // Keep3rJobFundableLiquidity\\n\\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\\n /// @param _liquidity Address of the liquidity token being approved\\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n emit LiquidityApproval(_liquidity);\\n }\\n\\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\\n /// @param _liquidity Address of the liquidity token being observed\\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\\n if (_tick[_liquidity].period == _period(block.timestamp)) {\\n // Will return cached twaps if liquidity is updated\\n _tickCache = _tick[_liquidity];\\n } else {\\n bool success;\\n\\n // Will always ask for 2 accumulators in sidechain\\n uint32[] memory _secondsAgo = new uint32[](2);\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\\n\\n int56 _tickCumulative2;\\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - _tickCumulative2;\\n\\n if (success) {\\n _tickCache.period = _period(block.timestamp);\\n } else {\\n delete _tickCache.period;\\n }\\n }\\n }\\n\\n // Keep3rJobsWorkable\\n\\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\\n function worked(address) external pure override {\\n revert Deprecated();\\n }\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Uses a USD per gas unit payment mechanism\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\\n if (_initialGas == 0) revert GasNotInitialized();\\n // Gas used for quote calculations & payment is not rewarded\\n uint256 _gasLeft = _getGasLeft();\\n\\n address _job = msg.sender;\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\\n\\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\\n\\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n _bondedPayment(_job, _keeper, _kp3rPayment);\\n delete _initialGas;\\n\\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\\n }\\n\\n // Keep3rKeeperFundable\\n\\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\\n function _depositBonds(uint256 _amount) internal virtual override {\\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\\n }\\n}\\n\",\"keccak256\":\"0xd546c5e5c9286e0e8785584d6395c0b4facc58b447351df92934346101b90290\",\"license\":\"MIT\"},\"solidity/for-test/testnet/Keep3rSidechainForTestnet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\\n\\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\\n constructor(\\n address _governance,\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\\n bondTime = 0; // allows keepers to instantly register\\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\\n liquidityMinimum = 1; // allows job providers to add low liquidity\\n rewardPeriodTime = 1 days; // reduces twap calculation period\\n inflationPeriod = 5 days; // increases credit minting\\n }\\n}\\n\",\"keccak256\":\"0xa098eda6b1501e4d252ac77bef69e520e0fa3dd7427626639db3511b07e535bd\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct TokenOraclePool {\\n address poolAddress;\\n bool isTKNToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0x76f99ca04361c0459fc9e99f0387ddb76da18cc470ec5bc744e7dc3bf6e9d334\",\"license\":\"MIT\"},\"solidity/interfaces/IPairManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n/// @title Pair Manager interface\\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\\ninterface IPairManager is IERC20Metadata {\\n /// @notice Address of the factory from which the pair manager was created\\n /// @return _factory The address of the PairManager Factory\\n function factory() external view returns (address _factory);\\n\\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\\n /// @return _pool The address of the pool\\n function pool() external view returns (address _pool);\\n\\n /// @notice Token0 of the pool\\n /// @return _token0 The address of token0\\n function token0() external view returns (address _token0);\\n\\n /// @notice Token1 of the pool\\n /// @return _token1 The address of token1\\n function token1() external view returns (address _token1);\\n}\\n\",\"keccak256\":\"0x345c312b340c5775fb8f68d89ce851c7f75522940bd9bc64f2301a3f8312636a\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IGovernable.sol';\\n\\ninterface IKeep3rV1Proxy is IGovernable {\\n // Structs\\n struct Recipient {\\n address recipient;\\n uint256 caps;\\n }\\n\\n // Variables\\n function keep3rV1() external view returns (address);\\n\\n function minter() external view returns (address);\\n\\n function next(address) external view returns (uint256);\\n\\n function caps(address) external view returns (uint256);\\n\\n function recipients() external view returns (address[] memory);\\n\\n function recipientsCaps() external view returns (Recipient[] memory);\\n\\n // Errors\\n error Cooldown();\\n error NoDrawableAmount();\\n error ZeroAddress();\\n error OnlyMinter();\\n\\n // Methods\\n function addRecipient(address recipient, uint256 amount) external;\\n\\n function removeRecipient(address recipient) external;\\n\\n function draw() external returns (uint256 _amount);\\n\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n function setMinter(address _minter) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function mint(address _account, uint256 _amount) external;\\n\\n function setKeep3rV1Governance(address _governance) external;\\n\\n function acceptKeep3rV1Governance() external;\\n\\n function dispute(address _keeper) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function addJob(address _job) external;\\n\\n function removeJob(address _job) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n}\\n\",\"keccak256\":\"0xfb2e81fe347b39aabce849ef2d42c6df846b7ef0ed5ae952c85bbb708da99408\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Throws if a variable is assigned to the zero address\\n error ZeroAddress();\\n}\\n\",\"keccak256\":\"0x9130019a08d9eaedfb920a323fed5c7f409736cd918f1a32921c93551b3ee00e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\n\\ninterface IDustCollector is IBaseErrors {\\n /// @notice Emitted when dust is sent\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address which will receive the funds\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(\\n address _token,\\n uint256 _amount,\\n address _to\\n ) external;\\n}\\n\",\"keccak256\":\"0x38dce228111f2a3c6b26ac09c5652c3f1f184c4cfe50d11ff0958ef6a50683bb\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Governable contract\\n/// @notice Manages the governance role\\ninterface IGovernable {\\n // Events\\n\\n /// @notice Emitted when pendingGovernance accepts to be governance\\n /// @param _governance Address of the new governance\\n event GovernanceSet(address _governance);\\n\\n /// @notice Emitted when a new governance is proposed\\n /// @param _pendingGovernance Address that is proposed to be the new governance\\n event GovernanceProposal(address _pendingGovernance);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not governance\\n error OnlyGovernance();\\n\\n /// @notice Throws if the caller of the function is not pendingGovernance\\n error OnlyPendingGovernance();\\n\\n /// @notice Throws if trying to set governance to zero address\\n error NoGovernanceZeroAddress();\\n\\n // Variables\\n\\n /// @notice Stores the governance address\\n /// @return _governance The governance addresss\\n function governance() external view returns (address _governance);\\n\\n /// @notice Stores the pendingGovernance address\\n /// @return _pendingGovernance The pendingGovernance addresss\\n function pendingGovernance() external view returns (address _pendingGovernance);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be governance\\n /// @param _governance The address being proposed as the new governance\\n function setGovernance(address _governance) external;\\n\\n /// @notice Changes the governance from the current governance to the previously proposed address\\n function acceptGovernance() external;\\n}\\n\",\"keccak256\":\"0x3284624b2479bbf97c821f37c93a096dcb869b30bbf9b20d30d1800f9535452c\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0xf4748c236ddf409e45e7169c735e2fc54e627b2b3ccd189ebb438ad768f1deb1\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governance to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governance to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0x002b9b4c75e62d48d74b6447649d39eb5c1e128d2523bb11e08e9cd3e27b1f70\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governance or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governance or a slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x08915189f1a9484d17a51b7fb343b765b9edba29062bb644af9663af18f03e34\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governance to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0xc95e6bba82a8371c6bd15a8e9d0df91c826b5050b8ee01d913c1c13a4e92a49b\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x942f99c6e3b229a551faaae8f03000b934b20502a7cfade14780508201fd098e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IBaseErrors.sol';\\nimport './IGovernable.sol';\\nimport './IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xe6eca166cf6ad99e5379d754030222873bb9868ff3e2a76de815a438ead533a2\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IMintable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IGovernable.sol';\\nimport './IBaseErrors.sol';\\n\\n/// @title Mintable contract\\n/// @notice Manages the minter role\\ninterface IMintable is IBaseErrors, IGovernable {\\n // Events\\n\\n /// @notice Emitted when governance sets a new minter\\n /// @param _minter Address of the new minter\\n event MinterSet(address _minter);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not the minter\\n error OnlyMinter();\\n\\n // Variables\\n\\n /// @notice Stores the minter address\\n /// @return _minter The minter addresss\\n function minter() external view returns (address _minter);\\n\\n // Methods\\n\\n /// @notice Sets a new address to be the minter\\n /// @param _minter The address set as the minter\\n function setMinter(address _minter) external;\\n}\\n\",\"keccak256\":\"0x255f4ed4b7c4ddf4fcff9db7524365ef734806583acca7c7912e867f110d9c81\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\nimport '../peripherals/IMintable.sol';\\n\\n/// @title Keep3rEscrow contract\\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\\ninterface IKeep3rEscrow is IMintable {\\n /// @notice Emitted when Keep3rEscrow#deposit function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _sender The address that called the function\\n /// @param _amount The amount of wKP3R the user deposited\\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#mint function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _recipient The address that will received the newly minted wKP3R\\n /// @param _amount The amount of wKP3R minted to the recipient\\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\\n /// @param _newWKP3R The address of the wKP3R contract\\n event wKP3RSet(address _newWKP3R);\\n\\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\\n error InsufficientBalance();\\n\\n /// @notice Lists the address of the wKP3R contract\\n /// @return _wKP3RAddress The address of wKP3R\\n function wKP3R() external view returns (address _wKP3RAddress);\\n\\n /// @notice Deposits wKP3R into the contract\\n /// @param _amount The amount of wKP3R to deposit\\n function deposit(uint256 _amount) external;\\n\\n /// @notice mints wKP3R to the recipient\\n /// @param _amount The amount of wKP3R to mint\\n function mint(uint256 _amount) external;\\n\\n /// @notice sets the wKP3R address\\n /// @param _wKP3R the wKP3R address\\n function setWKP3R(address _wKP3R) external;\\n}\\n\",\"keccak256\":\"0xf4796dde1afba7f50805aeae92ac0a4848525aeca8355d9b1c6b36c15cca4322\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../IKeep3rHelper.sol';\\n\\n/// @title Keep3rHelperSidechain contract\\n/// @notice Contains all the helper functions for sidechain keep3r implementations\\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\\n // Events\\n\\n /// @notice The oracle for a liquidity has been saved\\n /// @param _liquidity The address of the given liquidity\\n /// @param _oraclePool The address of the oracle pool\\n event OracleSet(address _liquidity, address _oraclePool);\\n\\n /// @notice Emitted when the WETH USD pool is changed\\n /// @param _address Address of the new WETH USD pool\\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\\n\\n /// Variables\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n /// @return _weth Address of WETH token\\n // solhint-disable func-name-mixedcase\\n function WETH() external view returns (address _weth);\\n\\n /// @return _oracle The address of the observable pool for given liquidity\\n function oracle(address _liquidity) external view returns (address _oracle);\\n\\n /// @notice WETH-USD pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\\n\\n /// @notice Quotes USD to ETH\\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\\n /// @param _usd The amount of USD to quote to ETH\\n /// @return _eth The resulting amount of ETH after quoting the USD\\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\\n\\n /// Methods\\n\\n /// @notice Sets an oracle for a given liquidity\\n /// @param _liquidity The address of the liquidity\\n /// @param _oracle The address of the pool used to quote the liquidity from\\n /// @dev The oracle must contain KP3R as either token0 or token1\\n function setOracle(address _liquidity, address _oracle) external;\\n\\n /// @notice Sets an oracle for querying WETH/USD quote\\n /// @param _poolAddress The address of the pool used as oracle\\n /// @dev The oracle must contain WETH as either token0 or token1\\n function setWethUsdPool(address _poolAddress) external;\\n}\\n\",\"keccak256\":\"0xb6d5459e8a47ab09a052e1acac1c28304f9f0762d20f01819559b4d39729c987\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IKeep3rJobs.sol';\\n\\n/// @title Keep3rJobWorkableRated contract\\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\\n /// @notice Throws when job contract calls deprecated worked(address) function\\n error Deprecated();\\n\\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\\n}\\n\",\"keccak256\":\"0xce2c2721f1df7d944bf3ae20331cb628d38247e667c47bf4a33a90f0b5753884\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title IKeep3rSidechainAccountance interface\\n/// @notice Implements a view to get the amount of credits that can be withdrawn\\ninterface IKeep3rSidechainAccountance {\\n /// @notice The surplus amount of wKP3Rs in escrow contract\\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\\n function virtualReserves() external view returns (int256 _virtualReserves);\\n}\\n\",\"keccak256\":\"0x4c11242f13d72b5db97e89672d09a771abb903e795ff85588d02c8e11fdc435e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040526203f480601f55621275006020556729a2241af62c000060215562069780602255622cd300602355601e6024553480156200003e57600080fd5b506040516200603238038062006032833981016040819052620000619162000133565b6001600055838383838383838382828286806001600160a01b0381166200009a5760405162b293ed60e81b815260040160405180910390fd5b600380546001600160a01b03199081166001600160a01b0393841617909155601e8054821696831696909617909555601c805486169482169490941790935550601d8054909316911617905550506000601f81905560205550506001602155505062015180602255505062069780602355506200019092505050565b80516001600160a01b03811681146200012e57600080fd5b919050565b600080600080608085870312156200014a57600080fd5b620001558562000116565b9350620001656020860162000116565b9250620001756040860162000116565b9150620001856060860162000116565b905092959194509250565b615e9280620001a06000396000f3fe608060405234801561001057600080fd5b50600436106104075760003560e01c8063966abd0011610228578063c5198abc1161013c578063ec8ca643116100be578063ec8ca64314610add578063f0f346b914610b06578063f11a1d1a14610b19578063f136a09d14610b2c578063f25e311b14610b4c578063f263c47014610b5f578063f39c38a014610b68578063f75f9f7b14610b7b578063f9d46cf214610b8e578063fc253d2b14610ba1578063fe75bc4614610baa57600080fd5b8063c5198abc146109f1578063c7ae40d014610a04578063cb4be2bb14610a17578063cb54694d14610a2a578063cd22af1b14610a3d578063d55995fe14610a68578063dd2080d614610a7b578063ddca3f4314610a8e578063e326ac4314610a97578063ebbb619414610ab7578063ec00cdfc14610aca57600080fd5b8063966abd001461080457806398e90a0f146108175780639d5c33d814610840578063a214580914610853578063a39744b514610866578063a515366a14610891578063a5d059ca146108a4578063a676f9ff146108b7578063a7d2e784146108d7578063aac6aa9c146108e0578063ab033ea9146108f3578063af320e8114610906578063b0103b1a14610919578063b0f328f11461093c578063b239223314610944578063b440027f14610957578063b600702a14610982578063b70362b914610995578063b7e77340146109a8578063b87fcbff146109bb578063c20297f0146109de57600080fd5b80635aa6e6751161031f5780635aa6e6751461066b5780635ebe23f01461067e5780635feeb79414610687578063633fb68f1461069a57806364bb43ee146106a357806368a9f19c146106b6578063694798e6146106c957806369fe0e2d146106f45780636ba42aaa146107075780636cf262bc1461071a5780636e2a9ca61461072d57806372da828a1461074057806374a8f10314610753578063768b5d90146107665780637c8fce231461076f578063878c723e146107775780638bb6dfa8146107a05780638cb22b76146107b35780638fe204dd146107d657806390a4684e146107e9578063951dc22c146107fc57600080fd5b8063034d4c611461040c57806307b435c2146104325780630c620bce1461045d5780630d6a1f87146104725780631101eb411461048557806311466d721461049a57806315006b82146104ad578063165e62e7146104d8578063168f92e7146105155780631b44555e146105405780631c5a9d9c146105605780631ef94b911461057357806321040b0114610593578063238efcbc146105be578063274a8db4146105c657806351cff8d9146105f957806352a4de291461060c57806355ea6c471461061f578063575288bf14610632578063594a3a931461064557806359a2255e14610658575b600080fd5b61041f61041a3660046157a4565b610bbd565b6040519081526020015b60405180910390f35b61041f6104403660046157de565b601760209081526000928352604080842090915290825290205481565b610465610cc3565b6040516104299190615b53565b61041f61048036600461598d565b610cd4565b610498610493366004615862565b610dda565b005b6104986104a836600461598d565b610f34565b61041f6104bb3660046157de565b601560209081526000928352604080842090915290825290205481565b6104eb6104e63660046157a4565b6110c3565b604080518251600690810b825260208085015190910b908201529181015190820152606001610429565b61041f6105233660046157de565b600e60209081526000928352604080842090915290825290205481565b61041f61054e3660046157a4565b600a6020526000908152604090205481565b61049861056e3660046157a4565b6112f0565b601c54610586906001600160a01b031681565b6040516104299190615aca565b61041f6105a13660046157de565b601860209081526000928352604080842090915290825290205481565b6104986114ab565b6105e96105d43660046157a4565b60066020526000908152604090205460ff1681565b6040519015158152602001610429565b6104986106073660046157a4565b611537565b61049861061a366004615862565b6116cf565b61049861062d3660046157a4565b611900565b610498610640366004615862565b6119b4565b6104986106533660046157de565b611c77565b6104986106663660046157a4565b611d1c565b600354610586906001600160a01b031681565b61041f601f5481565b6104986106953660046157a4565b611dce565b61041f60215481565b6104986106b13660046157a4565b611de7565b6104986106c43660046157a4565b611ec8565b61041f6106d73660046157de565b602860209081526000928352604080842090915290825290205481565b610498610702366004615a4e565b611fa7565b6105e96107153660046157a4565b612007565b61041f6107283660046157a4565b612067565b61049861073b366004615862565b61219d565b61049861074e3660046157a4565b6122ec565b6104986107613660046157a4565b612389565b61041f60225481565b610465612484565b6105866107853660046157a4565b6001602052600090815260409020546001600160a01b031681565b61041f6107ae3660046157a4565b612490565b6105e96107c13660046157a4565b60196020526000908152604090205460ff1681565b6104986107e4366004615a4e565b612533565b6104986107f73660046157de565b612591565b61046561267f565b6104986108123660046159b9565b61268b565b6105866108253660046157a4565b6002602052600090815260409020546001600160a01b031681565b61049861084e3660046157a4565b6127a1565b610498610861366004615817565b612880565b61041f6108743660046157de565b600d60209081526000928352604080842090915290825290205481565b61049861089f36600461598d565b612a50565b6104986108b236600461598d565b612cb1565b61041f6108c53660046157a4565b60296020526000908152604090205481565b61041f60205481565b6104986108ee3660046157a4565b612d8b565b6104986109013660046157a4565b612e3f565b6104986109143660046157de565b612eb5565b6105e96109273660046157a4565b600c6020526000908152604090205460ff1681565b61041f613334565b610498610952366004615a4e565b6133ca565b61041f6109653660046157de565b602560209081526000928352604080842090915290825290205481565b6104986109903660046157a4565b61342a565b6104986109a336600461598d565b613698565b6104986109b6366004615a4e565b61391c565b6105e96109c93660046157a4565b60056020526000908152604090205460ff1681565b6104986109ec3660046158f6565b61397c565b6104986109ff3660046157a4565b613a35565b601d54610586906001600160a01b031681565b610498610a253660046157a4565b613afb565b610498610a38366004615a4e565b613b98565b61041f610a4b3660046157de565b601660209081526000928352604080842090915290825290205481565b610498610a763660046158a3565b613c1c565b610498610a89366004615862565b613e53565b61041f60245481565b61041f610aa53660046157a4565b600b6020526000908152604090205481565b610498610ac5366004615a4e565b613fd0565b610498610ad83660046157a4565b614030565b610586610aeb3660046157a4565b602c602052600090815260409020546001600160a01b031681565b610498610b143660046157a4565b6140d8565b601e54610586906001600160a01b031681565b61041f610b3a3660046157a4565b602a6020526000908152604090205481565b610498610b5a366004615862565b61418c565b61041f60095481565b600454610586906001600160a01b031681565b610498610b893660046157a4565b6143d1565b6105e9610b9c36600461593c565b614489565b61041f60235481565b610498610bb836600461598d565b614572565b600080610bc983612067565b6022549091504290610be490610bdf9083615d13565b614662565b6001600160a01b0385166000908152602960205260409020541115610c88576022546001600160a01b038516600090815260296020526040902054610c299042615d13565b10610c65576022546001600160a01b038516600090815260296020526040902054610c549190615c39565b610c5e9082615d13565b9050610c9e565b6001600160a01b038416600090815260296020526040902054610c5e9082615d13565b610c9142614662565b610c9b9082615d13565b90505b610ca8818361467c565b610cb185612490565b610cbb9190615c39565b949350505050565b6060610ccf60266146a6565b905090565b6000610ce16026846146ba565b15610dd4576000610cf1846110c3565b90508060400151600014610dd2576001600160a01b03841660009081526014602052604081205460ff16610d32578160200151610d2d90615d85565b610d38565b81602001515b601e5460225460405163a0d2710760e01b8152929350610dc9926001600160a01b039092169163a0d2710791610d749189918791600401615c0a565b60206040518083038186803b158015610d8c57600080fd5b505afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190615a67565b6146dc565b92505050610dd4565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610e1657604051636efb4f4160e11b815260040160405180910390fd5b602054610e239042615c39565b6001600160a01b03808616600081815260176020908152604080832094891680845294825280832095909555918152601882528381209281529190529081208054849290610e72908490615c39565b90915550610e8390508484846146ed565b6001600160a01b038085166000908152602860209081526040808320938716835292905220548015801590610ec25750602154610ec082866148fb565b105b15610ee057604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de85604051610f2591815260200190565b60405180910390a35050505050565b336000818152600c602052604090205460ff1615610f655760405163ad2fdf3b60e01b815260040160405180910390fd5b610f70601a826146ba565b610f8c5760405162941a5760e11b815260040160405180910390fd5b610f9581614a19565b15610ff0576001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615e3d83398151915293610fe79390929091615c23565b60405180910390a25b6001600160a01b0381166000908152600f602052604090205482111561106f5761101981614bef565b6001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615e3d833981519152936110669390929091615c23565b60405180910390a25b61107a818484614c7d565b601c546001600160a01b03808516918382169116600080516020615e1d833981519152856110a6614d7a565b6040805192835260208301919091520160405180910390a4505050565b60408051606081018252600080825260208201819052918101919091526110e942614662565b6001600160a01b0383166000908152602b6020526040902060010154141561115f57506001600160a01b03166000908152602b602090815260409182902082516060810184528154600681810b810b810b8352600160381b909104810b810b900b92810192909252600101549181019190915290565b6040805160028082526060820183526000928392919060208301908036833701905050905061118d42614662565b6111979042615d13565b816000815181106111aa576111aa615dee565b602002602001019063ffffffff16908163ffffffff16815250506022546111d042614662565b6111da9042615d13565b6111e49190615c39565b816001815181106111f7576111f7615dee565b63ffffffff909216602092830291909101820152601e546001600160a01b0386811660009081526013909352604080842054905163dc686d9160e01b81529282169263dc686d919261124f9216908690600401615ade565b60606040518083038186803b15801561126757600080fd5b505afa15801561127b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129f9190615a0b565b600692830b90920b80875291945091506112ba908290615cc3565b600690810b900b602085015282156112df576112d542614662565b60408501526112e7565b600060408501525b5050505b919050565b336000818152600c602052604090205460ff1615611321576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b038082166000908152601660209081526040808320938616835292905220548061136557604051636258f48160e01b815260040160405180910390fd5b42811061138557604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600b60205260409020546113be576001600160a01b0382166000908152600b602052604090204290555b6113c9600783614d94565b506001600160a01b038083166000818152601560209081526040808320948816808452948252808320805490849055938352600d825280832094835293905291822080549192839261141c908490615c39565b9091555050601c546001600160a01b03858116911614156114585780600960008282546114499190615c39565b90915550611458905081614da9565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a758360405161149d91815260200190565b60405180910390a350505050565b6004546001600160a01b031633146114d657604051637ef5703160e11b815260040160405180910390fd5b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161152d91615aca565b60405180910390a1565b600260005414156115635760405162461bcd60e51b815260040161155a90615bd3565b60405180910390fd5b600260009081553381526018602090815260408083206001600160a01b03851684529091529020546115a85760405163184c088160e21b815260040160405180910390fd5b3360009081526017602090815260408083206001600160a01b038516845290915290205442116115eb576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600c602052604090205460ff161561161c576040516362e6201d60e01b815260040160405180910390fd5b3360008181526018602090815260408083206001600160a01b038681168086529184528285208054908690559585526017845282852082865290935290832092909255601c541614156116725761167281614e94565b6116866001600160a01b0383163383614edc565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b600260005414156116f25760405162461bcd60e51b815260040161155a90615bd3565b60026000556117026026836146ba565b61171f5760405163e0b6aead60e01b815260040160405180910390fd5b61172a601a846146ba565b61174757604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526012602052604090206117699083614d94565b5061177383614f37565b6021546001600160a01b038085166000908152602860209081526040808320938716835292905220546117b1906117ab908490615c39565b846148fb565b10156117d057604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615e3d8339815191529361181d9390929091615c23565b60405180910390a261183a6001600160a01b038316333084614f95565b6001600160a01b03808416600090815260286020908152604080832093861683529290529081208054839290611871908490615c39565b909155506118849050610dc482846148fb565b6001600160a01b038416600090815260106020526040812080549091906118ac908490615c39565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff1661193057604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16611969576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b600260005414156119d75760405162461bcd60e51b815260040161155a90615bd3565b60026000556119e7601a846146ba565b611a0457604051636211d34960e01b815260040160405180910390fd5b601c546001600160a01b0383811691161415611a325760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038416906370a0823190611a61903090600401615aca565b60206040518083038186803b158015611a7957600080fd5b505afa158015611a8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab19190615a67565b9050611ac86001600160a01b038416333085614f95565b600081846001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611af79190615aca565b60206040518083038186803b158015611b0f57600080fd5b505afa158015611b23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b479190615a67565b611b519190615d13565b9050600061271060245483611b669190615c65565b611b709190615c51565b9050611b7c8183615d13565b6001600160a01b038088166000908152600e60209081526040808320938a1683529290529081208054909190611bb3908490615c39565b90915550506001600160a01b0380871660009081526025602090815260408083208985168085529252909120429055600354611bf0921683614edc565b6001600160a01b0386166000908152601160205260409020611c129086614d94565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611c6291815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611cb357604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611d585760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b6040516331cee75f60e21b815260040160405180910390fd5b6003546001600160a01b03163314611e12576040516354348f0360e01b815260040160405180910390fd5b611e1d602682614fd3565b611e3a57604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600090815260136020908152604080832080546001600160a01b031916905560148252808320805460ff19169055602b90915280822080546001600160701b031916815560010191909155517f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e5690611ebd908390615aca565b60405180910390a150565b6003546001600160a01b03163314611ef3576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116611f1a5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff1615611f545760405163546da66560e11b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b90611ebd908390615aca565b6003546001600160a01b03163314611fd2576040516354348f0360e01b815260040160405180910390fd5b60248190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d90602001611ebd565b6000612011614d7a565b602e5561201f6007836146ba565b156112eb577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e5460405161205791815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b038316600090815260126020526040902061208c90614fe8565b811015612197576001600160a01b03831660009081526012602052604081206120b59083614ff2565b90506120c26026826146ba565b156121845760006120d2826110c3565b90508060400151600014612182576001600160a01b03821660009081526014602052604081205460ff1661211357816020015161210e90615d85565b612119565b81602001515b601e546001600160a01b03888116600090815260286020908152604080832089851684529091529081902054602254915163a0d2710760e01b815294955061217494929093169263a0d2710792610d74928791600401615c0a565b61217e9086615c39565b9450505b505b508061218f81615d56565b91505061206b565b50919050565b3360009081526005602052604090205460ff166121cd57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff16612206576040516310cec38560e21b815260040160405180910390fd5b6122118383836146ed565b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261224592909116908590600401615b3a565b602060405180830381600087803b15801561225f57600080fd5b505af192505050801561228f575060408051601f3d908101601f1916820190925261228c918101906159f0565b60015b6122985761229a565b505b336001600160a01b0316836001600160a01b03167f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e84846040516122df929190615b3a565b60405180910390a3505050565b6003546001600160a01b03163314612317576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661233e5760405163d92e233d60e01b815260040160405180910390fd5b601e80546001600160a01b0319166001600160a01b0383161790556040517f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b090611ebd908390615aca565b3360009081526005602052604090205460ff166123b957604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff166123f2576040516310cec38560e21b815260040160405180910390fd5b6123fd600782614fd3565b50601c546001600160a01b038083166000818152600d602090815260408083209490951680835293815284822054928252601881528482208483529052929092205461244b92849291614ffe565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610ccf601a6146a6565b60008061249c83612067565b6022546001600160a01b038516600090815260296020526040902054919250906124c69042615d13565b1015610dd457600081116124f2576001600160a01b0383166000908152600f602052604090205461252c565b6001600160a01b038316600090815260106020908152604080832054600f90925290912054612522908390615c65565b61252c9190615c51565b9150612197565b6003546001600160a01b0316331461255e576040516354348f0360e01b815260040160405180910390fd5b60208181556040518281527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee29101611ebd565b6001600160a01b0382811660009081526001602052604090205483911633146125cd57604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156126005760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602c6020908152604080832080546001600160a01b0319169588169586179055602d825280832094835293905282902042905590517fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c90612672908590615aca565b60405180910390a2505050565b6060610ccf60076146a6565b6003546001600160a01b031633146126b6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166126dd5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561273e576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015612738573d6000803e3d6000fd5b50612752565b6127526001600160a01b0384168284614edc565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b031633146127cc576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166127f35760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff161561282d5760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19166001179055517f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f90611ebd908390615aca565b6001600160a01b0383811660009081526001602052604090205484911633146128bc57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0382166128e35760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038085166000908152601860209081526040808320938716835292905220546129265760405163184c088160e21b815260040160405180910390fd5b6001600160a01b03808516600090815260176020908152604080832093871683529290522054421161296b576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff16156129a5576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b03808516600081815260186020908152604080832094881680845294825280832080549084905593835260178252808320858452909152812055906129f2908483614edc565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca792886284604051612a4191815260200190565b60405180910390a45050505050565b60026000541415612a735760405162461bcd60e51b815260040161155a90615bd3565b60026000908155338152600c602052604090205460ff1615612aa8576040516362e6201d60e01b815260040160405180910390fd5b612ab3601a336146ba565b15612ad15760405163d7229c4360e01b815260040160405180910390fd5b601f54612ade9042615c39565b3360009081526016602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81529091906370a0823190612b29903090600401615aca565b60206040518083038186803b158015612b4157600080fd5b505afa158015612b55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b799190615a67565b9050612b906001600160a01b038416333085614f95565b6040516370a0823160e01b815281906001600160a01b038516906370a0823190612bbe903090600401615aca565b60206040518083038186803b158015612bd657600080fd5b505afa158015612bea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c0e9190615a67565b612c189190615d13565b336000908152601960209081526040808320805460ff19166001179055601582528083206001600160a01b0388168452909152812080549294508492909190612c62908490615c39565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b602054612cbe9042615c39565b3360008181526017602090815260408083206001600160a01b03881680855290835281842095909555928252600d81528282209382529290925281208054839290612d0a908490615d13565b90915550503360009081526018602090815260408083206001600160a01b038616845290915281208054839290612d42908490615c39565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b03163314612db6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16612def576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19169055517f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d02590611ebd908390615aca565b6003546001600160a01b03163314612e6a576040516354348f0360e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90611ebd908390615aca565b6001600160a01b038181166000908152600160205260409020548291163314612ef157604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1680612f3057506001600160a01b0382166000908152600c602052604090205460ff165b15612f4e5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602c6020526040902054811690831614612f8b57604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602d6020908152604080832093861683529290522054612fbd90603c90615c39565b421015612fdd576040516356248e9760e01b815260040160405180910390fd5b612fe683614f37565b612fef82614f37565b6001600160a01b038316600090815260116020526040812061301090614fe8565b11156130f2576001600160a01b03831660009081526011602052604081206130389082614ff2565b6001600160a01b038086166000908152600e6020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613086908490615c39565b90915550506001600160a01b038085166000818152600e6020908152604080832094861683529381528382208290559181526011909152206130c89082614fd3565b506001600160a01b03831660009081526011602052604090206130eb9082614d94565b5050612fef565b6001600160a01b038316600090815260126020526040812061311390614fe8565b11156131f5576001600160a01b038316600090815260126020526040812061313b9082614ff2565b6001600160a01b03808616600090815260286020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613189908490615c39565b90915550506001600160a01b03808516600090815260286020908152604080832085851684528252808320839055928616825260129052206131cb9082614d94565b506001600160a01b03841660009081526012602052604090206131ee9082614fd3565b50506130f2565b6001600160a01b0380841660009081526010602052604080822054928516825281208054909190613227908490615c39565b90915550506001600160a01b038084166000908152601060209081526040808320839055600f9091528082205492851682528120805490919061326b908490615c39565b90915550506001600160a01b0383166000908152600f6020908152604080832083905560299091528120556132a1601a84614fd3565b506001600160a01b03808416600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602d8352818420958816808552958352818420849055938352602c909152908190208054909216909155517f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f290612672908690615aca565b600954601c54601d546040516370a0823160e01b8152600093926001600160a01b03908116926370a08231926133709290911690600401615aca565b60206040518083038186803b15801561338857600080fd5b505afa15801561339c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133c09190615a67565b610ccf9190615c84565b6003546001600160a01b031633146133f5576040516354348f0360e01b815260040160405180910390fd5b60238190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb6990602001611ebd565b6003546001600160a01b03163314613455576040516354348f0360e01b815260040160405180910390fd5b613460602682614d94565b61347d5760405163f25e6b9f60e01b815260040160405180910390fd5b601e5460405163eb37d34960e01b81526001600160a01b039091169063eb37d349906134ad908490600401615aca565b60206040518083038186803b1580156134c557600080fd5b505afa1580156134d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134fd91906157c1565b6001600160a01b03828116600090815260136020526040902080546001600160a01b0319169290911691821790556135485760405163d92e233d60e01b815260040160405180910390fd5b601e546001600160a01b038281166000908152601360205260409081902054905163696a437b60e01b81529282169263696a437b9261358b921690600401615aca565b60206040518083038186803b1580156135a357600080fd5b505afa1580156135b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135db91906159f0565b6001600160a01b0382166000908152601460205260409020805460ff191691151591909117905561360b816110c3565b6001600160a01b0382166000908152602b60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b161791909117815591810151600190920191909155517fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b90611ebd908390615aca565b602e546136b857604051630262ab9b60e61b815260040160405180910390fd5b60006136c2614d7a565b336000818152600c60205260409020549192509060ff16156136f75760405163ad2fdf3b60e01b815260040160405180910390fd5b613702601a826146ba565b61371e5760405162941a5760e11b815260040160405180910390fd5b61372781614a19565b15613782576001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615e3d833981519152936137799390929091615c23565b60405180910390a25b601e546001600160a01b038581166000908152600d60209081526040808320601c548516845290915280822054905163435b21c160e01b8152600481019190915290928392839291169063435b21c19060240160606040518083038186803b1580156137ed57600080fd5b505afa158015613801573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138259190615a80565b919450925090506000613843868361383d8a87615c65565b87615154565b6001600160a01b0386166000908152600f60205260409020549091508111156138c55761386f85614bef565b6001600160a01b038516600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615e3d833981519152936138bc9390929091615c23565b60405180910390a25b6138d0858983614c7d565b6000602e55601c5460408051838152602081018990526001600160a01b038b81169389821693911691600080516020615e1d833981519152910160405180910390a45050505050505050565b6003546001600160a01b03163314613947576040516354348f0360e01b815260040160405180910390fd5b601f8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b4390602001611ebd565b3360009081526005602052604090205460ff166139ac57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff166139e5576040516310cec38560e21b815260040160405180910390fd5b6139f184848484614ffe565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613a278486615c39565b60405190815260200161149d565b613a40601a826146ba565b15613a5e57604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526019602052604090205460ff1615613a9857604051632f3d320560e01b815260040160405180910390fd5b613aa3601a82614d94565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613b26576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116613b4d5760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383161790556040517feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae25090611ebd908390615aca565b6003546001600160a01b03163314613bc3576040516354348f0360e01b815260040160405180910390fd5b62015180811015613be757604051633f384aad60e21b815260040160405180910390fd5b60228190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d990602001611ebd565b60026000541415613c3f5760405162461bcd60e51b815260040161155a90615bd3565b600260009081556001600160a01b03858116825260016020526040909120548591163314613c8057604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260256020908152604080832093881683529290522054613cb290603c90615c39565b4211613cd157604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054831115613d175760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600c602052604090205460ff1615613d515760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290529081208054859290613d88908490615d13565b90915550613da290506001600160a01b0385168385614edc565b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054613df0576001600160a01b0385166000908152601160205260409020613dee9085614fd3565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613e3f91815260200190565b60405180910390a450506001600055505050565b336000818152600c602052604090205460ff1615613e845760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1615613ebe576040516362e6201d60e01b815260040160405180910390fd5b613ec9601a826146ba565b613ee55760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290522054821115613f2b5760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290529081208054849290613f62908490615d13565b90915550613f7c90506001600160a01b0385168484614edc565b826001600160a01b0316816001600160a01b0316856001600160a01b0316600080516020615e1d83398151915285613fb2614d7a565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b03163314613ffb576040516354348f0360e01b815260040160405180910390fd5b60218190556040518181527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e790602001611ebd565b6003546001600160a01b0316331461405b576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166140825760405163d92e233d60e01b815260040160405180910390fd5b61408d600954614e94565b601c80546001600160a01b0319166001600160a01b0383161790556040517f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf90611ebd908390615aca565b6003546001600160a01b03163314614103576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1661413c57604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19169055517f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e90611ebd908390615aca565b3360009081526005602052604090205460ff166141bc57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff166141f5576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b038316600090815260116020526040902061421790836146ba565b61423457604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600e60209081526040808320938616835292905220548111156142795760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb926142ad92909116908590600401615b3a565b602060405180830381600087803b1580156142c757600080fd5b505af19250505080156142f7575060408051601f3d908101601f191682019092526142f4918101906159f0565b60015b61430057614302565b505b6001600160a01b038084166000908152600e6020908152604080832093861683529290529081208054839290614339908490615d13565b90915550506001600160a01b038084166000908152600e602090815260408083209386168352929052205461438c576001600160a01b038316600090815260116020526040902061438a9083614fd3565b505b336001600160a01b0316836001600160a01b03167f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d31833310484846040516122df929190615b3a565b3360009081526006602052604090205460ff1661440157604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff161561443b576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b6000614493614d7a565b602e556144a16007876146ba565b80156144d257506001600160a01b038087166000908152600d60209081526040808320938916835292905220548411155b80156144f657506001600160a01b0386166000908152600a60205260409020548311155b801561452557506001600160a01b0386166000908152600b602052604090205482906145229042615d13565b10155b15614569577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e5460405161455d91815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b0316331461459d576040516354348f0360e01b815260040160405180910390fd5b6145a8601a836146ba565b6145c557604051636211d34960e01b815260040160405180910390fd5b6145ce82614f37565b6001600160a01b0382166000908152600f6020526040812080548392906145f6908490615c39565b90915550506001600160a01b038216600081815260296020908152604080832054600f909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d192614656928252602082015260400190565b60405180910390a25050565b6000602254826146729190615d71565b610dd49083615d13565b6000602254831015612197576022546146958385615c65565b61469f9190615c51565b9050610dd4565b606060006146b3836151b1565b9392505050565b6001600160a01b038116600090815260018301602052604081205415156146b3565b6000610dd48260225460235461520d565b600260005414156147105760405162461bcd60e51b815260040161155a90615bd3565b600260009081556001600160a01b038416815260126020526040902061473690836146ba565b614752576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b038084166000908152602860209081526040808320938616835292905220548111156147985760405163435b562560e01b815260040160405180910390fd5b6147a1836152bb565b60006147b0610dc483856148fb565b6001600160a01b03851660009081526010602052604090205490915015614866576001600160a01b038416600090815260106020908152604080832054600f90925290912054614801908390615c65565b61480b9190615c51565b6001600160a01b0385166000908152600f602052604081208054909190614833908490615d13565b90915550506001600160a01b03841660009081526010602052604081208054839290614860908490615d13565b90915550505b6001600160a01b0380851660009081526028602090815260408083209387168352929052908120805484929061489d908490615d13565b90915550506001600160a01b038085166000908152602860209081526040808320938716835292905220546148f0576001600160a01b03841660009081526012602052604090206148ee9084614fd3565b505b505060016000555050565b6001600160a01b0381166000908152602b602052604081206001015415610dd4576001600160a01b03821660009081526014602052604081205460ff1661496d576001600160a01b0383166000908152602b602052604090205461496890600160381b900460060b615d85565b614991565b6001600160a01b0383166000908152602b6020526040902054600160381b900460060b5b601e5460225460405163a0d2710760e01b81529293506001600160a01b039091169163a0d27107916149c99188918691600401615c0a565b60206040518083038186803b1580156149e157600080fd5b505afa1580156149f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbb9190615a67565b6000614a2442614662565b6001600160a01b03831660009081526029602052604090205410156112eb57614a5460225442610bdf9190615d13565b6001600160a01b03831660009081526029602052604090205411614aca57614a7b826152bb565b6001600160a01b038216600090815260106020908152604080832054600f90925290912055614aa942614662565b6001600160a01b038316600090815260296020526040902055506001919050565b6022546001600160a01b038316600090815260296020526040902054614af09042615d13565b10614b4c57614afe826152bb565b6001600160a01b038216600090815260106020908152604080832054600f83528184205560225460299092528220805491929091614b3d908490615c39565b90915550600191506112eb9050565b614b5542614662565b6001600160a01b0383166000908152602a602052604090205410156112eb576001600160a01b038216600090815260106020526040902054614b96836152bb565b6001600160a01b038316600090815260106020908152604080832054600f909252909120548291614bc691615c65565b614bd09190615c51565b6001600160a01b0384166000908152600f602052604090205550919050565b6001600160a01b038116600090815260296020526040902054614c3490614c169042615d13565b6001600160a01b03831660009081526010602052604090205461467c565b6001600160a01b0382166000908152600f602052604081208054909190614c5c908490615c39565b90915550506001600160a01b03166000908152602960205260409020429055565b6001600160a01b0383166000908152600f6020526040902054811115614cb65760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602a60209081526040808320429055600f90915281208054839290614ceb908490615d13565b90915550506001600160a01b038083166000908152600d60209081526040808320601c5490941683529290529081208054839290614d2a908490615c39565b90915550506001600160a01b0382166000908152600a602052604081208054839290614d57908490615c39565b925050819055508060096000828254614d709190615c39565b9091555050505050565b6000603f5a614d8a906040615c65565b610ccf9190615c51565b60006146b3836001600160a01b0384166152e0565b601c54601d5460405163095ea7b360e01b81526001600160a01b039283169263095ea7b392614ddf929116908590600401615b3a565b602060405180830381600087803b158015614df957600080fd5b505af1158015614e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614e3191906159f0565b50601d5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f25906024015b600060405180830381600087803b158015614e7957600080fd5b505af1158015614e8d573d6000803e3d6000fd5b5050505050565b8060096000828254614ea69190615d13565b9091555050601d5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401614e5f565b614f328363a9059cbb60e01b8484604051602401614efb929190615b3a565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261532f565b505050565b614f4081614a19565b50614f4a81614bef565b6001600160a01b0381166000908152600f6020908152604080832054601090925290912054614f799190615401565b6001600160a01b039091166000908152600f6020526040902055565b6040516001600160a01b0380851660248301528316604482015260648101829052614fcd9085906323b872dd60e01b90608401614efb565b50505050565b60006146b3836001600160a01b038416615417565b6000610dd4825490565b60006146b3838361550a565b601c546001600160a01b038481169116146150d6576003546001600160a01b038085169163a9059cbb91166150338486615c39565b6040518363ffffffff1660e01b8152600401615050929190615b3a565b602060405180830381600087803b15801561506a57600080fd5b505af192505050801561509a575060408051601f3d908101601f19168201909252615097918101906159f0565b60015b6150d4573d8080156150c8576040519150601f19603f3d011682016040523d82523d6000602084013e6150cd565b606091505b50506150d6565b505b6001600160a01b038085166000908152600d602090815260408083209387168352929052908120805484929061510d908490615d13565b90915550506001600160a01b03808516600090815260186020908152604080832093871683529290529081208054839290615149908490615d13565b909155505050505050565b6000808486602e546151669190615d13565b6151709190615c39565b9050670de0b6b3a7640000846127106151898685615c65565b6151939190615c51565b61519d9190615c65565b6151a79190615c51565b9695505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561520157602002820191906000526020600020905b8154815260200190600101908083116151ed575b50505050509050919050565b600080806000198587098587029250828110838203039150508060001415615247576000841161523c57600080fd5b5082900490506146b3565b80841161525357600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6152c481615534565b6001600160a01b03909116600090815260106020526040902055565b600081815260018301602052604081205461532757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610dd4565b506000610dd4565b6000615384826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166156779092919063ffffffff16565b805190915015614f3257808060200190518101906153a291906159f0565b614f325760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161155a565b600081831061541057816146b3565b5090919050565b6000818152600183016020526040812054801561550057600061543b600183615d13565b855490915060009061544f90600190615d13565b90508181146154b457600086600001828154811061546f5761546f615dee565b906000526020600020015490508087600001848154811061549257615492615dee565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806154c5576154c5615dd8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610dd4565b6000915050610dd4565b600082600001828154811061552157615521615dee565b9060005260206000200154905092915050565b6000805b6001600160a01b038316600090815260126020526040902061555990614fe8565b811015612197576001600160a01b03831660009081526012602052604081206155829083614ff2565b905061558f6026826146ba565b156156645761559d42614662565b6001600160a01b0382166000908152602b602052604090206001015414615623576155c7816110c3565b6001600160a01b0382166000908152602b60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b16179190911781559101516001909101555b6001600160a01b0380851660009081526028602090815260408083209385168352929052205461565790610dc490836148fb565b6156619084615c39565b92505b508061566f81615d56565b915050615538565b6060610cbb848460008585843b6156d05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161155a565b600080866001600160a01b031685876040516156ec9190615aae565b60006040518083038185875af1925050503d8060008114615729576040519150601f19603f3d011682016040523d82523d6000602084013e61572e565b606091505b509150915061573e828286615749565b979650505050505050565b606083156157585750816146b3565b8251156157685782518084602001fd5b8160405162461bcd60e51b815260040161155a9190615ba0565b805180151581146112eb57600080fd5b8051600681900b81146112eb57600080fd5b6000602082840312156157b657600080fd5b81356146b381615e04565b6000602082840312156157d357600080fd5b81516146b381615e04565b600080604083850312156157f157600080fd5b82356157fc81615e04565b9150602083013561580c81615e04565b809150509250929050565b60008060006060848603121561582c57600080fd5b833561583781615e04565b9250602084013561584781615e04565b9150604084013561585781615e04565b809150509250925092565b60008060006060848603121561587757600080fd5b833561588281615e04565b9250602084013561589281615e04565b929592945050506040919091013590565b600080600080608085870312156158b957600080fd5b84356158c481615e04565b935060208501356158d481615e04565b92506040850135915060608501356158eb81615e04565b939692955090935050565b6000806000806080858703121561590c57600080fd5b843561591781615e04565b9350602085013561592781615e04565b93969395505050506040820135916060013590565b600080600080600060a0868803121561595457600080fd5b853561595f81615e04565b9450602086013561596f81615e04565b94979496505050506040830135926060810135926080909101359150565b600080604083850312156159a057600080fd5b82356159ab81615e04565b946020939093013593505050565b6000806000606084860312156159ce57600080fd5b83356159d981615e04565b925060208401359150604084013561585781615e04565b600060208284031215615a0257600080fd5b6146b382615782565b600080600060608486031215615a2057600080fd5b615a2984615792565b9250615a3760208501615792565b9150615a4560408501615782565b90509250925092565b600060208284031215615a6057600080fd5b5035919050565b600060208284031215615a7957600080fd5b5051919050565b600080600060608486031215615a9557600080fd5b8351925060208401519150604084015190509250925092565b60008251615ac0818460208701615d2a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615b2d57845163ffffffff1683529383019391830191600101615b0b565b5090979650505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015615b945783516001600160a01b031683529284019291840191600101615b6f565b50909695505050505050565b6020815260008251806020840152615bbf816040850160208701615d2a565b601f01601f19169190910160400192915050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b92835260069190910b6020830152604082015260600190565b9283526020830191909152604082015260600190565b60008219821115615c4c57615c4c615dac565b500190565b600082615c6057615c60615dc2565b500490565b6000816000190483118215151615615c7f57615c7f615dac565b500290565b60008083128015600160ff1b850184121615615ca257615ca2615dac565b6001600160ff1b0384018313811615615cbd57615cbd615dac565b50500390565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615cee57615cee615dac565b81667fffffffffffff018313811615615d0957615d09615dac565b5090039392505050565b600082821015615d2557615d25615dac565b500390565b60005b83811015615d45578181015183820152602001615d2d565b83811115614fcd5750506000910152565b6000600019821415615d6a57615d6a615dac565b5060010190565b600082615d8057615d80615dc2565b500690565b60008160060b667fffffffffffff19811415615da357615da3615dac565b60000392915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114615e1957600080fd5b5056fe46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfaee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a2646970667358221220387041f4445770e88edda922a11b4527ef0755a64cad19454f2008ef77f4af2564736f6c63430008070033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106104075760003560e01c8063966abd0011610228578063c5198abc1161013c578063ec8ca643116100be578063ec8ca64314610add578063f0f346b914610b06578063f11a1d1a14610b19578063f136a09d14610b2c578063f25e311b14610b4c578063f263c47014610b5f578063f39c38a014610b68578063f75f9f7b14610b7b578063f9d46cf214610b8e578063fc253d2b14610ba1578063fe75bc4614610baa57600080fd5b8063c5198abc146109f1578063c7ae40d014610a04578063cb4be2bb14610a17578063cb54694d14610a2a578063cd22af1b14610a3d578063d55995fe14610a68578063dd2080d614610a7b578063ddca3f4314610a8e578063e326ac4314610a97578063ebbb619414610ab7578063ec00cdfc14610aca57600080fd5b8063966abd001461080457806398e90a0f146108175780639d5c33d814610840578063a214580914610853578063a39744b514610866578063a515366a14610891578063a5d059ca146108a4578063a676f9ff146108b7578063a7d2e784146108d7578063aac6aa9c146108e0578063ab033ea9146108f3578063af320e8114610906578063b0103b1a14610919578063b0f328f11461093c578063b239223314610944578063b440027f14610957578063b600702a14610982578063b70362b914610995578063b7e77340146109a8578063b87fcbff146109bb578063c20297f0146109de57600080fd5b80635aa6e6751161031f5780635aa6e6751461066b5780635ebe23f01461067e5780635feeb79414610687578063633fb68f1461069a57806364bb43ee146106a357806368a9f19c146106b6578063694798e6146106c957806369fe0e2d146106f45780636ba42aaa146107075780636cf262bc1461071a5780636e2a9ca61461072d57806372da828a1461074057806374a8f10314610753578063768b5d90146107665780637c8fce231461076f578063878c723e146107775780638bb6dfa8146107a05780638cb22b76146107b35780638fe204dd146107d657806390a4684e146107e9578063951dc22c146107fc57600080fd5b8063034d4c611461040c57806307b435c2146104325780630c620bce1461045d5780630d6a1f87146104725780631101eb411461048557806311466d721461049a57806315006b82146104ad578063165e62e7146104d8578063168f92e7146105155780631b44555e146105405780631c5a9d9c146105605780631ef94b911461057357806321040b0114610593578063238efcbc146105be578063274a8db4146105c657806351cff8d9146105f957806352a4de291461060c57806355ea6c471461061f578063575288bf14610632578063594a3a931461064557806359a2255e14610658575b600080fd5b61041f61041a3660046157a4565b610bbd565b6040519081526020015b60405180910390f35b61041f6104403660046157de565b601760209081526000928352604080842090915290825290205481565b610465610cc3565b6040516104299190615b53565b61041f61048036600461598d565b610cd4565b610498610493366004615862565b610dda565b005b6104986104a836600461598d565b610f34565b61041f6104bb3660046157de565b601560209081526000928352604080842090915290825290205481565b6104eb6104e63660046157a4565b6110c3565b604080518251600690810b825260208085015190910b908201529181015190820152606001610429565b61041f6105233660046157de565b600e60209081526000928352604080842090915290825290205481565b61041f61054e3660046157a4565b600a6020526000908152604090205481565b61049861056e3660046157a4565b6112f0565b601c54610586906001600160a01b031681565b6040516104299190615aca565b61041f6105a13660046157de565b601860209081526000928352604080842090915290825290205481565b6104986114ab565b6105e96105d43660046157a4565b60066020526000908152604090205460ff1681565b6040519015158152602001610429565b6104986106073660046157a4565b611537565b61049861061a366004615862565b6116cf565b61049861062d3660046157a4565b611900565b610498610640366004615862565b6119b4565b6104986106533660046157de565b611c77565b6104986106663660046157a4565b611d1c565b600354610586906001600160a01b031681565b61041f601f5481565b6104986106953660046157a4565b611dce565b61041f60215481565b6104986106b13660046157a4565b611de7565b6104986106c43660046157a4565b611ec8565b61041f6106d73660046157de565b602860209081526000928352604080842090915290825290205481565b610498610702366004615a4e565b611fa7565b6105e96107153660046157a4565b612007565b61041f6107283660046157a4565b612067565b61049861073b366004615862565b61219d565b61049861074e3660046157a4565b6122ec565b6104986107613660046157a4565b612389565b61041f60225481565b610465612484565b6105866107853660046157a4565b6001602052600090815260409020546001600160a01b031681565b61041f6107ae3660046157a4565b612490565b6105e96107c13660046157a4565b60196020526000908152604090205460ff1681565b6104986107e4366004615a4e565b612533565b6104986107f73660046157de565b612591565b61046561267f565b6104986108123660046159b9565b61268b565b6105866108253660046157a4565b6002602052600090815260409020546001600160a01b031681565b61049861084e3660046157a4565b6127a1565b610498610861366004615817565b612880565b61041f6108743660046157de565b600d60209081526000928352604080842090915290825290205481565b61049861089f36600461598d565b612a50565b6104986108b236600461598d565b612cb1565b61041f6108c53660046157a4565b60296020526000908152604090205481565b61041f60205481565b6104986108ee3660046157a4565b612d8b565b6104986109013660046157a4565b612e3f565b6104986109143660046157de565b612eb5565b6105e96109273660046157a4565b600c6020526000908152604090205460ff1681565b61041f613334565b610498610952366004615a4e565b6133ca565b61041f6109653660046157de565b602560209081526000928352604080842090915290825290205481565b6104986109903660046157a4565b61342a565b6104986109a336600461598d565b613698565b6104986109b6366004615a4e565b61391c565b6105e96109c93660046157a4565b60056020526000908152604090205460ff1681565b6104986109ec3660046158f6565b61397c565b6104986109ff3660046157a4565b613a35565b601d54610586906001600160a01b031681565b610498610a253660046157a4565b613afb565b610498610a38366004615a4e565b613b98565b61041f610a4b3660046157de565b601660209081526000928352604080842090915290825290205481565b610498610a763660046158a3565b613c1c565b610498610a89366004615862565b613e53565b61041f60245481565b61041f610aa53660046157a4565b600b6020526000908152604090205481565b610498610ac5366004615a4e565b613fd0565b610498610ad83660046157a4565b614030565b610586610aeb3660046157a4565b602c602052600090815260409020546001600160a01b031681565b610498610b143660046157a4565b6140d8565b601e54610586906001600160a01b031681565b61041f610b3a3660046157a4565b602a6020526000908152604090205481565b610498610b5a366004615862565b61418c565b61041f60095481565b600454610586906001600160a01b031681565b610498610b893660046157a4565b6143d1565b6105e9610b9c36600461593c565b614489565b61041f60235481565b610498610bb836600461598d565b614572565b600080610bc983612067565b6022549091504290610be490610bdf9083615d13565b614662565b6001600160a01b0385166000908152602960205260409020541115610c88576022546001600160a01b038516600090815260296020526040902054610c299042615d13565b10610c65576022546001600160a01b038516600090815260296020526040902054610c549190615c39565b610c5e9082615d13565b9050610c9e565b6001600160a01b038416600090815260296020526040902054610c5e9082615d13565b610c9142614662565b610c9b9082615d13565b90505b610ca8818361467c565b610cb185612490565b610cbb9190615c39565b949350505050565b6060610ccf60266146a6565b905090565b6000610ce16026846146ba565b15610dd4576000610cf1846110c3565b90508060400151600014610dd2576001600160a01b03841660009081526014602052604081205460ff16610d32578160200151610d2d90615d85565b610d38565b81602001515b601e5460225460405163a0d2710760e01b8152929350610dc9926001600160a01b039092169163a0d2710791610d749189918791600401615c0a565b60206040518083038186803b158015610d8c57600080fd5b505afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190615a67565b6146dc565b92505050610dd4565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610e1657604051636efb4f4160e11b815260040160405180910390fd5b602054610e239042615c39565b6001600160a01b03808616600081815260176020908152604080832094891680845294825280832095909555918152601882528381209281529190529081208054849290610e72908490615c39565b90915550610e8390508484846146ed565b6001600160a01b038085166000908152602860209081526040808320938716835292905220548015801590610ec25750602154610ec082866148fb565b105b15610ee057604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de85604051610f2591815260200190565b60405180910390a35050505050565b336000818152600c602052604090205460ff1615610f655760405163ad2fdf3b60e01b815260040160405180910390fd5b610f70601a826146ba565b610f8c5760405162941a5760e11b815260040160405180910390fd5b610f9581614a19565b15610ff0576001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615e3d83398151915293610fe79390929091615c23565b60405180910390a25b6001600160a01b0381166000908152600f602052604090205482111561106f5761101981614bef565b6001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615e3d833981519152936110669390929091615c23565b60405180910390a25b61107a818484614c7d565b601c546001600160a01b03808516918382169116600080516020615e1d833981519152856110a6614d7a565b6040805192835260208301919091520160405180910390a4505050565b60408051606081018252600080825260208201819052918101919091526110e942614662565b6001600160a01b0383166000908152602b6020526040902060010154141561115f57506001600160a01b03166000908152602b602090815260409182902082516060810184528154600681810b810b810b8352600160381b909104810b810b900b92810192909252600101549181019190915290565b6040805160028082526060820183526000928392919060208301908036833701905050905061118d42614662565b6111979042615d13565b816000815181106111aa576111aa615dee565b602002602001019063ffffffff16908163ffffffff16815250506022546111d042614662565b6111da9042615d13565b6111e49190615c39565b816001815181106111f7576111f7615dee565b63ffffffff909216602092830291909101820152601e546001600160a01b0386811660009081526013909352604080842054905163dc686d9160e01b81529282169263dc686d919261124f9216908690600401615ade565b60606040518083038186803b15801561126757600080fd5b505afa15801561127b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129f9190615a0b565b600692830b90920b80875291945091506112ba908290615cc3565b600690810b900b602085015282156112df576112d542614662565b60408501526112e7565b600060408501525b5050505b919050565b336000818152600c602052604090205460ff1615611321576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b038082166000908152601660209081526040808320938616835292905220548061136557604051636258f48160e01b815260040160405180910390fd5b42811061138557604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600b60205260409020546113be576001600160a01b0382166000908152600b602052604090204290555b6113c9600783614d94565b506001600160a01b038083166000818152601560209081526040808320948816808452948252808320805490849055938352600d825280832094835293905291822080549192839261141c908490615c39565b9091555050601c546001600160a01b03858116911614156114585780600960008282546114499190615c39565b90915550611458905081614da9565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a758360405161149d91815260200190565b60405180910390a350505050565b6004546001600160a01b031633146114d657604051637ef5703160e11b815260040160405180910390fd5b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fc73be659241aade67e9a059bcf21494955018b213dbd1179054ccf928b13f3b69161152d91615aca565b60405180910390a1565b600260005414156115635760405162461bcd60e51b815260040161155a90615bd3565b60405180910390fd5b600260009081553381526018602090815260408083206001600160a01b03851684529091529020546115a85760405163184c088160e21b815260040160405180910390fd5b3360009081526017602090815260408083206001600160a01b038516845290915290205442116115eb576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600c602052604090205460ff161561161c576040516362e6201d60e01b815260040160405180910390fd5b3360008181526018602090815260408083206001600160a01b038681168086529184528285208054908690559585526017845282852082865290935290832092909255601c541614156116725761167281614e94565b6116866001600160a01b0383163383614edc565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b600260005414156116f25760405162461bcd60e51b815260040161155a90615bd3565b60026000556117026026836146ba565b61171f5760405163e0b6aead60e01b815260040160405180910390fd5b61172a601a846146ba565b61174757604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526012602052604090206117699083614d94565b5061177383614f37565b6021546001600160a01b038085166000908152602860209081526040808320938716835292905220546117b1906117ab908490615c39565b846148fb565b10156117d057604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615e3d8339815191529361181d9390929091615c23565b60405180910390a261183a6001600160a01b038316333084614f95565b6001600160a01b03808416600090815260286020908152604080832093861683529290529081208054839290611871908490615c39565b909155506118849050610dc482846148fb565b6001600160a01b038416600090815260106020526040812080549091906118ac908490615c39565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff1661193057604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16611969576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b600260005414156119d75760405162461bcd60e51b815260040161155a90615bd3565b60026000556119e7601a846146ba565b611a0457604051636211d34960e01b815260040160405180910390fd5b601c546001600160a01b0383811691161415611a325760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038416906370a0823190611a61903090600401615aca565b60206040518083038186803b158015611a7957600080fd5b505afa158015611a8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab19190615a67565b9050611ac86001600160a01b038416333085614f95565b600081846001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611af79190615aca565b60206040518083038186803b158015611b0f57600080fd5b505afa158015611b23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b479190615a67565b611b519190615d13565b9050600061271060245483611b669190615c65565b611b709190615c51565b9050611b7c8183615d13565b6001600160a01b038088166000908152600e60209081526040808320938a1683529290529081208054909190611bb3908490615c39565b90915550506001600160a01b0380871660009081526025602090815260408083208985168085529252909120429055600354611bf0921683614edc565b6001600160a01b0386166000908152601160205260409020611c129086614d94565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611c6291815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611cb357604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611d585760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b6040516331cee75f60e21b815260040160405180910390fd5b6003546001600160a01b03163314611e12576040516354348f0360e01b815260040160405180910390fd5b611e1d602682614fd3565b611e3a57604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600090815260136020908152604080832080546001600160a01b031916905560148252808320805460ff19169055602b90915280822080546001600160701b031916815560010191909155517f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e5690611ebd908390615aca565b60405180910390a150565b6003546001600160a01b03163314611ef3576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116611f1a5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff1615611f545760405163546da66560e11b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b90611ebd908390615aca565b6003546001600160a01b03163314611fd2576040516354348f0360e01b815260040160405180910390fd5b60248190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d90602001611ebd565b6000612011614d7a565b602e5561201f6007836146ba565b156112eb577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e5460405161205791815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b038316600090815260126020526040902061208c90614fe8565b811015612197576001600160a01b03831660009081526012602052604081206120b59083614ff2565b90506120c26026826146ba565b156121845760006120d2826110c3565b90508060400151600014612182576001600160a01b03821660009081526014602052604081205460ff1661211357816020015161210e90615d85565b612119565b81602001515b601e546001600160a01b03888116600090815260286020908152604080832089851684529091529081902054602254915163a0d2710760e01b815294955061217494929093169263a0d2710792610d74928791600401615c0a565b61217e9086615c39565b9450505b505b508061218f81615d56565b91505061206b565b50919050565b3360009081526005602052604090205460ff166121cd57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff16612206576040516310cec38560e21b815260040160405180910390fd5b6122118383836146ed565b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261224592909116908590600401615b3a565b602060405180830381600087803b15801561225f57600080fd5b505af192505050801561228f575060408051601f3d908101601f1916820190925261228c918101906159f0565b60015b6122985761229a565b505b336001600160a01b0316836001600160a01b03167f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e84846040516122df929190615b3a565b60405180910390a3505050565b6003546001600160a01b03163314612317576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661233e5760405163d92e233d60e01b815260040160405180910390fd5b601e80546001600160a01b0319166001600160a01b0383161790556040517f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b090611ebd908390615aca565b3360009081526005602052604090205460ff166123b957604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff166123f2576040516310cec38560e21b815260040160405180910390fd5b6123fd600782614fd3565b50601c546001600160a01b038083166000818152600d602090815260408083209490951680835293815284822054928252601881528482208483529052929092205461244b92849291614ffe565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610ccf601a6146a6565b60008061249c83612067565b6022546001600160a01b038516600090815260296020526040902054919250906124c69042615d13565b1015610dd457600081116124f2576001600160a01b0383166000908152600f602052604090205461252c565b6001600160a01b038316600090815260106020908152604080832054600f90925290912054612522908390615c65565b61252c9190615c51565b9150612197565b6003546001600160a01b0316331461255e576040516354348f0360e01b815260040160405180910390fd5b60208181556040518281527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee29101611ebd565b6001600160a01b0382811660009081526001602052604090205483911633146125cd57604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156126005760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602c6020908152604080832080546001600160a01b0319169588169586179055602d825280832094835293905282902042905590517fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c90612672908590615aca565b60405180910390a2505050565b6060610ccf60076146a6565b6003546001600160a01b031633146126b6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166126dd5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561273e576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015612738573d6000803e3d6000fd5b50612752565b6127526001600160a01b0384168284614edc565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b031633146127cc576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166127f35760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff161561282d5760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19166001179055517f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f90611ebd908390615aca565b6001600160a01b0383811660009081526001602052604090205484911633146128bc57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0382166128e35760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038085166000908152601860209081526040808320938716835292905220546129265760405163184c088160e21b815260040160405180910390fd5b6001600160a01b03808516600090815260176020908152604080832093871683529290522054421161296b576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff16156129a5576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b03808516600081815260186020908152604080832094881680845294825280832080549084905593835260178252808320858452909152812055906129f2908483614edc565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca792886284604051612a4191815260200190565b60405180910390a45050505050565b60026000541415612a735760405162461bcd60e51b815260040161155a90615bd3565b60026000908155338152600c602052604090205460ff1615612aa8576040516362e6201d60e01b815260040160405180910390fd5b612ab3601a336146ba565b15612ad15760405163d7229c4360e01b815260040160405180910390fd5b601f54612ade9042615c39565b3360009081526016602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81529091906370a0823190612b29903090600401615aca565b60206040518083038186803b158015612b4157600080fd5b505afa158015612b55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b799190615a67565b9050612b906001600160a01b038416333085614f95565b6040516370a0823160e01b815281906001600160a01b038516906370a0823190612bbe903090600401615aca565b60206040518083038186803b158015612bd657600080fd5b505afa158015612bea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c0e9190615a67565b612c189190615d13565b336000908152601960209081526040808320805460ff19166001179055601582528083206001600160a01b0388168452909152812080549294508492909190612c62908490615c39565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b602054612cbe9042615c39565b3360008181526017602090815260408083206001600160a01b03881680855290835281842095909555928252600d81528282209382529290925281208054839290612d0a908490615d13565b90915550503360009081526018602090815260408083206001600160a01b038616845290915281208054839290612d42908490615c39565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b03163314612db6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16612def576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090819020805460ff19169055517f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d02590611ebd908390615aca565b6003546001600160a01b03163314612e6a576040516354348f0360e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383161790556040517fe987aaedf9d279143bdf1eee16cf1d0feb47742867d81083df8d6cd0a5ac857f90611ebd908390615aca565b6001600160a01b038181166000908152600160205260409020548291163314612ef157604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1680612f3057506001600160a01b0382166000908152600c602052604090205460ff165b15612f4e5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602c6020526040902054811690831614612f8b57604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602d6020908152604080832093861683529290522054612fbd90603c90615c39565b421015612fdd576040516356248e9760e01b815260040160405180910390fd5b612fe683614f37565b612fef82614f37565b6001600160a01b038316600090815260116020526040812061301090614fe8565b11156130f2576001600160a01b03831660009081526011602052604081206130389082614ff2565b6001600160a01b038086166000908152600e6020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613086908490615c39565b90915550506001600160a01b038085166000818152600e6020908152604080832094861683529381528382208290559181526011909152206130c89082614fd3565b506001600160a01b03831660009081526011602052604090206130eb9082614d94565b5050612fef565b6001600160a01b038316600090815260126020526040812061311390614fe8565b11156131f5576001600160a01b038316600090815260126020526040812061313b9082614ff2565b6001600160a01b03808616600090815260286020818152604080842085871680865290835281852054958a168552928252808420928452919052812080549394509192613189908490615c39565b90915550506001600160a01b03808516600090815260286020908152604080832085851684528252808320839055928616825260129052206131cb9082614d94565b506001600160a01b03841660009081526012602052604090206131ee9082614fd3565b50506130f2565b6001600160a01b0380841660009081526010602052604080822054928516825281208054909190613227908490615c39565b90915550506001600160a01b038084166000908152601060209081526040808320839055600f9091528082205492851682528120805490919061326b908490615c39565b90915550506001600160a01b0383166000908152600f6020908152604080832083905560299091528120556132a1601a84614fd3565b506001600160a01b03808416600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602d8352818420958816808552958352818420849055938352602c909152908190208054909216909155517f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f290612672908690615aca565b600954601c54601d546040516370a0823160e01b8152600093926001600160a01b03908116926370a08231926133709290911690600401615aca565b60206040518083038186803b15801561338857600080fd5b505afa15801561339c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133c09190615a67565b610ccf9190615c84565b6003546001600160a01b031633146133f5576040516354348f0360e01b815260040160405180910390fd5b60238190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb6990602001611ebd565b6003546001600160a01b03163314613455576040516354348f0360e01b815260040160405180910390fd5b613460602682614d94565b61347d5760405163f25e6b9f60e01b815260040160405180910390fd5b601e5460405163eb37d34960e01b81526001600160a01b039091169063eb37d349906134ad908490600401615aca565b60206040518083038186803b1580156134c557600080fd5b505afa1580156134d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134fd91906157c1565b6001600160a01b03828116600090815260136020526040902080546001600160a01b0319169290911691821790556135485760405163d92e233d60e01b815260040160405180910390fd5b601e546001600160a01b038281166000908152601360205260409081902054905163696a437b60e01b81529282169263696a437b9261358b921690600401615aca565b60206040518083038186803b1580156135a357600080fd5b505afa1580156135b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135db91906159f0565b6001600160a01b0382166000908152601460205260409020805460ff191691151591909117905561360b816110c3565b6001600160a01b0382166000908152602b60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b161791909117815591810151600190920191909155517fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b90611ebd908390615aca565b602e546136b857604051630262ab9b60e61b815260040160405180910390fd5b60006136c2614d7a565b336000818152600c60205260409020549192509060ff16156136f75760405163ad2fdf3b60e01b815260040160405180910390fd5b613702601a826146ba565b61371e5760405162941a5760e11b815260040160405180910390fd5b61372781614a19565b15613782576001600160a01b038116600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615e3d833981519152936137799390929091615c23565b60405180910390a25b601e546001600160a01b038581166000908152600d60209081526040808320601c548516845290915280822054905163435b21c160e01b8152600481019190915290928392839291169063435b21c19060240160606040518083038186803b1580156137ed57600080fd5b505afa158015613801573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138259190615a80565b919450925090506000613843868361383d8a87615c65565b87615154565b6001600160a01b0386166000908152600f60205260409020549091508111156138c55761386f85614bef565b6001600160a01b038516600081815260296020908152604080832054600f835281842054601090935292819020549051600080516020615e3d833981519152936138bc9390929091615c23565b60405180910390a25b6138d0858983614c7d565b6000602e55601c5460408051838152602081018990526001600160a01b038b81169389821693911691600080516020615e1d833981519152910160405180910390a45050505050505050565b6003546001600160a01b03163314613947576040516354348f0360e01b815260040160405180910390fd5b601f8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b4390602001611ebd565b3360009081526005602052604090205460ff166139ac57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff166139e5576040516310cec38560e21b815260040160405180910390fd5b6139f184848484614ffe565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613a278486615c39565b60405190815260200161149d565b613a40601a826146ba565b15613a5e57604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526019602052604090205460ff1615613a9857604051632f3d320560e01b815260040160405180910390fd5b613aa3601a82614d94565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613b26576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116613b4d5760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383161790556040517feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae25090611ebd908390615aca565b6003546001600160a01b03163314613bc3576040516354348f0360e01b815260040160405180910390fd5b62015180811015613be757604051633f384aad60e21b815260040160405180910390fd5b60228190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d990602001611ebd565b60026000541415613c3f5760405162461bcd60e51b815260040161155a90615bd3565b600260009081556001600160a01b03858116825260016020526040909120548591163314613c8057604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260256020908152604080832093881683529290522054613cb290603c90615c39565b4211613cd157604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054831115613d175760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600c602052604090205460ff1615613d515760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290529081208054859290613d88908490615d13565b90915550613da290506001600160a01b0385168385614edc565b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054613df0576001600160a01b0385166000908152601160205260409020613dee9085614fd3565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613e3f91815260200190565b60405180910390a450506001600055505050565b336000818152600c602052604090205460ff1615613e845760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1615613ebe576040516362e6201d60e01b815260040160405180910390fd5b613ec9601a826146ba565b613ee55760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290522054821115613f2b5760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290529081208054849290613f62908490615d13565b90915550613f7c90506001600160a01b0385168484614edc565b826001600160a01b0316816001600160a01b0316856001600160a01b0316600080516020615e1d83398151915285613fb2614d7a565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b03163314613ffb576040516354348f0360e01b815260040160405180910390fd5b60218190556040518181527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e790602001611ebd565b6003546001600160a01b0316331461405b576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b0381166140825760405163d92e233d60e01b815260040160405180910390fd5b61408d600954614e94565b601c80546001600160a01b0319166001600160a01b0383161790556040517f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf90611ebd908390615aca565b6003546001600160a01b03163314614103576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1661413c57604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090819020805460ff19169055517f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e90611ebd908390615aca565b3360009081526005602052604090205460ff166141bc57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff166141f5576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b038316600090815260116020526040902061421790836146ba565b61423457604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600e60209081526040808320938616835292905220548111156142795760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb926142ad92909116908590600401615b3a565b602060405180830381600087803b1580156142c757600080fd5b505af19250505080156142f7575060408051601f3d908101601f191682019092526142f4918101906159f0565b60015b61430057614302565b505b6001600160a01b038084166000908152600e6020908152604080832093861683529290529081208054839290614339908490615d13565b90915550506001600160a01b038084166000908152600e602090815260408083209386168352929052205461438c576001600160a01b038316600090815260116020526040902061438a9083614fd3565b505b336001600160a01b0316836001600160a01b03167f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d31833310484846040516122df929190615b3a565b3360009081526006602052604090205460ff1661440157604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff161561443b576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b6000614493614d7a565b602e556144a16007876146ba565b80156144d257506001600160a01b038087166000908152600d60209081526040808320938916835292905220548411155b80156144f657506001600160a01b0386166000908152600a60205260409020548311155b801561452557506001600160a01b0386166000908152600b602052604090205482906145229042615d13565b10155b15614569577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e5460405161455d91815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b0316331461459d576040516354348f0360e01b815260040160405180910390fd5b6145a8601a836146ba565b6145c557604051636211d34960e01b815260040160405180910390fd5b6145ce82614f37565b6001600160a01b0382166000908152600f6020526040812080548392906145f6908490615c39565b90915550506001600160a01b038216600081815260296020908152604080832054600f909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d192614656928252602082015260400190565b60405180910390a25050565b6000602254826146729190615d71565b610dd49083615d13565b6000602254831015612197576022546146958385615c65565b61469f9190615c51565b9050610dd4565b606060006146b3836151b1565b9392505050565b6001600160a01b038116600090815260018301602052604081205415156146b3565b6000610dd48260225460235461520d565b600260005414156147105760405162461bcd60e51b815260040161155a90615bd3565b600260009081556001600160a01b038416815260126020526040902061473690836146ba565b614752576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b038084166000908152602860209081526040808320938616835292905220548111156147985760405163435b562560e01b815260040160405180910390fd5b6147a1836152bb565b60006147b0610dc483856148fb565b6001600160a01b03851660009081526010602052604090205490915015614866576001600160a01b038416600090815260106020908152604080832054600f90925290912054614801908390615c65565b61480b9190615c51565b6001600160a01b0385166000908152600f602052604081208054909190614833908490615d13565b90915550506001600160a01b03841660009081526010602052604081208054839290614860908490615d13565b90915550505b6001600160a01b0380851660009081526028602090815260408083209387168352929052908120805484929061489d908490615d13565b90915550506001600160a01b038085166000908152602860209081526040808320938716835292905220546148f0576001600160a01b03841660009081526012602052604090206148ee9084614fd3565b505b505060016000555050565b6001600160a01b0381166000908152602b602052604081206001015415610dd4576001600160a01b03821660009081526014602052604081205460ff1661496d576001600160a01b0383166000908152602b602052604090205461496890600160381b900460060b615d85565b614991565b6001600160a01b0383166000908152602b6020526040902054600160381b900460060b5b601e5460225460405163a0d2710760e01b81529293506001600160a01b039091169163a0d27107916149c99188918691600401615c0a565b60206040518083038186803b1580156149e157600080fd5b505afa1580156149f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbb9190615a67565b6000614a2442614662565b6001600160a01b03831660009081526029602052604090205410156112eb57614a5460225442610bdf9190615d13565b6001600160a01b03831660009081526029602052604090205411614aca57614a7b826152bb565b6001600160a01b038216600090815260106020908152604080832054600f90925290912055614aa942614662565b6001600160a01b038316600090815260296020526040902055506001919050565b6022546001600160a01b038316600090815260296020526040902054614af09042615d13565b10614b4c57614afe826152bb565b6001600160a01b038216600090815260106020908152604080832054600f83528184205560225460299092528220805491929091614b3d908490615c39565b90915550600191506112eb9050565b614b5542614662565b6001600160a01b0383166000908152602a602052604090205410156112eb576001600160a01b038216600090815260106020526040902054614b96836152bb565b6001600160a01b038316600090815260106020908152604080832054600f909252909120548291614bc691615c65565b614bd09190615c51565b6001600160a01b0384166000908152600f602052604090205550919050565b6001600160a01b038116600090815260296020526040902054614c3490614c169042615d13565b6001600160a01b03831660009081526010602052604090205461467c565b6001600160a01b0382166000908152600f602052604081208054909190614c5c908490615c39565b90915550506001600160a01b03166000908152602960205260409020429055565b6001600160a01b0383166000908152600f6020526040902054811115614cb65760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602a60209081526040808320429055600f90915281208054839290614ceb908490615d13565b90915550506001600160a01b038083166000908152600d60209081526040808320601c5490941683529290529081208054839290614d2a908490615c39565b90915550506001600160a01b0382166000908152600a602052604081208054839290614d57908490615c39565b925050819055508060096000828254614d709190615c39565b9091555050505050565b6000603f5a614d8a906040615c65565b610ccf9190615c51565b60006146b3836001600160a01b0384166152e0565b601c54601d5460405163095ea7b360e01b81526001600160a01b039283169263095ea7b392614ddf929116908590600401615b3a565b602060405180830381600087803b158015614df957600080fd5b505af1158015614e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614e3191906159f0565b50601d5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f25906024015b600060405180830381600087803b158015614e7957600080fd5b505af1158015614e8d573d6000803e3d6000fd5b5050505050565b8060096000828254614ea69190615d13565b9091555050601d5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401614e5f565b614f328363a9059cbb60e01b8484604051602401614efb929190615b3a565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261532f565b505050565b614f4081614a19565b50614f4a81614bef565b6001600160a01b0381166000908152600f6020908152604080832054601090925290912054614f799190615401565b6001600160a01b039091166000908152600f6020526040902055565b6040516001600160a01b0380851660248301528316604482015260648101829052614fcd9085906323b872dd60e01b90608401614efb565b50505050565b60006146b3836001600160a01b038416615417565b6000610dd4825490565b60006146b3838361550a565b601c546001600160a01b038481169116146150d6576003546001600160a01b038085169163a9059cbb91166150338486615c39565b6040518363ffffffff1660e01b8152600401615050929190615b3a565b602060405180830381600087803b15801561506a57600080fd5b505af192505050801561509a575060408051601f3d908101601f19168201909252615097918101906159f0565b60015b6150d4573d8080156150c8576040519150601f19603f3d011682016040523d82523d6000602084013e6150cd565b606091505b50506150d6565b505b6001600160a01b038085166000908152600d602090815260408083209387168352929052908120805484929061510d908490615d13565b90915550506001600160a01b03808516600090815260186020908152604080832093871683529290529081208054839290615149908490615d13565b909155505050505050565b6000808486602e546151669190615d13565b6151709190615c39565b9050670de0b6b3a7640000846127106151898685615c65565b6151939190615c51565b61519d9190615c65565b6151a79190615c51565b9695505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561520157602002820191906000526020600020905b8154815260200190600101908083116151ed575b50505050509050919050565b600080806000198587098587029250828110838203039150508060001415615247576000841161523c57600080fd5b5082900490506146b3565b80841161525357600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6152c481615534565b6001600160a01b03909116600090815260106020526040902055565b600081815260018301602052604081205461532757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610dd4565b506000610dd4565b6000615384826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166156779092919063ffffffff16565b805190915015614f3257808060200190518101906153a291906159f0565b614f325760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161155a565b600081831061541057816146b3565b5090919050565b6000818152600183016020526040812054801561550057600061543b600183615d13565b855490915060009061544f90600190615d13565b90508181146154b457600086600001828154811061546f5761546f615dee565b906000526020600020015490508087600001848154811061549257615492615dee565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806154c5576154c5615dd8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610dd4565b6000915050610dd4565b600082600001828154811061552157615521615dee565b9060005260206000200154905092915050565b6000805b6001600160a01b038316600090815260126020526040902061555990614fe8565b811015612197576001600160a01b03831660009081526012602052604081206155829083614ff2565b905061558f6026826146ba565b156156645761559d42614662565b6001600160a01b0382166000908152602b602052604090206001015414615623576155c7816110c3565b6001600160a01b0382166000908152602b60209081526040918290208351815492850151600690810b66ffffffffffffff908116600160381b026001600160701b03199095169290910b16179190911781559101516001909101555b6001600160a01b0380851660009081526028602090815260408083209385168352929052205461565790610dc490836148fb565b6156619084615c39565b92505b508061566f81615d56565b915050615538565b6060610cbb848460008585843b6156d05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161155a565b600080866001600160a01b031685876040516156ec9190615aae565b60006040518083038185875af1925050503d8060008114615729576040519150601f19603f3d011682016040523d82523d6000602084013e61572e565b606091505b509150915061573e828286615749565b979650505050505050565b606083156157585750816146b3565b8251156157685782518084602001fd5b8160405162461bcd60e51b815260040161155a9190615ba0565b805180151581146112eb57600080fd5b8051600681900b81146112eb57600080fd5b6000602082840312156157b657600080fd5b81356146b381615e04565b6000602082840312156157d357600080fd5b81516146b381615e04565b600080604083850312156157f157600080fd5b82356157fc81615e04565b9150602083013561580c81615e04565b809150509250929050565b60008060006060848603121561582c57600080fd5b833561583781615e04565b9250602084013561584781615e04565b9150604084013561585781615e04565b809150509250925092565b60008060006060848603121561587757600080fd5b833561588281615e04565b9250602084013561589281615e04565b929592945050506040919091013590565b600080600080608085870312156158b957600080fd5b84356158c481615e04565b935060208501356158d481615e04565b92506040850135915060608501356158eb81615e04565b939692955090935050565b6000806000806080858703121561590c57600080fd5b843561591781615e04565b9350602085013561592781615e04565b93969395505050506040820135916060013590565b600080600080600060a0868803121561595457600080fd5b853561595f81615e04565b9450602086013561596f81615e04565b94979496505050506040830135926060810135926080909101359150565b600080604083850312156159a057600080fd5b82356159ab81615e04565b946020939093013593505050565b6000806000606084860312156159ce57600080fd5b83356159d981615e04565b925060208401359150604084013561585781615e04565b600060208284031215615a0257600080fd5b6146b382615782565b600080600060608486031215615a2057600080fd5b615a2984615792565b9250615a3760208501615792565b9150615a4560408501615782565b90509250925092565b600060208284031215615a6057600080fd5b5035919050565b600060208284031215615a7957600080fd5b5051919050565b600080600060608486031215615a9557600080fd5b8351925060208401519150604084015190509250925092565b60008251615ac0818460208701615d2a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615b2d57845163ffffffff1683529383019391830191600101615b0b565b5090979650505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015615b945783516001600160a01b031683529284019291840191600101615b6f565b50909695505050505050565b6020815260008251806020840152615bbf816040850160208701615d2a565b601f01601f19169190910160400192915050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b92835260069190910b6020830152604082015260600190565b9283526020830191909152604082015260600190565b60008219821115615c4c57615c4c615dac565b500190565b600082615c6057615c60615dc2565b500490565b6000816000190483118215151615615c7f57615c7f615dac565b500290565b60008083128015600160ff1b850184121615615ca257615ca2615dac565b6001600160ff1b0384018313811615615cbd57615cbd615dac565b50500390565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615cee57615cee615dac565b81667fffffffffffff018313811615615d0957615d09615dac565b5090039392505050565b600082821015615d2557615d25615dac565b500390565b60005b83811015615d45578181015183820152602001615d2d565b83811115614fcd5750506000910152565b6000600019821415615d6a57615d6a615dac565b5060010190565b600082615d8057615d80615dc2565b500690565b60008160060b667fffffffffffff19811415615da357615da3615dac565b60000392915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114615e1957600080fd5b5056fe46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfaee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a2646970667358221220387041f4445770e88edda922a11b4527ef0755a64cad19454f2008ef77f4af2564736f6c63430008070033", "devdoc": { "kind": "dev", "methods": { @@ -3456,6 +3456,9 @@ "slashers(address)": { "notice": "Tracks whether the address is a slasher or not" }, + "totalBonds()": { + "notice": "Tracks the total amount of bonded KP3Rs in the contract" + }, "totalJobCredits(address)": { "notice": "Calculates the total credits of a given job" }, @@ -3468,6 +3471,9 @@ "unbondTime()": { "notice": "The amount of time required to pass before a keeper can unbond what he has bonded" }, + "virtualReserves()": { + "notice": "The surplus amount of wKP3Rs in escrow contract" + }, "withdraw(address)": { "notice": "Withdraw funds after unbonding has finished" }, @@ -3500,7 +3506,7 @@ "type": "t_uint256" }, { - "astId": 8417, + "astId": 8431, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "jobOwner", "offset": 0, @@ -3508,7 +3514,7 @@ "type": "t_mapping(t_address,t_address)" }, { - "astId": 8423, + "astId": 8437, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "jobPendingOwner", "offset": 0, @@ -3516,7 +3522,7 @@ "type": "t_mapping(t_address,t_address)" }, { - "astId": 5374, + "astId": 5362, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "governance", "offset": 0, @@ -3524,7 +3530,7 @@ "type": "t_address" }, { - "astId": 5378, + "astId": 5366, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "pendingGovernance", "offset": 0, @@ -3532,7 +3538,7 @@ "type": "t_address" }, { - "astId": 5985, + "astId": 5999, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "slashers", "offset": 0, @@ -3540,7 +3546,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 5991, + "astId": 6005, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "disputers", "offset": 0, @@ -3548,7 +3554,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 5479, + "astId": 5467, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_keepers", "offset": 0, @@ -3556,290 +3562,290 @@ "type": "t_struct(AddressSet)1631_storage" }, { - "astId": 5485, + "astId": 5471, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", - "label": "workCompleted", + "label": "totalBonds", "offset": 0, "slot": "9", + "type": "t_uint256" + }, + { + "astId": 5477, + "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", + "label": "workCompleted", + "offset": 0, + "slot": "10", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 5491, + "astId": 5483, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "firstSeen", "offset": 0, - "slot": "10", + "slot": "11", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 5497, + "astId": 5489, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "disputes", "offset": 0, - "slot": "11", + "slot": "12", "type": "t_mapping(t_address,t_bool)" }, { - "astId": 5505, + "astId": 5497, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "bonds", "offset": 0, - "slot": "12", + "slot": "13", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5513, + "astId": 5505, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "jobTokenCredits", "offset": 0, - "slot": "13", + "slot": "14", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5518, + "astId": 5510, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_jobLiquidityCredits", "offset": 0, - "slot": "14", + "slot": "15", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 5523, + "astId": 5515, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_jobPeriodCredits", "offset": 0, - "slot": "15", + "slot": "16", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 5529, + "astId": 5521, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_jobTokens", "offset": 0, - "slot": "16", + "slot": "17", "type": "t_mapping(t_address,t_struct(AddressSet)1631_storage)" }, { - "astId": 5535, + "astId": 5527, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_jobLiquidities", "offset": 0, - "slot": "17", + "slot": "18", "type": "t_mapping(t_address,t_struct(AddressSet)1631_storage)" }, { - "astId": 5540, + "astId": 5532, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_liquidityPool", "offset": 0, - "slot": "18", + "slot": "19", "type": "t_mapping(t_address,t_address)" }, { - "astId": 5545, + "astId": 5537, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_isKP3RToken0", "offset": 0, - "slot": "19", + "slot": "20", "type": "t_mapping(t_address,t_bool)" }, { - "astId": 5553, + "astId": 5545, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "pendingBonds", "offset": 0, - "slot": "20", + "slot": "21", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5561, + "astId": 5553, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "canActivateAfter", "offset": 0, - "slot": "21", + "slot": "22", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5569, + "astId": 5561, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "canWithdrawAfter", "offset": 0, - "slot": "22", + "slot": "23", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5577, + "astId": 5569, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "pendingUnbonds", "offset": 0, - "slot": "23", + "slot": "24", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 5583, + "astId": 5575, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "hasBonded", "offset": 0, - "slot": "24", + "slot": "25", "type": "t_mapping(t_address,t_bool)" }, { - "astId": 5587, + "astId": 5579, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_jobs", "offset": 0, - "slot": "25", + "slot": "26", "type": "t_struct(AddressSet)1631_storage" }, { - "astId": 5699, + "astId": 5692, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "keep3rV1", "offset": 0, - "slot": "27", + "slot": "28", "type": "t_address" }, { - "astId": 5703, + "astId": 5696, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "keep3rV1Proxy", "offset": 0, - "slot": "28", + "slot": "29", "type": "t_address" }, { - "astId": 5707, + "astId": 5700, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "keep3rHelper", "offset": 0, - "slot": "29", + "slot": "30", "type": "t_address" }, { - "astId": 5712, + "astId": 5705, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "bondTime", "offset": 0, - "slot": "30", + "slot": "31", "type": "t_uint256" }, { - "astId": 5717, + "astId": 5710, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "unbondTime", "offset": 0, - "slot": "31", + "slot": "32", "type": "t_uint256" }, { - "astId": 5722, + "astId": 5715, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "liquidityMinimum", "offset": 0, - "slot": "32", + "slot": "33", "type": "t_uint256" }, { - "astId": 5727, + "astId": 5720, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "rewardPeriodTime", "offset": 0, - "slot": "33", + "slot": "34", "type": "t_uint256" }, { - "astId": 5732, + "astId": 5725, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "inflationPeriod", "offset": 0, - "slot": "34", + "slot": "35", "type": "t_uint256" }, { - "astId": 5737, + "astId": 5730, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "fee", "offset": 0, - "slot": "35", + "slot": "36", "type": "t_uint256" }, { - "astId": 6418, + "astId": 6432, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "jobTokenCreditsAddedAt", "offset": 0, - "slot": "36", + "slot": "37", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 6661, + "astId": 6675, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_approvedLiquidities", "offset": 0, - "slot": "37", + "slot": "38", "type": "t_struct(AddressSet)1631_storage" }, { - "astId": 6669, + "astId": 6683, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "liquidityAmount", "offset": 0, - "slot": "39", + "slot": "40", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 6675, + "astId": 6689, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "rewardedAt", "offset": 0, - "slot": "40", + "slot": "41", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 6681, + "astId": 6695, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "workedAt", "offset": 0, - "slot": "41", + "slot": "42", "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 6687, + "astId": 6701, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_tick", "offset": 0, - "slot": "42", - "type": "t_mapping(t_address,t_struct(TickCache)14724_storage)" + "slot": "43", + "type": "t_mapping(t_address,t_struct(TickCache)14619_storage)" }, { - "astId": 8138, + "astId": 8152, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "pendingJobMigrations", "offset": 0, - "slot": "43", + "slot": "44", "type": "t_mapping(t_address,t_address)" }, { - "astId": 8144, + "astId": 8158, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_migrationCreatedAt", "offset": 0, - "slot": "44", + "slot": "45", "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 8541, + "astId": 8555, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "_initialGas", "offset": 0, - "slot": "45", - "type": "t_uint256" - }, - { - "astId": 10025, - "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", - "label": "totalBonds", - "offset": 0, "slot": "46", "type": "t_uint256" } @@ -3899,12 +3905,12 @@ "numberOfBytes": "32", "value": "t_struct(AddressSet)1631_storage" }, - "t_mapping(t_address,t_struct(TickCache)14724_storage)": { + "t_mapping(t_address,t_struct(TickCache)14619_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct IKeep3rJobFundableLiquidity.TickCache)", "numberOfBytes": "32", - "value": "t_struct(TickCache)14724_storage" + "value": "t_struct(TickCache)14619_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -3958,12 +3964,12 @@ ], "numberOfBytes": "64" }, - "t_struct(TickCache)14724_storage": { + "t_struct(TickCache)14619_storage": { "encoding": "inplace", "label": "struct IKeep3rJobFundableLiquidity.TickCache", "members": [ { - "astId": 14719, + "astId": 14614, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "current", "offset": 0, @@ -3971,7 +3977,7 @@ "type": "t_int56" }, { - "astId": 14721, + "astId": 14616, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "difference", "offset": 7, @@ -3979,7 +3985,7 @@ "type": "t_int56" }, { - "astId": 14723, + "astId": 14618, "contract": "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol:Keep3rSidechainForTestnet", "label": "period", "offset": 0, diff --git a/deployments/optimisticGoerli/Kp3rWethOracle.json b/deployments/optimisticGoerli/Kp3rWethOracle.json index e483e34..baee156 100644 --- a/deployments/optimisticGoerli/Kp3rWethOracle.json +++ b/deployments/optimisticGoerli/Kp3rWethOracle.json @@ -983,5 +983,5 @@ "type": "function" } ], - "numDeployments": 2 + "numDeployments": 4 } \ No newline at end of file diff --git a/deployments/optimisticGoerli/WethUsdOracle.json b/deployments/optimisticGoerli/WethUsdOracle.json index e483e34..baee156 100644 --- a/deployments/optimisticGoerli/WethUsdOracle.json +++ b/deployments/optimisticGoerli/WethUsdOracle.json @@ -983,5 +983,5 @@ "type": "function" } ], - "numDeployments": 2 + "numDeployments": 4 } \ No newline at end of file diff --git a/deployments/optimisticGoerli/solcInputs/0100086ed88435cb002327f6c69d11e5.json b/deployments/optimisticGoerli/solcInputs/0100086ed88435cb002327f6c69d11e5.json new file mode 100644 index 0000000..1f9c5fc --- /dev/null +++ b/deployments/optimisticGoerli/solcInputs/0100086ed88435cb002327f6c69d11e5.json @@ -0,0 +1,334 @@ +{ + "language": "Solidity", + "sources": { + "solidity/contracts/Keep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport './peripherals/jobs/Keep3rJobs.sol';\nimport './peripherals/keepers/Keep3rKeepers.sol';\nimport './peripherals/DustCollector.sol';\n\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\n}\n" + }, + "solidity/interfaces/IKeep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobManager.sol';\nimport './Keep3rJobWorkable.sol';\nimport './Keep3rJobDisputable.sol';\n\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\nimport './Keep3rKeeperDisputable.sol';\n\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\n" + }, + "solidity/contracts/peripherals/DustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '../../contracts/peripherals/Governable.sol';\nimport '../../interfaces/peripherals/IDustCollector.sol';\n\nabstract contract DustCollector is IDustCollector, Governable {\n using SafeERC20 for IERC20;\n\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external override onlyGovernance {\n if (_to == address(0)) revert ZeroAddress();\n if (_token == _ETH_ADDRESS) {\n payable(_to).transfer(_amount);\n } else {\n IERC20(_token).safeTransfer(_to, _amount);\n }\n emit DustSent(_token, _amount, _to);\n }\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" + }, + "solidity/interfaces/peripherals/IBaseErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" + }, + "solidity/interfaces/peripherals/IGovernable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" + }, + "solidity/interfaces/peripherals/IDustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @inheritdoc IKeep3rJobManager\n function addJob(address _job) external override {\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\n if (hasBonded[_job]) revert AlreadyAKeeper();\n _jobs.add(_job);\n jobOwner[_job] = msg.sender;\n emit JobAddition(_job, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobMigration.sol';\nimport '../../../interfaces/IKeep3rHelper.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 internal _initialGas;\n\n /// @inheritdoc IKeep3rJobWorkable\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\n _initialGas = _getGasLeft();\n if (_keepers.contains(_keeper)) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external override returns (bool _isBondedKeeper) {\n _initialGas = _getGasLeft();\n if (\n _keepers.contains(_keeper) &&\n bonds[_keeper][_bond] >= _minBond &&\n workCompleted[_keeper] >= _earned &&\n block.timestamp - firstSeen[_keeper] >= _age\n ) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function worked(address _keeper) external virtual override {\n if (_initialGas == 0) revert GasNotInitialized();\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _gasLeft = _getGasLeft();\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n _gasLeft = _getGasLeft();\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function bondedPayment(address _keeper, uint256 _payment) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (disputes[_keeper]) revert Disputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_keeper, _amount);\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\n }\n\n function _bondedPayment(\n address _job,\n address _keeper,\n uint256 _payment\n ) internal {\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\n\n workedAt[_job] = block.timestamp;\n _jobLiquidityCredits[_job] -= _payment;\n bonds[_keeper][keep3rV1] += _payment;\n workCompleted[_keeper] += _payment;\n totalBonds += _payment;\n }\n\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\n /// @param _gasLeft Amount of gas left after working the job\n /// @param _extraGas Amount of expected unaccounted gas\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\n /// @return _payment Amount to be payed in KP3R tokens\n function _calculatePayment(\n uint256 _gasLeft,\n uint256 _extraGas,\n uint256 _oneEthQuote,\n uint256 _boost\n ) internal view returns (uint256 _payment) {\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\n }\n\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\n _gasLeft = (gasleft() * 64) / 63;\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\nimport '../Keep3rDisputable.sol';\n\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\n\n try IERC20(_token).transfer(governance, _amount) {} catch {}\n jobTokenCredits[_job][_token] -= _amount;\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit JobSlashToken(_job, _token, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobPendingOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\n jobPendingOwner[_job] = _newOwner;\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\n }\n\n /// @inheritdoc IKeep3rJobOwnership\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\n address _previousOwner = jobOwner[_job];\n\n jobOwner[_job] = jobPendingOwner[_job];\n delete jobPendingOwner[_job];\n\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\n }\n\n modifier onlyJobOwner(address _job) {\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\n _;\n }\n\n modifier onlyPendingJobOwner(address _job) {\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\nimport './Keep3rRoles.sol';\n\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @notice List of all enabled keepers\n EnumerableSet.AddressSet internal _keepers;\n\n /// @inheritdoc IKeep3rAccountance\n uint256 public override totalBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override workCompleted;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override firstSeen;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override disputes;\n\n /// @inheritdoc IKeep3rAccountance\n /// @notice Mapping (job => bonding => amount)\n mapping(address => mapping(address => uint256)) public override bonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\n\n /// @notice The current liquidity credits available for a job\n mapping(address => uint256) internal _jobLiquidityCredits;\n\n /// @notice Map the address of a job to its correspondent periodCredits\n mapping(address => uint256) internal _jobPeriodCredits;\n\n /// @notice Enumerable array of Job Tokens for Credits\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\n\n /// @notice List of liquidities that a job has (job => liquidities)\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\n\n /// @notice Liquidity pool to observe\n mapping(address => address) internal _liquidityPool;\n\n /// @notice Tracks if a pool has KP3R as token0\n mapping(address => bool) internal _isKP3RToken0;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override hasBonded;\n\n /// @notice List of all enabled jobs\n EnumerableSet.AddressSet internal _jobs;\n\n /// @inheritdoc IKeep3rAccountance\n function jobs() external view override returns (address[] memory _list) {\n _list = _jobs.values();\n }\n\n /// @inheritdoc IKeep3rAccountance\n function keepers() external view override returns (address[] memory _list) {\n _list = _keepers.values();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport './DustCollector.sol';\nimport './Governable.sol';\n\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override slashers;\n\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override disputers;\n\n constructor(address _governance) Governable(_governance) DustCollector() {}\n\n /// @inheritdoc IKeep3rRoles\n function addSlasher(address _slasher) external override onlyGovernance {\n if (_slasher == address(0)) revert ZeroAddress();\n if (slashers[_slasher]) revert SlasherExistent();\n slashers[_slasher] = true;\n emit SlasherAdded(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeSlasher(address _slasher) external override onlyGovernance {\n if (!slashers[_slasher]) revert SlasherUnexistent();\n delete slashers[_slasher];\n emit SlasherRemoved(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function addDisputer(address _disputer) external override onlyGovernance {\n if (_disputer == address(0)) revert ZeroAddress();\n if (disputers[_disputer]) revert DisputerExistent();\n disputers[_disputer] = true;\n emit DisputerAdded(_disputer);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeDisputer(address _disputer) external override onlyGovernance {\n if (!disputers[_disputer]) revert DisputerUnexistent();\n delete disputers[_disputer];\n emit DisputerRemoved(_disputer);\n }\n\n /// @notice Functions with this modifier can only be called by either a slasher or governance\n modifier onlySlasher {\n if (!slashers[msg.sender]) revert OnlySlasher();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by either a disputer or governance\n modifier onlyDisputer {\n if (!disputers[msg.sender]) revert OnlyDisputer();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Governable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public override governance;\n\n /// @inheritdoc IGovernable\n address public override pendingGovernance;\n\n constructor(address _governance) {\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\n governance = _governance;\n }\n\n /// @inheritdoc IGovernable\n function setGovernance(address _governance) external override onlyGovernance {\n pendingGovernance = _governance;\n emit GovernanceProposal(_governance);\n }\n\n /// @inheritdoc IGovernable\n function acceptGovernance() external override onlyPendingGovernance {\n governance = pendingGovernance;\n delete pendingGovernance;\n emit GovernanceSet(governance);\n }\n\n /// @notice Functions with this modifier can only be called by governance\n modifier onlyGovernance {\n if (msg.sender != governance) revert OnlyGovernance();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernance\n modifier onlyPendingGovernance {\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\n _;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\n\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobMigration\n mapping(address => address) public override pendingJobMigrations;\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\n\n /// @inheritdoc IKeep3rJobMigration\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\n if (_fromJob == _toJob) revert JobMigrationImpossible();\n\n pendingJobMigrations[_fromJob] = _toJob;\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\n\n emit JobMigrationRequested(_fromJob, _toJob);\n }\n\n /// @inheritdoc IKeep3rJobMigration\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\n\n // force job credits update for both jobs\n _settleJobAccountance(_fromJob);\n _settleJobAccountance(_toJob);\n\n // migrate tokens\n while (_jobTokens[_fromJob].length() > 0) {\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\n _jobTokens[_fromJob].remove(_tokenToMigrate);\n _jobTokens[_toJob].add(_tokenToMigrate);\n }\n\n // migrate liquidities\n while (_jobLiquidities[_fromJob].length() > 0) {\n address _liquidity = _jobLiquidities[_fromJob].at(0);\n\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\n delete liquidityAmount[_fromJob][_liquidity];\n\n _jobLiquidities[_toJob].add(_liquidity);\n _jobLiquidities[_fromJob].remove(_liquidity);\n }\n\n // migrate job balances\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\n delete _jobPeriodCredits[_fromJob];\n\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\n delete _jobLiquidityCredits[_fromJob];\n\n // stop _fromJob from being a job\n delete rewardedAt[_fromJob];\n _jobs.remove(_fromJob);\n\n // delete unused data slots\n delete jobOwner[_fromJob];\n delete jobPendingOwner[_fromJob];\n delete _migrationCreatedAt[_fromJob][_toJob];\n delete pendingJobMigrations[_fromJob];\n\n emit JobMigrationSuccessful(_fromJob, _toJob);\n }\n}\n" + }, + "solidity/interfaces/IKeep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rHelperParameters.sol';\n\n/// @title Keep3rHelper contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelper is IKeep3rHelperParameters {\n // Errors\n\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\n error LiquidityPairInvalid();\n\n // Methods\n // solhint-enable func-name-mixedcase\n\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\n /// @param _eth The amount of ETH\n /// @return _amountOut The amount of KP3R\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\n\n /// @notice Returns the amount of KP3R the keeper has bonded\n /// @param _keeper The address of the keeper to check\n /// @return _amountBonded The amount of KP3R the keeper has bonded\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\n /// @param _keeper The address of the keeper to check\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\n\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\n /// @return _rewardBoost The reward boost that corresponds to the keeper\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\n\n /// @notice Given a pool address, returns the underlying tokens of the pair\n /// @param _pool Address of the correspondant pool\n /// @return _token0 Address of the first token of the pair\n /// @return _token1 Address of the second token of the pair\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\n\n /// @notice Defines the order of the tokens in the pair for twap calculations\n /// @param _pool Address of the correspondant pool\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\n\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\n /// @param _pool Address of the pool to observe\n /// @param _secondsAgo Array with time references to observe\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\n /// @return _success Boolean indicating if the observe call was succesfull\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n );\n\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\n /// @param _bonds Amount of bonded KP3R owned by the keeper\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\n /// @return _extra Amount of extra gas that should be added to the gas spent\n function getPaymentParams(uint256 _bonds)\n external\n view\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n );\n\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\n /// @param _liquidityAmount Amount of liquidity to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _kp3rAmount);\n\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\n /// @param _baseAmount Amount of token to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _quoteAmount);\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice Cooldown between withdrawals\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override nonReentrant {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n // KP3R shouldn't be used for direct token payments\n if (_token == keep3rV1) revert TokenUnallowed();\n uint256 _before = IERC20(_token).balanceOf(address(this));\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\n uint256 _tokenFee = (_received * fee) / _BASE;\n jobTokenCredits[_job][_token] += _received - _tokenFee;\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\n IERC20(_token).safeTransfer(governance, _tokenFee);\n _jobTokens[_job].add(_token);\n\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\n }\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external override nonReentrant onlyJobOwner(_job) {\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\n if (disputes[_job]) revert JobDisputed();\n\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_receiver, _amount);\n\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/IPairManager.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '../../libraries/FullMath.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice List of liquidities that are accepted in the system\n EnumerableSet.AddressSet internal _approvedLiquidities;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override rewardedAt;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override workedAt;\n\n /// @notice Tracks an address and returns its TickCache\n mapping(address => TickCache) internal _tick;\n\n // Views\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approvedLiquidities() external view override returns (address[] memory _list) {\n _list = _approvedLiquidities.values();\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n _periodCredits += _getReward(\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\n );\n }\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n\n // If the job was rewarded in the past 1 period time\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\n // If the job has period credits, update minted job credits to new twap\n _liquidityCredits = _periodCredits > 0\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\n } else {\n // Else return a full period worth of credits if current credits have expired\n _liquidityCredits = _periodCredits;\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n uint256 _cooldown = block.timestamp;\n\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\n // Will calculate cooldown if it outdated\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will calculate cooldown from last reward reference in this period\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\n } else {\n // Will calculate cooldown from last reward timestamp\n _cooldown -= rewardedAt[_job];\n }\n } else {\n // Will calculate cooldown from period start if expired\n _cooldown -= _period(block.timestamp);\n }\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\n\n if (_tick[_liquidity].period == lastPeriod) {\n // Will only ask for current period accumulator if liquidity is outdated\n uint32[] memory _secondsAgo = new uint32[](1);\n int56 previousTick = _tick[_liquidity].current;\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - previousTick;\n } else if (_tick[_liquidity].period < lastPeriod) {\n // Will ask for 2 accumulators if liquidity is expired\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n }\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Methods\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n _settleJobAccountance(_job);\n _jobLiquidityCredits[_job] += _amount;\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\n delete _liquidityPool[_liquidity];\n delete _isKP3RToken0[_liquidity];\n delete _tick[_liquidity];\n\n emit LiquidityRevocation(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override nonReentrant {\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\n if (!_jobs.contains(_job)) revert JobUnavailable();\n\n _jobLiquidities[_job].add(_liquidity);\n\n _settleJobAccountance(_job);\n\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\n liquidityAmount[_job][_liquidity] += _amount;\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlyJobOwner(_job) {\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\n pendingUnbonds[_job][_liquidity] += _amount;\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit Unbonding(_job, _liquidity, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external override onlyJobOwner(_job) {\n if (_receiver == address(0)) revert ZeroAddress();\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\n if (disputes[_job]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[_job][_liquidity];\n\n delete pendingUnbonds[_job][_liquidity];\n delete canWithdrawAfter[_job][_liquidity];\n\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\n }\n\n // Internal functions\n\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\n if (rewardedAt[_job] < _period(block.timestamp)) {\n // Will exit function if job has been rewarded in current period\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\n // Will reset job to period syncronicity if a full period passed without rewards\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] = _period(block.timestamp);\n _rewarded = true;\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will reset job's syncronicity if last reward was more than epoch ago\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] += rewardPeriodTime;\n _rewarded = true;\n } else if (workedAt[_job] < _period(block.timestamp)) {\n // First keeper on period has to update job accountance to current twaps\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\n // Updating job accountance does not reward job\n }\n }\n }\n\n /// @notice Only called if _jobLiquidityCredits < payment\n function _rewardJobCredits(address _job) internal {\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\n rewardedAt[_job] = block.timestamp;\n }\n\n /// @notice Updates accountance for _jobPeriodCredits\n function _updateJobPeriod(address _job) internal {\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\n }\n\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n if (_tick[_liquidity].period != _period(block.timestamp)) {\n // Updates liquidity cache only if needed\n _tick[_liquidity] = observeLiquidity(_liquidity);\n }\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\n }\n }\n }\n\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\n function _unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) internal nonReentrant {\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\n\n // Ensures current twaps in job liquidities\n _updateJobPeriod(_job);\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\n\n // A liquidity can be revoked causing a job to have 0 periodCredits\n if (_jobPeriodCredits[_job] > 0) {\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\n }\n\n liquidityAmount[_job][_liquidity] -= _amount;\n if (liquidityAmount[_job][_liquidity] == 0) {\n _jobLiquidities[_job].remove(_liquidity);\n }\n }\n\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\n if (_timePassed < rewardPeriodTime) {\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\n } else _result = _multiplier;\n }\n\n /// @notice Returns the start of the period of the provided timestamp\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\n return _timestamp - (_timestamp % rewardPeriodTime);\n }\n\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\n }\n\n /// @notice Returns underlying KP3R amount for a given liquidity amount\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\n if (_tick[_liquidity].period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\n }\n }\n\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\n /// @dev Ensures a maximum of 1 period of credits\n function _settleJobAccountance(address _job) internal virtual {\n _updateJobCreditsIfNeeded(_job);\n _rewardJobCredits(_job);\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/IKeep3rHelper.sol';\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\nimport './Keep3rAccountance.sol';\n\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1Proxy;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rHelper;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override bondTime = 3 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override unbondTime = 14 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override liquidityMinimum = 3 ether;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override rewardPeriodTime = 5 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override inflationPeriod = 34 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override fee = 30;\n\n /// @notice The base that will be used to calculate the fee\n uint256 internal constant _BASE = 10_000;\n\n /// @notice The minimum reward period\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) {\n keep3rHelper = _keep3rHelper;\n keep3rV1 = _keep3rV1;\n keep3rV1Proxy = _keep3rV1Proxy;\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\n if (_keep3rHelper == address(0)) revert ZeroAddress();\n keep3rHelper = _keep3rHelper;\n emit Keep3rHelperChange(_keep3rHelper);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\n if (_keep3rV1 == address(0)) revert ZeroAddress();\n _mint(totalBonds);\n\n keep3rV1 = _keep3rV1;\n emit Keep3rV1Change(_keep3rV1);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\n keep3rV1Proxy = _keep3rV1Proxy;\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\n bondTime = _bondTime;\n emit BondTimeChange(_bondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\n unbondTime = _unbondTime;\n emit UnbondTimeChange(_unbondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\n liquidityMinimum = _liquidityMinimum;\n emit LiquidityMinimumChange(_liquidityMinimum);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\n rewardPeriodTime = _rewardPeriodTime;\n emit RewardPeriodTimeChange(_rewardPeriodTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\n inflationPeriod = _inflationPeriod;\n emit InflationPeriodChange(_inflationPeriod);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setFee(uint256 _fee) external override onlyGovernance {\n fee = _fee;\n emit FeeChange(_fee);\n }\n\n function _mint(uint256 _amount) internal {\n totalBonds -= _amount;\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IGovernable.sol';\n\ninterface IKeep3rV1Proxy is IGovernable {\n // Structs\n struct Recipient {\n address recipient;\n uint256 caps;\n }\n\n // Variables\n function keep3rV1() external view returns (address);\n\n function minter() external view returns (address);\n\n function next(address) external view returns (uint256);\n\n function caps(address) external view returns (uint256);\n\n function recipients() external view returns (address[] memory);\n\n function recipientsCaps() external view returns (Recipient[] memory);\n\n // Errors\n error Cooldown();\n error NoDrawableAmount();\n error ZeroAddress();\n error OnlyMinter();\n\n // Methods\n function addRecipient(address recipient, uint256 amount) external;\n\n function removeRecipient(address recipient) external;\n\n function draw() external returns (uint256 _amount);\n\n function setKeep3rV1(address _keep3rV1) external;\n\n function setMinter(address _minter) external;\n\n function mint(uint256 _amount) external;\n\n function mint(address _account, uint256 _amount) external;\n\n function setKeep3rV1Governance(address _governance) external;\n\n function acceptKeep3rV1Governance() external;\n\n function dispute(address _keeper) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function addJob(address _job) external;\n\n function removeJob(address _job) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n}\n" + }, + "solidity/interfaces/IKeep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rHelperParameters contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelperParameters {\n // Structs\n\n /// @dev KP3R-WETH Pool address and isKP3RToken0\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\n struct TokenOraclePool {\n address poolAddress;\n bool isTKNToken0;\n }\n\n // Errors\n\n /// @notice Throws when pool does not have KP3R as token0 nor token1\n error InvalidOraclePool();\n\n // Events\n\n /// @notice Emitted when the kp3r weth pool is changed\n /// @param _address Address of the new kp3r weth pool\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\n\n /// @notice Emitted when the minimum boost multiplier is changed\n /// @param _minBoost The minimum boost multiplier\n event MinBoostChange(uint256 _minBoost);\n\n /// @notice Emitted when the maximum boost multiplier is changed\n /// @param _maxBoost The maximum boost multiplier\n event MaxBoostChange(uint256 _maxBoost);\n\n /// @notice Emitted when the target bond amount is changed\n /// @param _targetBond The target bond amount\n event TargetBondChange(uint256 _targetBond);\n\n /// @notice Emitted when the Keep3r V2 address is changed\n /// @param _keep3rV2 The address of Keep3r V2\n event Keep3rV2Change(address _keep3rV2);\n\n /// @notice Emitted when the work extra gas amount is changed\n /// @param _workExtraGas The work extra gas\n event WorkExtraGasChange(uint256 _workExtraGas);\n\n /// @notice Emitted when the quote twap time is changed\n /// @param _quoteTwapTime The twap time for quoting\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\n\n /// @notice Emitted when minimum rewarded gas fee is changed\n /// @param _minBaseFee The minimum rewarded gas fee\n event MinBaseFeeChange(uint256 _minBaseFee);\n\n /// @notice Emitted when minimum rewarded priority fee is changed\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\n event MinPriorityFeeChange(uint256 _minPriorityFee);\n\n // Variables\n\n /// @notice Address of KP3R token\n /// @return _kp3r Address of KP3R token\n // solhint-disable func-name-mixedcase\n function KP3R() external view returns (address _kp3r);\n\n /// @notice The boost base used to calculate the boost rewards for the keeper\n /// @return _base The boost base number\n function BOOST_BASE() external view returns (uint256 _base);\n\n /// @notice KP3R-WETH pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\n /// @return _multiplier The minimum boost multiplier\n function minBoost() external view returns (uint256 _multiplier);\n\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\n /// @return _multiplier The maximum boost multiplier\n function maxBoost() external view returns (uint256 _multiplier);\n\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\n /// @return _target The amount of KP3R that comforms the targetBond\n function targetBond() external view returns (uint256 _target);\n\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\n /// @return _workExtraGas The work unaccounted gas amount\n function workExtraGas() external view returns (uint256 _workExtraGas);\n\n /// @notice The twap time for quoting\n /// @return _quoteTwapTime The twap time\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\n\n /// @notice The minimum base fee that is used to calculate keeper rewards\n /// @return _minBaseFee The minimum rewarded gas fee\n function minBaseFee() external view returns (uint256 _minBaseFee);\n\n /// @notice The minimum priority fee that is also rewarded for keepers\n /// @return _minPriorityFee The minimum rewarded priority fee\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\n\n /// @notice Address of Keep3r V2\n /// @return _keep3rV2 Address of Keep3r V2\n function keep3rV2() external view returns (address _keep3rV2);\n\n // Methods\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function setKp3rWethPool(address _poolAddress) external;\n\n /// @notice Sets the minimum boost multiplier\n /// @param _minBoost The minimum boost multiplier\n function setMinBoost(uint256 _minBoost) external;\n\n /// @notice Sets the maximum boost multiplier\n /// @param _maxBoost The maximum boost multiplier\n function setMaxBoost(uint256 _maxBoost) external;\n\n /// @notice Sets the target bond amount\n /// @param _targetBond The target bond amount\n function setTargetBond(uint256 _targetBond) external;\n\n /// @notice Sets the Keep3r V2 address\n /// @param _keep3rV2 The address of Keep3r V2\n function setKeep3rV2(address _keep3rV2) external;\n\n /// @notice Sets the work extra gas amount\n /// @param _workExtraGas The work extra gas\n function setWorkExtraGas(uint256 _workExtraGas) external;\n\n /// @notice Sets the quote twap time\n /// @param _quoteTwapTime The twap time for quoting\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\n\n /// @notice Sets the minimum rewarded gas fee\n /// @param _minBaseFee The minimum rewarded gas fee\n function setMinBaseFee(uint256 _minBaseFee) external;\n\n /// @notice Sets the minimum rewarded gas priority fee\n /// @param _minPriorityFee The minimum rewarded priority fee\n function setMinPriorityFee(uint256 _minPriorityFee) external;\n}\n" + }, + "solidity/interfaces/IPairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n/// @title Pair Manager interface\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\ninterface IPairManager is IERC20Metadata {\n /// @notice Address of the factory from which the pair manager was created\n /// @return _factory The address of the PairManager Factory\n function factory() external view returns (address _factory);\n\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\n /// @return _pool The address of the pool\n function pool() external view returns (address _pool);\n\n /// @notice Token0 of the pool\n /// @return _token0 The address of token0\n function token0() external view returns (address _token0);\n\n /// @notice Token1 of the pool\n /// @return _token1 The address of token1\n function token1() external view returns (address _token1);\n}\n" + }, + "solidity/contracts/libraries/FullMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (~denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "solidity/contracts/peripherals/Keep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rParameters.sol';\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\n\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\n /// @inheritdoc IKeep3rDisputable\n function dispute(address _jobOrKeeper) external override onlyDisputer {\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\n disputes[_jobOrKeeper] = true;\n emit Dispute(_jobOrKeeper, msg.sender);\n }\n\n /// @inheritdoc IKeep3rDisputable\n function resolve(address _jobOrKeeper) external override onlyDisputer {\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\n disputes[_jobOrKeeper] = false;\n emit Resolve(_jobOrKeeper, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rKeeperFundable.sol';\nimport '../Keep3rDisputable.sol';\nimport '../../../interfaces/external/IKeep3rV1.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\n }\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function revoke(address _keeper) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _keepers.remove(_keeper);\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\n emit KeeperRevoke(_keeper, msg.sender);\n }\n\n function _slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) internal {\n if (_bonded != keep3rV1) {\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\n }\n bonds[_keeper][_bonded] -= _bondAmount;\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nimport '../../../interfaces/external/IKeep3rV1.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperFundable\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\n if (disputes[msg.sender]) revert Disputed();\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\n\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\n\n hasBonded[msg.sender] = true;\n pendingBonds[msg.sender][_bonding] += _amount;\n\n emit Bonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function activate(address _bonding) external override {\n address _keeper = msg.sender;\n if (disputes[_keeper]) revert Disputed();\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\n if (_canActivateAfter == 0) revert BondsUnexistent();\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\n\n if (firstSeen[_keeper] == 0) {\n firstSeen[_keeper] = block.timestamp;\n }\n _keepers.add(_keeper);\n\n uint256 _amount = pendingBonds[_keeper][_bonding];\n delete pendingBonds[_keeper][_bonding];\n\n // bond provided tokens\n bonds[_keeper][_bonding] += _amount;\n if (_bonding == keep3rV1) {\n totalBonds += _amount;\n _depositBonds(_amount);\n }\n\n emit Activation(_keeper, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function unbond(address _bonding, uint256 _amount) external override {\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\n bonds[msg.sender][_bonding] -= _amount;\n pendingUnbonds[msg.sender][_bonding] += _amount;\n\n emit Unbonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function withdraw(address _bonding) external override nonReentrant {\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\n if (disputes[msg.sender]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\n\n delete pendingUnbonds[msg.sender][_bonding];\n delete canWithdrawAfter[msg.sender][_bonding];\n\n if (_bonding == keep3rV1) _mint(_amount);\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(msg.sender, _bonding, _amount);\n }\n\n function _depositBonds(uint256 _amount) internal virtual {\n IKeep3rV1(keep3rV1).burn(_amount);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n// solhint-disable func-name-mixedcase\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\n // Structs\n struct Checkpoint {\n uint32 fromBlock;\n uint256 votes;\n }\n\n // Events\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event JobAdded(address indexed _job, uint256 _block, address _governance);\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\n event KeeperDispute(address indexed _keeper, uint256 _block);\n event KeeperResolved(address indexed _keeper, uint256 _block);\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\n\n // Variables\n function KPRH() external returns (address);\n\n function delegates(address _delegator) external view returns (address);\n\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\n\n function numCheckpoints(address _account) external view returns (uint32);\n\n function DOMAIN_TYPEHASH() external returns (bytes32);\n\n function DOMAINSEPARATOR() external returns (bytes32);\n\n function DELEGATION_TYPEHASH() external returns (bytes32);\n\n function PERMIT_TYPEHASH() external returns (bytes32);\n\n function nonces(address _user) external view returns (uint256);\n\n function BOND() external returns (uint256);\n\n function UNBOND() external returns (uint256);\n\n function LIQUIDITYBOND() external returns (uint256);\n\n function FEE() external returns (uint256);\n\n function BASE() external returns (uint256);\n\n function ETH() external returns (address);\n\n function bondings(address _user, address _bonding) external view returns (uint256);\n\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\n\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function bonds(address _keeper, address _bonding) external view returns (uint256);\n\n function votes(address _delegator) external view returns (uint256);\n\n function firstSeen(address _keeper) external view returns (uint256);\n\n function disputes(address _keeper) external view returns (bool);\n\n function lastJob(address _keeper) external view returns (uint256);\n\n function workCompleted(address _keeper) external view returns (uint256);\n\n function jobs(address _job) external view returns (bool);\n\n function credits(address _job, address _credit) external view returns (uint256);\n\n function liquidityProvided(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmountsUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function jobProposalDelay(address _job) external view returns (uint256);\n\n function liquidityApplied(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmount(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function keepers(address _keeper) external view returns (bool);\n\n function blacklist(address _keeper) external view returns (bool);\n\n function keeperList(uint256 _index) external view returns (address);\n\n function jobList(uint256 _index) external view returns (address);\n\n function governance() external returns (address);\n\n function pendingGovernance() external returns (address);\n\n function liquidityAccepted(address _liquidity) external view returns (bool);\n\n function liquidityPairs(uint256 _index) external view returns (address);\n\n // Methods\n function getCurrentVotes(address _account) external view returns (uint256);\n\n function addCreditETH(address _job) external payable;\n\n function addCredit(\n address _credit,\n address _job,\n uint256 _amount\n ) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function pairs() external view returns (address[] memory);\n\n function addLiquidityToJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function applyCreditToJob(\n address _provider,\n address _liquidity,\n address _job\n ) external;\n\n function unbondLiquidityFromJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function removeLiquidityFromJob(address _liquidity, address _job) external;\n\n function mint(uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n\n function worked(address _keeper) external;\n\n function receipt(\n address _credit,\n address _keeper,\n uint256 _amount\n ) external;\n\n function receiptETH(address _keeper, uint256 _amount) external;\n\n function addJob(address _job) external;\n\n function getJobs() external view returns (address[] memory);\n\n function removeJob(address _job) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function isKeeper(address _keeper) external returns (bool);\n\n function isMinKeeper(\n address _keeper,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function bond(address _bonding, uint256 _amount) external;\n\n function getKeepers() external view returns (address[] memory);\n\n function activate(address _bonding) external;\n\n function unbond(address _bonding, uint256 _amount) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function withdraw(address _bonding) external;\n\n function dispute(address _keeper) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function permit(\n address _owner,\n address _spender,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3r.sol';\n\ncontract Keep3rForTestnet is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3r.sol';\n\ncontract Keep3rForTest is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3r.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\n\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @param _governance Address of governance\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\n constructor(\n address _governance, // governance\n address _keep3rHelperSidechain, // helper\n address _wrappedKP3R, // keep3rV1\n address _keep3rEscrow // keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\n\n // Keep3rSidechainAccountance\n\n /// @inheritdoc IKeep3rSidechainAccountance\n function virtualReserves() external view override returns (int256 _virtualReserves) {\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\n }\n\n // Keep3rJobFundableLiquidity\n\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\n /// @param _liquidity Address of the liquidity token being approved\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\n /// @param _liquidity Address of the liquidity token being observed\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n\n // Will always ask for 2 accumulators in sidechain\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Keep3rJobsWorkable\n\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\n function worked(address) external pure override {\n revert Deprecated();\n }\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Uses a USD per gas unit payment mechanism\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\n if (_initialGas == 0) revert GasNotInitialized();\n // Gas used for quote calculations & payment is not rewarded\n uint256 _gasLeft = _getGasLeft();\n\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\n\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _kp3rPayment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\n }\n\n // Keep3rKeeperFundable\n\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\n function _depositBonds(uint256 _amount) internal virtual override {\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\n }\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// solhint-disable-next-line no-empty-blocks\n\nimport '../peripherals/IMintable.sol';\n\n/// @title Keep3rEscrow contract\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\ninterface IKeep3rEscrow is IMintable {\n /// @notice Emitted when Keep3rEscrow#deposit function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _sender The address that called the function\n /// @param _amount The amount of wKP3R the user deposited\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#mint function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _recipient The address that will received the newly minted wKP3R\n /// @param _amount The amount of wKP3R minted to the recipient\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\n /// @param _newWKP3R The address of the wKP3R contract\n event wKP3RSet(address _newWKP3R);\n\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\n error InsufficientBalance();\n\n /// @notice Lists the address of the wKP3R contract\n /// @return _wKP3RAddress The address of wKP3R\n function wKP3R() external view returns (address _wKP3RAddress);\n\n /// @notice Deposits wKP3R into the contract\n /// @param _amount The amount of wKP3R to deposit\n function deposit(uint256 _amount) external;\n\n /// @notice mints wKP3R to the recipient\n /// @param _amount The amount of wKP3R to mint\n function mint(uint256 _amount) external;\n\n /// @notice sets the wKP3R address\n /// @param _wKP3R the wKP3R address\n function setWKP3R(address _wKP3R) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../IKeep3rHelper.sol';\n\n/// @title Keep3rHelperSidechain contract\n/// @notice Contains all the helper functions for sidechain keep3r implementations\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\n // Events\n\n /// @notice The oracle for a liquidity has been saved\n /// @param _liquidity The address of the given liquidity\n /// @param _oraclePool The address of the oracle pool\n event OracleSet(address _liquidity, address _oraclePool);\n\n /// @notice Emitted when the WETH USD pool is changed\n /// @param _address Address of the new WETH USD pool\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\n\n /// Variables\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n /// @return _weth Address of WETH token\n // solhint-disable func-name-mixedcase\n function WETH() external view returns (address _weth);\n\n /// @return _oracle The address of the observable pool for given liquidity\n function oracle(address _liquidity) external view returns (address _oracle);\n\n /// @notice WETH-USD pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice Quotes USD to ETH\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\n /// @param _usd The amount of USD to quote to ETH\n /// @return _eth The resulting amount of ETH after quoting the USD\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\n\n /// Methods\n\n /// @notice Sets an oracle for a given liquidity\n /// @param _liquidity The address of the liquidity\n /// @param _oracle The address of the pool used to quote the liquidity from\n /// @dev The oracle must contain KP3R as either token0 or token1\n function setOracle(address _liquidity, address _oracle) external;\n\n /// @notice Sets an oracle for querying WETH/USD quote\n /// @param _poolAddress The address of the pool used as oracle\n /// @dev The oracle must contain WETH as either token0 or token1\n function setWethUsdPool(address _poolAddress) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IKeep3rJobs.sol';\n\n/// @title Keep3rJobWorkableRated contract\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\n /// @notice Throws when job contract calls deprecated worked(address) function\n error Deprecated();\n\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title IKeep3rSidechainAccountance interface\n/// @notice Implements a view to get the amount of credits that can be withdrawn\ninterface IKeep3rSidechainAccountance {\n /// @notice The surplus amount of wKP3Rs in escrow contract\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\n function virtualReserves() external view returns (int256 _virtualReserves);\n}\n" + }, + "solidity/interfaces/peripherals/IMintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IGovernable.sol';\nimport './IBaseErrors.sol';\n\n/// @title Mintable contract\n/// @notice Manages the minter role\ninterface IMintable is IBaseErrors, IGovernable {\n // Events\n\n /// @notice Emitted when governance sets a new minter\n /// @param _minter Address of the new minter\n event MinterSet(address _minter);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not the minter\n error OnlyMinter();\n\n // Variables\n\n /// @notice Stores the minter address\n /// @return _minter The minter addresss\n function minter() external view returns (address _minter);\n\n // Methods\n\n /// @notice Sets a new address to be the minter\n /// @param _minter The address set as the minter\n function setMinter(address _minter) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rSidechainForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTest is Keep3rSidechain {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _governance,\n address _keep3rHelper,\n address _wrappedKP3R,\n address _keep3rEscrow\n ) Keep3rSidechain(_governance, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n}\n" + }, + "solidity/for-test/JobRatedForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\n\ncontract JobRatedForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n uint256 public usdPerGasUnit = 1_000e9;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n}\n" + }, + "solidity/for-test/JobForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract JobForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/for-test/BasicJob.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract BasicJob {\n error KeeperNotValid();\n\n address public keep3r;\n uint256 public nonce;\n uint256[] public array;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external upkeep {}\n\n function workHard(uint256 _howHard) external upkeep {\n for (uint256 i = nonce; i < _howHard; i++) {\n nonce++;\n }\n }\n\n function workRefund(uint256 _howHard) external upkeep {\n for (uint256 i; i < _howHard; i++) {\n array.push(i);\n }\n\n while (array.length > 0) {\n array.pop();\n }\n }\n\n modifier upkeep() {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\n _;\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/peripherals/IBaseErrors.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/external/IKeep3rV1.sol';\nimport '../interfaces/IKeep3rHelperParameters.sol';\nimport './peripherals/Governable.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\n /// @inheritdoc IKeep3rHelperParameters\n address public immutable override KP3R;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public constant override BOOST_BASE = 10_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBoost = 11_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override maxBoost = 12_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override targetBond = 200 ether;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override workExtraGas = 34_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint32 public override quoteTwapTime = 10 minutes;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBaseFee = 15e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minPriorityFee = 2e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n address public override keep3rV2;\n\n /// @inheritdoc IKeep3rHelperParameters\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Governable(_governance) {\n KP3R = _kp3r;\n keep3rV2 = _keep3rV2;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setKp3rWethPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\n minBoost = _minBoost;\n emit MinBoostChange(minBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\n maxBoost = _maxBoost;\n emit MaxBoostChange(maxBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\n targetBond = _targetBond;\n emit TargetBondChange(targetBond);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\n if (_keep3rV2 == address(0)) revert ZeroAddress();\n keep3rV2 = _keep3rV2;\n emit Keep3rV2Change(keep3rV2);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\n workExtraGas = _workExtraGas;\n emit WorkExtraGasChange(workExtraGas);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\n _setQuoteTwapTime(_quoteTwapTime);\n }\n\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\n quoteTwapTime = _quoteTwapTime;\n emit QuoteTwapTimeChange(quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\n minBaseFee = _minBaseFee;\n emit MinBaseFeeChange(minBaseFee);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\n minPriorityFee = _minPriorityFee;\n emit MinPriorityFeeChange(minPriorityFee);\n }\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function _setKp3rWethPool(address _poolAddress) internal {\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\n\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\n\n return TokenOraclePool(_poolAddress, _isTKNToken0);\n }\n}\n" + }, + "solidity/contracts/libraries/TickMath.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n// solhint-disable\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n // Second inequality must be < because the price can never reach the price at the max tick\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport './pool/IUniswapV3PoolImmutables.sol';\nimport './pool/IUniswapV3PoolState.sol';\nimport './pool/IUniswapV3PoolDerivedState.sol';\nimport './pool/IUniswapV3PoolActions.sol';\nimport './pool/IUniswapV3PoolOwnerActions.sol';\nimport './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolEvents\n{\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// observationIndex The index of the last oracle observation that was written,\n /// observationCardinality The current maximum number of observations stored in the pool,\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper,\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return _liquidity The amount of liquidity in the position,\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 _liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// Returns initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" + }, + "solidity/for-test/UniV3PairManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport '../contracts/libraries/LiquidityAmounts.sol';\nimport '../contracts/libraries/FixedPoint96.sol';\nimport '../contracts/libraries/FullMath.sol';\nimport '../contracts/libraries/TickMath.sol';\nimport '../contracts/UniV3PairManager.sol';\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManagerForTest is UniV3PairManager {\n constructor(address _pool, address _governance) UniV3PairManager(_pool, _governance) {}\n\n function internalAddLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n external\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n return _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n }\n\n function internalPay(\n address token,\n address payer,\n address recipient,\n uint256 value\n ) external {\n return _pay(token, payer, recipient, value);\n }\n\n function internalMint(address dst, uint256 amount) external {\n return _mint(dst, amount);\n }\n\n function internalBurn(address dst, uint256 amount) external {\n return _burn(dst, amount);\n }\n\n function internalTransferTokens(\n address src,\n address dst,\n uint256 amount\n ) external {\n _transferTokens(src, dst, amount);\n }\n\n function internalSafeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) external {\n _safeTransferFrom(token, from, to, value);\n }\n\n receive() external payable {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "solidity/contracts/libraries/LiquidityAmounts.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport './FullMath.sol';\nimport './FixedPoint96.sol';\n\n// solhint-disable\nlibrary LiquidityAmounts {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/contracts/libraries/FixedPoint96.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nlibrary FixedPoint96 {\n // solhint-disable\n uint8 internal constant RESOLUTION = 96;\n uint256 internal constant Q96 = 0x1000000000000000000000000;\n}\n" + }, + "solidity/contracts/UniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport './libraries/LiquidityAmounts.sol';\nimport './libraries/FixedPoint96.sol';\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\n\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\nimport './peripherals/Governable.sol';\n\ncontract UniV3PairManager is IUniV3PairManager, Governable {\n /// @inheritdoc IERC20Metadata\n string public override name;\n\n /// @inheritdoc IERC20Metadata\n string public override symbol;\n\n /// @inheritdoc IERC20\n uint256 public override totalSupply;\n\n /// @inheritdoc IPairManager\n address public immutable override factory;\n\n /// @inheritdoc IPairManager\n address public immutable override token0;\n\n /// @inheritdoc IPairManager\n address public immutable override token1;\n\n /// @inheritdoc IPairManager\n address public immutable override pool;\n\n /// @inheritdoc IUniV3PairManager\n uint24 public immutable override fee;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioAX96;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioBX96;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickLower;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickUpper;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickSpacing;\n\n /// @notice Uniswap's maximum tick\n /// @dev Due to tick spacing, pools with different fees may have differences between _MAX_TICK and tickUpper. Use tickUpper to find the max tick of the pool.\n int24 private constant _MAX_TICK = 887272;\n\n /// @inheritdoc IERC20Metadata\n //solhint-disable-next-line const-name-snakecase\n uint8 public constant override decimals = 18;\n\n /// @inheritdoc IERC20\n mapping(address => mapping(address => uint256)) public override allowance;\n\n /// @inheritdoc IERC20\n mapping(address => uint256) public override balanceOf;\n\n /// @notice Struct that contains token0, token1, and fee of the Uniswap pool\n PoolKey private _poolKey;\n\n constructor(address _pool, address _governance) Governable(_governance) {\n uint24 _fee = IUniswapV3Pool(_pool).fee();\n address _token0 = IUniswapV3Pool(_pool).token0();\n address _token1 = IUniswapV3Pool(_pool).token1();\n int24 _tickSpacing = IUniswapV3Pool(_pool).tickSpacing();\n int24 _tickUpper = _MAX_TICK - (_MAX_TICK % _tickSpacing);\n int24 _tickLower = -_tickUpper;\n\n factory = msg.sender;\n pool = _pool;\n fee = _fee;\n tickSpacing = _tickSpacing;\n tickUpper = _tickUpper;\n tickLower = _tickLower;\n token0 = _token0;\n token1 = _token1;\n name = string(abi.encodePacked('Keep3rLP - ', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n symbol = string(abi.encodePacked('kLP-', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n\n sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(_tickLower);\n sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(_tickUpper);\n _poolKey = PoolKey({token0: _token0, token1: _token1, fee: _fee});\n }\n\n // This low-level function should be called from a contract which performs important safety checks\n /// @inheritdoc IUniV3PairManager\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint128 liquidity) {\n (liquidity, , ) = _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n _mint(to, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external override {\n MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));\n if (msg.sender != pool) revert OnlyPool();\n if (amount0Owed > 0) _pay(decoded._poolKey.token0, decoded.payer, pool, amount0Owed);\n if (amount1Owed > 0) _pay(decoded._poolKey.token1, decoded.payer, pool, amount1Owed);\n }\n\n /// @inheritdoc IUniV3PairManager\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint256 amount0, uint256 amount1) {\n (amount0, amount1) = IUniswapV3Pool(pool).burn(tickLower, tickUpper, liquidity);\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n\n IUniswapV3Pool(pool).collect(to, tickLower, tickUpper, uint128(amount0), uint128(amount1));\n _burn(msg.sender, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function collect() external override onlyGovernance returns (uint256 amount0, uint256 amount1) {\n (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n (amount0, amount1) = IUniswapV3Pool(pool).collect(governance, tickLower, tickUpper, tokensOwed0, tokensOwed1);\n }\n\n /// @inheritdoc IUniV3PairManager\n function position()\n external\n view\n override\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n )\n {\n (liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128, tokensOwed0, tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n }\n\n /// @inheritdoc IERC20\n function approve(address spender, uint256 amount) external override returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transfer(address to, uint256 amount) external override returns (bool) {\n _transferTokens(msg.sender, to, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool) {\n address spender = msg.sender;\n uint256 spenderAllowance = allowance[from][spender];\n\n if (spender != from && spenderAllowance != type(uint256).max) {\n uint256 newAllowance = spenderAllowance - amount;\n allowance[from][spender] = newAllowance;\n\n emit Approval(from, spender, newAllowance);\n }\n\n _transferTokens(from, to, amount);\n return true;\n }\n\n /// @notice Adds liquidity to an initialized pool\n /// @dev Reverts if the returned amount0 is less than amount0Min or if amount1 is less than amount1Min\n /// @dev This function calls the mint function of the corresponding Uniswap pool, which in turn calls UniswapV3Callback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @return liquidity The calculated liquidity we get for the token amounts we provided\n /// @return amount0 The amount of token0 we ended up providing\n /// @return amount1 The amount of token1 we ended up providing\n function _addLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n internal\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(pool).slot0();\n\n liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, amount0Desired, amount1Desired);\n\n (amount0, amount1) = IUniswapV3Pool(pool).mint(\n address(this),\n tickLower,\n tickUpper,\n liquidity,\n abi.encode(MintCallbackData({_poolKey: _poolKey, payer: msg.sender}))\n );\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n }\n\n /// @notice Transfers the passed-in token from the payer to the recipient for the corresponding value\n /// @param token The token to be transferred to the recipient\n /// @param from The address of the payer\n /// @param to The address of the passed-in tokens recipient\n /// @param value How much of that token to be transferred from payer to the recipient\n function _pay(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n _safeTransferFrom(token, from, to, value);\n }\n\n /// @notice Mints Keep3r credits to the passed-in address of recipient and increases total supply of Keep3r credits by the corresponding amount\n /// @param to The recipient of the Keep3r credits\n /// @param amount The amount Keep3r credits to be minted to the recipient\n function _mint(address to, uint256 amount) internal {\n totalSupply += amount;\n balanceOf[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @notice Burns Keep3r credits to the passed-in address of recipient and reduces total supply of Keep3r credits by the corresponding amount\n /// @param to The address that will get its Keep3r credits burned\n /// @param amount The amount Keep3r credits to be burned from the recipient/recipient\n function _burn(address to, uint256 amount) internal {\n totalSupply -= amount;\n balanceOf[to] -= amount;\n emit Transfer(to, address(0), amount);\n }\n\n /// @notice Transfers amount of Keep3r credits between two addresses\n /// @param from The user that transfers the Keep3r credits\n /// @param to The user that receives the Keep3r credits\n /// @param amount The amount of Keep3r credits to be transferred\n function _transferTokens(\n address from,\n address to,\n uint256 amount\n ) internal {\n balanceOf[from] -= amount;\n balanceOf[to] += amount;\n\n emit Transfer(from, to, amount);\n }\n\n /// @notice Transfers the passed-in token from the specified \"from\" to the specified \"to\" for the corresponding value\n /// @dev Reverts with IUniV3PairManager#UnsuccessfulTransfer if the transfer was not successful,\n /// or if the passed data length is different than 0 and the decoded data is not a boolean\n /// @param token The token to be transferred to the specified \"to\"\n /// @param from The address which is going to transfer the tokens\n /// @param value How much of that token to be transferred from \"from\" to \"to\"\n function _safeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert UnsuccessfulTransfer();\n }\n}\n" + }, + "solidity/interfaces/external/IWeth9.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IWeth9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256) external;\n}\n" + }, + "solidity/interfaces/IUniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IPairManager.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\nimport './peripherals/IGovernable.sol';\n\n/// @title Pair Manager contract\n/// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner\n/// so that the user can use it as liquidity for a Keep3rJob\ninterface IUniV3PairManager is IGovernable, IPairManager {\n // Structs\n struct PoolKey {\n address token0;\n address token1;\n uint24 fee;\n }\n\n /// @notice The data to be decoded by the UniswapV3MintCallback function\n struct MintCallbackData {\n PoolKey _poolKey; // Struct that contains token0, token1, and fee of the pool passed into the constructor\n address payer; // The address of the payer, which will be the msg.sender of the mint function\n }\n\n // Variables\n\n /// @notice The fee of the Uniswap pool passed into the constructor\n /// @return _fee The fee of the Uniswap pool passed into the constructor\n function fee() external view returns (uint24 _fee);\n\n /// @notice Highest tick in the Uniswap's curve\n /// @return _tickUpper The highest tick in the Uniswap's curve\n function tickUpper() external view returns (int24 _tickUpper);\n\n /// @notice Lowest tick in the Uniswap's curve\n /// @return _tickLower The lower tick in the Uniswap's curve\n function tickLower() external view returns (int24 _tickLower);\n\n /// @notice The pair tick spacing\n /// @return _tickSpacing The pair tick spacing\n function tickSpacing() external view returns (int24 _tickSpacing);\n\n /// @notice The sqrtRatioAX96 at the lowest tick (-887200) of the Uniswap pool\n /// @return _sqrtPriceA96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the lowest tick\n function sqrtRatioAX96() external view returns (uint160 _sqrtPriceA96);\n\n /// @notice The sqrtRatioBX96 at the highest tick (887200) of the Uniswap pool\n /// @return _sqrtPriceBX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the highest tick\n function sqrtRatioBX96() external view returns (uint160 _sqrtPriceBX96);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the pool\n error OnlyPool();\n\n /// @notice Throws when the slippage exceeds what the user is comfortable with\n error ExcessiveSlippage();\n\n /// @notice Throws when a transfer is unsuccessful\n error UnsuccessfulTransfer();\n\n // Methods\n\n /// @notice This function is called after a user calls IUniV3PairManager#mint function\n /// It ensures that any tokens owed to the pool are paid by the msg.sender of IUniV3PairManager#mint function\n /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity\n /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity\n /// @param data The encoded token0, token1, fee (_poolKey) and the payer (msg.sender) of the IUniV3PairManager#mint function\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external;\n\n /// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool\n /// @dev Triggers UniV3PairManager#uniswapV3MintCallback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @param to The address to which the kLP tokens are going to be minted to\n /// @return liquidity kLP tokens sent in exchange for the provision of tokens\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint128 liquidity);\n\n /// @notice Returns the pair manager's position in the corresponding UniswapV3 pool\n /// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager\n /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position\n /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position\n /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation\n /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation\n function position()\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees\n // owed to a specific position to the recipient, in this case, that recipient is the pair manager\n /// @dev The collected fees will be sent to governance\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect() external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity\n // in the entire range\n /// @param liquidity The amount of liquidity to be burned\n /// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)\n /// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)\n /// @param to The address that will receive the due fees\n /// @return amount0 The calculated amount of token0 that will be sent to the recipient\n /// @return amount1 The calculated amount of token1 that will be sent to the recipient\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint256 amount0, uint256 amount1);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "solidity/interfaces/IPairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IGovernable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ninterface IPairManagerFactory is IGovernable {\n // Variables\n\n /// @notice Maps the address of a Uniswap pool, to the address of the corresponding PairManager\n /// For example, the uniswap address of DAI-WETH, will return the Keep3r/DAI-WETH pair manager address\n /// @param _pool The address of the Uniswap pool\n /// @return _pairManager The address of the corresponding pair manager\n function pairManagers(address _pool) external view returns (address _pairManager);\n\n // Events\n\n /// @notice Emitted when a new pair manager is created\n /// @param _pool The address of the corresponding Uniswap pool\n /// @param _pairManager The address of the just-created pair manager\n event PairCreated(address _pool, address _pairManager);\n\n // Errors\n\n /// @notice Throws an error if the pair manager is already initialized\n error AlreadyInitialized();\n\n /// @notice Throws an error if the caller is not the owner\n error OnlyOwner();\n\n // Methods\n\n /// @notice Creates a new pair manager based on the address of a Uniswap pool\n /// For example, the uniswap address of DAI-WETH, will create the Keep3r/DAI-WETH pool\n /// @param _pool The address of the Uniswap pool the pair manager will be based of\n /// @return _pairManager The address of the just-created pair manager\n function createPairManager(address _pool) external returns (address _pairManager);\n}\n" + }, + "solidity/contracts/UniV3PairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IPairManagerFactory.sol';\nimport './UniV3PairManager.sol';\nimport './peripherals/Governable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ncontract UniV3PairManagerFactory is IPairManagerFactory, Governable {\n mapping(address => address) public override pairManagers;\n\n constructor(address _governance) Governable(_governance) {}\n\n ///@inheritdoc IPairManagerFactory\n function createPairManager(address _pool) external override returns (address _pairManager) {\n if (pairManagers[_pool] != address(0)) revert AlreadyInitialized();\n _pairManager = address(new UniV3PairManager(_pool, governance));\n pairManagers[_pool] = _pairManager;\n emit PairCreated(_pool, _pairManager);\n }\n}\n" + }, + "solidity/for-test/peripherals/GovernableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" + }, + "solidity/for-test/BridgeForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ncontract BridgeForTest is ERC20 {\n address public immutable kp3r;\n\n constructor(address _kp3r) ERC20('Wrapped KP3R', 'wKP3R') {\n kp3r = _kp3r;\n }\n\n function bridge(uint256 _amount) external {\n IERC20(kp3r).transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n }\n\n function bridgeBack(uint256 _amount) external {\n _burn(msg.sender, _amount);\n IERC20(kp3r).transfer(msg.sender, _amount);\n }\n}\n" + }, + "solidity/for-test/ERC20ForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(uint256 _amount) public {\n _mint(msg.sender, _amount);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(uint256 _amount) public {\n _burn(msg.sender, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n function deposit() external payable {\n // Function added for compatibility with WETH\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperFundableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperFundable.sol';\n\ncontract Keep3rKeeperFundableForTest is Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function isKeeper(address _keeper) external view returns (bool) {\n return _keepers.contains(_keeper);\n }\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/Mintable.sol';\nimport '../peripherals/DustCollector.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rEscrow\n address public override wKP3R;\n\n /// @param _governance Address of governance\n /// @param _wKP3R Address of wrapped KP3R implementation\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\n wKP3R = _wKP3R;\n }\n\n /// @inheritdoc IKeep3rEscrow\n function deposit(uint256 _amount) external override {\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function mint(uint256 _amount) external override onlyMinter {\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function setWKP3R(address _wKP3R) external override onlyGovernance {\n if (_wKP3R == address(0)) revert ZeroAddress();\n wKP3R = _wKP3R;\n emit wKP3RSet(wKP3R);\n }\n}\n" + }, + "solidity/contracts/peripherals/Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IMintable.sol';\nimport './Governable.sol';\n\nabstract contract Mintable is Governable, IMintable {\n /// @inheritdoc IMintable\n address public override minter;\n\n constructor(address _governance) Governable(_governance) {}\n\n /// @inheritdoc IMintable\n function setMinter(address _minter) external override onlyGovernance {\n if (_minter == address(0)) revert ZeroAddress();\n minter = _minter;\n emit MinterSet(_minter);\n }\n\n /// @notice Functions with this modifier can only be called by the minter;\n modifier onlyMinter() {\n if (msg.sender != minter) revert OnlyMinter();\n _;\n }\n}\n" + }, + "solidity/for-test/peripherals/DustCollectorForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/DustCollector.sol';\n\ncontract DustCollectorForTest is DustCollector {\n constructor() DustCollector() Governable(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rAccountanceForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rAccountance.sol';\n\ncontract Keep3rAccountanceForTest is Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor() Keep3rRoles(msg.sender) {}\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n\n function setKeeper(address keeper) external {\n _keepers.add(keeper);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableLiquidityForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol';\n\ncontract Keep3rJobFundableLiquidityForTest is Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external returns (bool) {\n return _jobLiquidities[_job].add(_liquidity);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewTickOrder(address _liquidity) external view returns (bool) {\n return _isKP3RToken0[_liquidity];\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function internalSettleJobAccountance(address _job) external {\n _settleJobAccountance(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobDisputable.sol';\n\ncontract Keep3rJobDisputableForTest is Keep3rJobDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function internalJobLiquidityCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobLiquidityCredits[_job];\n }\n\n function internalJobPeriodCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobPeriodCredits[_job];\n }\n\n function internalJobTokens(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobTokens[_job].length());\n for (uint256 i; i < _jobTokens[_job].length(); i++) {\n _tokens[i] = _jobTokens[_job].at(i);\n }\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobLiquidities[_job].length());\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n _tokens[i] = _jobLiquidities[_job].at(i);\n }\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rDisputable.sol';\n\ncontract Keep3rDisputableForTest is Keep3rDisputable {\n constructor() Keep3rParameters(address(0), address(0), address(0)) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperDisputable.sol';\n\ncontract Keep3rKeeperDisputableForTest is Keep3rKeeperDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function internalSlash(\n address _bonded,\n address _keeper,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external {\n _slash(_bonded, _keeper, _bondAmount, _unbondAmount);\n }\n\n function isKeeper(address _address) external view returns (bool _isKeeper) {\n _isKeeper = _keepers.contains(_address);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableCreditsForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableCredits.sol';\n\ncontract Keep3rJobFundableCreditsForTest is Keep3rJobFundableCredits {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job, address _jobOwner) external {\n _jobs.add(_job);\n jobOwner[_job] = _jobOwner;\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function isJobToken(address _job, address _token) external view returns (bool _contains) {\n _contains = _jobTokens[_job].contains(_token);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/IKeep3rHelper.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n /// @inheritdoc IKeep3rHelper\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelper\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\n // solhint-disable-next-line avoid-tx-origin\n return getRewardAmountFor(tx.origin, _gasUsed);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\n _bonds = Math.min(_bonds, targetBond);\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\n _rewardBoost = _cap * _getBasefee();\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\n }\n\n /// @inheritdoc IKeep3rHelper\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\n address _token0;\n address _token1;\n (_token0, _token1) = getPoolTokens(_pool);\n if (_token0 == KP3R) {\n return true;\n } else if (_token1 != KP3R) {\n revert LiquidityPairInvalid();\n }\n }\n\n /// @inheritdoc IKeep3rHelper\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n override\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n )\n {\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\n _tickCumulative1 = _uniswapResponse[0];\n if (_uniswapResponse.length > 1) {\n _tickCumulative2 = _uniswapResponse[1];\n }\n _success = true;\n } catch (bytes memory) {}\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n )\n {\n _oneEthQuote = quote(1 ether);\n _boost = getRewardBoostFor(_bonds);\n _extra = workExtraGas;\n }\n\n /// @inheritdoc IKeep3rHelper\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure override returns (uint256 _kp3rAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) public pure override returns (uint256 _quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\n }\n }\n\n /// @notice Gets the gas basefee cost to calculate keeper rewards\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTestnet is Keep3rHelper {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal pure override returns (uint256) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/Keep3rHelperForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTest is Keep3rHelper {\n uint256 public basefee;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal view override returns (uint256) {\n return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee();\n }\n\n function setBaseFee(uint256 _baseFee) external {\n basefee = _baseFee;\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rHelper.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\n /// @inheritdoc IKeep3rHelperSidechain\n mapping(address => address) public override oracle;\n /// @inheritdoc IKeep3rHelperSidechain\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n address public immutable override WETH;\n\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\n /// @param _governance Address of governance\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\n /// @dev Oracle pools should use 18 decimals tokens\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\n WETH = _weth;\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\n _setQuoteTwapTime(1 days);\n workExtraGas = 0;\n }\n\n /// @inheritdoc IKeep3rHelper\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\n oracle[_liquidity] = _oracle;\n emit OracleSet(_liquidity, _oracle);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n /// @dev Oracle is compatible with IUniswapV3Pool\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setWethUsdPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override(Keep3rHelper, IKeep3rHelper)\n returns (\n uint256 _boost,\n uint256 _oneUsdQuote,\n uint256 _extraGas\n )\n {\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\n _boost = getRewardBoostFor(_bonds);\n _extraGas = workExtraGas;\n }\n\n function _setWethUsdPool(address _poolAddress) internal {\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\n }\n\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechainForTestnet is Keep3rHelperSidechain {\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelperSidechain(_keep3rV2, _governance, _kp3r, _weth, _kp3rWethOracle, _wethUsdOracle) {}\n\n /// @dev Overrides oracle validation that uses KP3R and WETH addresses\n function _validateOraclePool(address _poolAddress, address) internal view virtual override returns (TokenOraclePool memory _oraclePool) {\n return TokenOraclePool(_poolAddress, true);\n }\n\n /// @dev Overrides token comparison with KP3R address\n function isKP3RToken0(address) public view virtual override returns (bool) {\n return true;\n }\n\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256) {\n return _usd / 1000;\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rParametersForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rParameters.sol';\n\ncontract Keep3rParametersForTest is Keep3rParameters {\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobWorkableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobWorkable.sol';\n\ncontract Keep3rJobWorkableForTest is Keep3rJobWorkable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewGas() external view returns (uint256) {\n return _initialGas;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobMigrationForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobMigration.sol';\n\ncontract Keep3rJobMigrationForTest is Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(address => uint256) public settleJobAccountanceCallCount;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobTokenListLength(address _job) external view returns (uint256) {\n return _jobTokens[_job].length();\n }\n\n function viewJobLiquidityList(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewMigrationCreatedAt(address _fromJob, address _toJob) external view returns (uint256) {\n return _migrationCreatedAt[_fromJob][_toJob];\n }\n\n function isJob(address _job) external view returns (bool) {\n return _jobs.contains(_job);\n }\n\n function _settleJobAccountance(address _job) internal override {\n settleJobAccountanceCallCount[_job]++;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobManager.sol';\n\ncontract Keep3rJobManagerForTest is Keep3rJobManager {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rRoles(msg.sender) {}\n\n function isJob(address _job) external view returns (bool _isJob) {\n _isJob = _jobs.contains(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobOwnershipForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobOwnership.sol';\n\ncontract Keep3rJobOwnershipForTest is Keep3rJobOwnership {}\n" + }, + "solidity/for-test/libraries/LiquidityAmountsForTest.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/libraries/FullMath.sol';\nimport '../../contracts/libraries/FixedPoint96.sol';\n\n/// @dev Made this library into a contract to be able to calculate liquidity more precisely for tests\n\n// solhint-disable\ncontract LiquidityAmountsForTest {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) external pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) external pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/for-test/IUniswapV3PoolForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n// solhint-disable-next-line no-empty-blocks\ninterface IUniswapV3PoolForTest is IERC20Minimal, IUniswapV3Pool {\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Minimal ERC20 interface for Uniswap\n/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3\ninterface IERC20Minimal {\n /// @notice Returns the balance of a token\n /// @param account The account for which to look up the number of tokens it has, i.e. its balance\n /// @return The number of tokens held by the account\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Transfers the amount of token from the `msg.sender` to the recipient\n /// @param recipient The account that will receive the amount transferred\n /// @param amount The number of tokens to send from the sender to the recipient\n /// @return Returns true for a successful transfer, false for an unsuccessful transfer\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /// @notice Returns the current allowance given to a spender by an owner\n /// @param owner The account of the token owner\n /// @param spender The account of the token spender\n /// @return The current allowance granted by `owner` to `spender`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`\n /// @param spender The account which will be allowed to spend a given amount of the owners tokens\n /// @param amount The amount of tokens allowed to be used by `spender`\n /// @return Returns true for a successful approval, false for unsuccessful\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`\n /// @param sender The account from which the transfer will be initiated\n /// @param recipient The recipient of the transfer\n /// @param amount The amount of the transfer\n /// @return Returns true for a successful transfer, false for unsuccessful\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.\n /// @param from The account from which the tokens were sent, i.e. the balance decreased\n /// @param to The account to which the tokens were sent, i.e. the balance increased\n /// @param value The amount of tokens that were transferred\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.\n /// @param owner The account that approved spending of its tokens\n /// @param spender The account for which the spending allowance was modified\n /// @param value The new allowance from the owner to the spender\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 33 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimisticGoerli/solcInputs/7d006d28afea8f44b7106e2df679db88.json b/deployments/optimisticGoerli/solcInputs/7d006d28afea8f44b7106e2df679db88.json new file mode 100644 index 0000000..771a29a --- /dev/null +++ b/deployments/optimisticGoerli/solcInputs/7d006d28afea8f44b7106e2df679db88.json @@ -0,0 +1,334 @@ +{ + "language": "Solidity", + "sources": { + "solidity/contracts/Keep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport './peripherals/jobs/Keep3rJobs.sol';\nimport './peripherals/keepers/Keep3rKeepers.sol';\nimport './peripherals/DustCollector.sol';\n\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\n}\n" + }, + "solidity/interfaces/IKeep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobManager.sol';\nimport './Keep3rJobWorkable.sol';\nimport './Keep3rJobDisputable.sol';\n\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\nimport './Keep3rKeeperDisputable.sol';\n\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\n" + }, + "solidity/contracts/peripherals/DustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '../../contracts/peripherals/Governable.sol';\nimport '../../interfaces/peripherals/IDustCollector.sol';\n\nabstract contract DustCollector is IDustCollector, Governable {\n using SafeERC20 for IERC20;\n\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external override onlyGovernance {\n if (_to == address(0)) revert ZeroAddress();\n if (_token == _ETH_ADDRESS) {\n payable(_to).transfer(_amount);\n } else {\n IERC20(_token).safeTransfer(_to, _amount);\n }\n emit DustSent(_token, _amount, _to);\n }\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" + }, + "solidity/interfaces/peripherals/IBaseErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" + }, + "solidity/interfaces/peripherals/IGovernable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" + }, + "solidity/interfaces/peripherals/IDustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @inheritdoc IKeep3rJobManager\n function addJob(address _job) external override {\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\n if (hasBonded[_job]) revert AlreadyAKeeper();\n _jobs.add(_job);\n jobOwner[_job] = msg.sender;\n emit JobAddition(_job, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobMigration.sol';\nimport '../../../interfaces/IKeep3rHelper.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 internal _initialGas;\n\n /// @inheritdoc IKeep3rJobWorkable\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\n _initialGas = _getGasLeft();\n if (_keepers.contains(_keeper)) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external override returns (bool _isBondedKeeper) {\n _initialGas = _getGasLeft();\n if (\n _keepers.contains(_keeper) &&\n bonds[_keeper][_bond] >= _minBond &&\n workCompleted[_keeper] >= _earned &&\n block.timestamp - firstSeen[_keeper] >= _age\n ) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function worked(address _keeper) external virtual override {\n if (_initialGas == 0) revert GasNotInitialized();\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _gasLeft = _getGasLeft();\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n _gasLeft = _getGasLeft();\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function bondedPayment(address _keeper, uint256 _payment) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (disputes[_keeper]) revert Disputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_keeper, _amount);\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\n }\n\n function _bondedPayment(\n address _job,\n address _keeper,\n uint256 _payment\n ) internal {\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\n\n workedAt[_job] = block.timestamp;\n _jobLiquidityCredits[_job] -= _payment;\n bonds[_keeper][keep3rV1] += _payment;\n workCompleted[_keeper] += _payment;\n totalBonds += _payment;\n }\n\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\n /// @param _gasLeft Amount of gas left after working the job\n /// @param _extraGas Amount of expected unaccounted gas\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\n /// @return _payment Amount to be payed in KP3R tokens\n function _calculatePayment(\n uint256 _gasLeft,\n uint256 _extraGas,\n uint256 _oneEthQuote,\n uint256 _boost\n ) internal view returns (uint256 _payment) {\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\n }\n\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\n _gasLeft = (gasleft() * 64) / 63;\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\nimport '../Keep3rDisputable.sol';\n\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\n\n try IERC20(_token).transfer(governance, _amount) {} catch {}\n jobTokenCredits[_job][_token] -= _amount;\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit JobSlashToken(_job, _token, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobPendingOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\n jobPendingOwner[_job] = _newOwner;\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\n }\n\n /// @inheritdoc IKeep3rJobOwnership\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\n address _previousOwner = jobOwner[_job];\n\n jobOwner[_job] = jobPendingOwner[_job];\n delete jobPendingOwner[_job];\n\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\n }\n\n modifier onlyJobOwner(address _job) {\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\n _;\n }\n\n modifier onlyPendingJobOwner(address _job) {\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\nimport './Keep3rRoles.sol';\n\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @notice List of all enabled keepers\n EnumerableSet.AddressSet internal _keepers;\n\n /// @inheritdoc IKeep3rAccountance\n uint256 public override totalBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override workCompleted;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override firstSeen;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override disputes;\n\n /// @inheritdoc IKeep3rAccountance\n /// @notice Mapping (job => bonding => amount)\n mapping(address => mapping(address => uint256)) public override bonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\n\n /// @notice The current liquidity credits available for a job\n mapping(address => uint256) internal _jobLiquidityCredits;\n\n /// @notice Map the address of a job to its correspondent periodCredits\n mapping(address => uint256) internal _jobPeriodCredits;\n\n /// @notice Enumerable array of Job Tokens for Credits\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\n\n /// @notice List of liquidities that a job has (job => liquidities)\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\n\n /// @notice Liquidity pool to observe\n mapping(address => address) internal _liquidityPool;\n\n /// @notice Tracks if a pool has KP3R as token0\n mapping(address => bool) internal _isKP3RToken0;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override hasBonded;\n\n /// @notice List of all enabled jobs\n EnumerableSet.AddressSet internal _jobs;\n\n /// @inheritdoc IKeep3rAccountance\n function jobs() external view override returns (address[] memory _list) {\n _list = _jobs.values();\n }\n\n /// @inheritdoc IKeep3rAccountance\n function keepers() external view override returns (address[] memory _list) {\n _list = _keepers.values();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport './DustCollector.sol';\nimport './Governable.sol';\n\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override slashers;\n\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override disputers;\n\n constructor(address _governance) Governable(_governance) DustCollector() {}\n\n /// @inheritdoc IKeep3rRoles\n function addSlasher(address _slasher) external override onlyGovernance {\n if (_slasher == address(0)) revert ZeroAddress();\n if (slashers[_slasher]) revert SlasherExistent();\n slashers[_slasher] = true;\n emit SlasherAdded(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeSlasher(address _slasher) external override onlyGovernance {\n if (!slashers[_slasher]) revert SlasherUnexistent();\n delete slashers[_slasher];\n emit SlasherRemoved(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function addDisputer(address _disputer) external override onlyGovernance {\n if (_disputer == address(0)) revert ZeroAddress();\n if (disputers[_disputer]) revert DisputerExistent();\n disputers[_disputer] = true;\n emit DisputerAdded(_disputer);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeDisputer(address _disputer) external override onlyGovernance {\n if (!disputers[_disputer]) revert DisputerUnexistent();\n delete disputers[_disputer];\n emit DisputerRemoved(_disputer);\n }\n\n /// @notice Functions with this modifier can only be called by either a slasher or governance\n modifier onlySlasher {\n if (!slashers[msg.sender]) revert OnlySlasher();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by either a disputer or governance\n modifier onlyDisputer {\n if (!disputers[msg.sender]) revert OnlyDisputer();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Governable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public override governance;\n\n /// @inheritdoc IGovernable\n address public override pendingGovernance;\n\n constructor(address _governance) {\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\n governance = _governance;\n }\n\n /// @inheritdoc IGovernable\n function setGovernance(address _governance) external override onlyGovernance {\n pendingGovernance = _governance;\n emit GovernanceProposal(_governance);\n }\n\n /// @inheritdoc IGovernable\n function acceptGovernance() external override onlyPendingGovernance {\n governance = pendingGovernance;\n delete pendingGovernance;\n emit GovernanceSet(governance);\n }\n\n /// @notice Functions with this modifier can only be called by governance\n modifier onlyGovernance {\n if (msg.sender != governance) revert OnlyGovernance();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernance\n modifier onlyPendingGovernance {\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\n _;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\n\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobMigration\n mapping(address => address) public override pendingJobMigrations;\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\n\n /// @inheritdoc IKeep3rJobMigration\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\n if (_fromJob == _toJob) revert JobMigrationImpossible();\n\n pendingJobMigrations[_fromJob] = _toJob;\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\n\n emit JobMigrationRequested(_fromJob, _toJob);\n }\n\n /// @inheritdoc IKeep3rJobMigration\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\n\n // force job credits update for both jobs\n _settleJobAccountance(_fromJob);\n _settleJobAccountance(_toJob);\n\n // migrate tokens\n while (_jobTokens[_fromJob].length() > 0) {\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\n _jobTokens[_fromJob].remove(_tokenToMigrate);\n _jobTokens[_toJob].add(_tokenToMigrate);\n }\n\n // migrate liquidities\n while (_jobLiquidities[_fromJob].length() > 0) {\n address _liquidity = _jobLiquidities[_fromJob].at(0);\n\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\n delete liquidityAmount[_fromJob][_liquidity];\n\n _jobLiquidities[_toJob].add(_liquidity);\n _jobLiquidities[_fromJob].remove(_liquidity);\n }\n\n // migrate job balances\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\n delete _jobPeriodCredits[_fromJob];\n\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\n delete _jobLiquidityCredits[_fromJob];\n\n // stop _fromJob from being a job\n delete rewardedAt[_fromJob];\n _jobs.remove(_fromJob);\n\n // delete unused data slots\n delete jobOwner[_fromJob];\n delete jobPendingOwner[_fromJob];\n delete _migrationCreatedAt[_fromJob][_toJob];\n delete pendingJobMigrations[_fromJob];\n\n emit JobMigrationSuccessful(_fromJob, _toJob);\n }\n}\n" + }, + "solidity/interfaces/IKeep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rHelperParameters.sol';\n\n/// @title Keep3rHelper contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelper is IKeep3rHelperParameters {\n // Errors\n\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\n error LiquidityPairInvalid();\n\n // Methods\n // solhint-enable func-name-mixedcase\n\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\n /// @param _eth The amount of ETH\n /// @return _amountOut The amount of KP3R\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\n\n /// @notice Returns the amount of KP3R the keeper has bonded\n /// @param _keeper The address of the keeper to check\n /// @return _amountBonded The amount of KP3R the keeper has bonded\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\n /// @param _keeper The address of the keeper to check\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\n\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\n /// @return _rewardBoost The reward boost that corresponds to the keeper\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\n\n /// @notice Given a pool address, returns the underlying tokens of the pair\n /// @param _pool Address of the correspondant pool\n /// @return _token0 Address of the first token of the pair\n /// @return _token1 Address of the second token of the pair\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\n\n /// @notice Defines the order of the tokens in the pair for twap calculations\n /// @param _pool Address of the correspondant pool\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\n\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\n /// @param _pool Address of the pool to observe\n /// @param _secondsAgo Array with time references to observe\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\n /// @return _success Boolean indicating if the observe call was succesfull\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n );\n\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\n /// @param _bonds Amount of bonded KP3R owned by the keeper\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\n /// @return _extra Amount of extra gas that should be added to the gas spent\n function getPaymentParams(uint256 _bonds)\n external\n view\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n );\n\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\n /// @param _liquidityAmount Amount of liquidity to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _kp3rAmount);\n\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\n /// @param _baseAmount Amount of token to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _quoteAmount);\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice Cooldown between withdrawals\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override nonReentrant {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n // KP3R shouldn't be used for direct token payments\n if (_token == keep3rV1) revert TokenUnallowed();\n uint256 _before = IERC20(_token).balanceOf(address(this));\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\n uint256 _tokenFee = (_received * fee) / _BASE;\n jobTokenCredits[_job][_token] += _received - _tokenFee;\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\n IERC20(_token).safeTransfer(governance, _tokenFee);\n _jobTokens[_job].add(_token);\n\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\n }\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external override nonReentrant onlyJobOwner(_job) {\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\n if (disputes[_job]) revert JobDisputed();\n\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_receiver, _amount);\n\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/IPairManager.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '../../libraries/FullMath.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice List of liquidities that are accepted in the system\n EnumerableSet.AddressSet internal _approvedLiquidities;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override rewardedAt;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override workedAt;\n\n /// @notice Tracks an address and returns its TickCache\n mapping(address => TickCache) internal _tick;\n\n // Views\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approvedLiquidities() external view override returns (address[] memory _list) {\n _list = _approvedLiquidities.values();\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n _periodCredits += _getReward(\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\n );\n }\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n\n // If the job was rewarded in the past 1 period time\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\n // If the job has period credits, update minted job credits to new twap\n _liquidityCredits = _periodCredits > 0\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\n } else {\n // Else return a full period worth of credits if current credits have expired\n _liquidityCredits = _periodCredits;\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n uint256 _cooldown = block.timestamp;\n\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\n // Will calculate cooldown if it outdated\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will calculate cooldown from last reward reference in this period\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\n } else {\n // Will calculate cooldown from last reward timestamp\n _cooldown -= rewardedAt[_job];\n }\n } else {\n // Will calculate cooldown from period start if expired\n _cooldown -= _period(block.timestamp);\n }\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\n\n if (_tick[_liquidity].period == lastPeriod) {\n // Will only ask for current period accumulator if liquidity is outdated\n uint32[] memory _secondsAgo = new uint32[](1);\n int56 previousTick = _tick[_liquidity].current;\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - previousTick;\n } else if (_tick[_liquidity].period < lastPeriod) {\n // Will ask for 2 accumulators if liquidity is expired\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n }\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Methods\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n _settleJobAccountance(_job);\n _jobLiquidityCredits[_job] += _amount;\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\n delete _liquidityPool[_liquidity];\n delete _isKP3RToken0[_liquidity];\n delete _tick[_liquidity];\n\n emit LiquidityRevocation(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override nonReentrant {\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\n if (!_jobs.contains(_job)) revert JobUnavailable();\n\n _jobLiquidities[_job].add(_liquidity);\n\n _settleJobAccountance(_job);\n\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\n liquidityAmount[_job][_liquidity] += _amount;\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlyJobOwner(_job) {\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\n pendingUnbonds[_job][_liquidity] += _amount;\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit Unbonding(_job, _liquidity, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external override onlyJobOwner(_job) {\n if (_receiver == address(0)) revert ZeroAddress();\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\n if (disputes[_job]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[_job][_liquidity];\n\n delete pendingUnbonds[_job][_liquidity];\n delete canWithdrawAfter[_job][_liquidity];\n\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\n }\n\n // Internal functions\n\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\n if (rewardedAt[_job] < _period(block.timestamp)) {\n // Will exit function if job has been rewarded in current period\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\n // Will reset job to period syncronicity if a full period passed without rewards\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] = _period(block.timestamp);\n _rewarded = true;\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will reset job's syncronicity if last reward was more than epoch ago\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] += rewardPeriodTime;\n _rewarded = true;\n } else if (workedAt[_job] < _period(block.timestamp)) {\n // First keeper on period has to update job accountance to current twaps\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\n // Updating job accountance does not reward job\n }\n }\n }\n\n /// @notice Only called if _jobLiquidityCredits < payment\n function _rewardJobCredits(address _job) internal {\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\n rewardedAt[_job] = block.timestamp;\n }\n\n /// @notice Updates accountance for _jobPeriodCredits\n function _updateJobPeriod(address _job) internal {\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\n }\n\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n if (_tick[_liquidity].period != _period(block.timestamp)) {\n // Updates liquidity cache only if needed\n _tick[_liquidity] = observeLiquidity(_liquidity);\n }\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\n }\n }\n }\n\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\n function _unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) internal nonReentrant {\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\n\n // Ensures current twaps in job liquidities\n _updateJobPeriod(_job);\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\n\n // A liquidity can be revoked causing a job to have 0 periodCredits\n if (_jobPeriodCredits[_job] > 0) {\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\n }\n\n liquidityAmount[_job][_liquidity] -= _amount;\n if (liquidityAmount[_job][_liquidity] == 0) {\n _jobLiquidities[_job].remove(_liquidity);\n }\n }\n\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\n if (_timePassed < rewardPeriodTime) {\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\n } else _result = _multiplier;\n }\n\n /// @notice Returns the start of the period of the provided timestamp\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\n return _timestamp - (_timestamp % rewardPeriodTime);\n }\n\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\n }\n\n /// @notice Returns underlying KP3R amount for a given liquidity amount\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\n if (_tick[_liquidity].period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\n }\n }\n\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\n /// @dev Ensures a maximum of 1 period of credits\n function _settleJobAccountance(address _job) internal virtual {\n _updateJobCreditsIfNeeded(_job);\n _rewardJobCredits(_job);\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/IKeep3rHelper.sol';\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\nimport './Keep3rAccountance.sol';\n\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1Proxy;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rHelper;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override bondTime = 3 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override unbondTime = 14 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override liquidityMinimum = 3 ether;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override rewardPeriodTime = 5 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override inflationPeriod = 34 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override fee = 30;\n\n /// @notice The base that will be used to calculate the fee\n uint256 internal constant _BASE = 10_000;\n\n /// @notice The minimum reward period\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) {\n keep3rHelper = _keep3rHelper;\n keep3rV1 = _keep3rV1;\n keep3rV1Proxy = _keep3rV1Proxy;\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\n if (_keep3rHelper == address(0)) revert ZeroAddress();\n keep3rHelper = _keep3rHelper;\n emit Keep3rHelperChange(_keep3rHelper);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\n if (_keep3rV1 == address(0)) revert ZeroAddress();\n _mint(totalBonds);\n\n keep3rV1 = _keep3rV1;\n emit Keep3rV1Change(_keep3rV1);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\n keep3rV1Proxy = _keep3rV1Proxy;\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\n bondTime = _bondTime;\n emit BondTimeChange(_bondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\n unbondTime = _unbondTime;\n emit UnbondTimeChange(_unbondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\n liquidityMinimum = _liquidityMinimum;\n emit LiquidityMinimumChange(_liquidityMinimum);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\n rewardPeriodTime = _rewardPeriodTime;\n emit RewardPeriodTimeChange(_rewardPeriodTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\n inflationPeriod = _inflationPeriod;\n emit InflationPeriodChange(_inflationPeriod);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setFee(uint256 _fee) external override onlyGovernance {\n fee = _fee;\n emit FeeChange(_fee);\n }\n\n function _mint(uint256 _amount) internal {\n totalBonds -= _amount;\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IGovernable.sol';\n\ninterface IKeep3rV1Proxy is IGovernable {\n // Structs\n struct Recipient {\n address recipient;\n uint256 caps;\n }\n\n // Variables\n function keep3rV1() external view returns (address);\n\n function minter() external view returns (address);\n\n function next(address) external view returns (uint256);\n\n function caps(address) external view returns (uint256);\n\n function recipients() external view returns (address[] memory);\n\n function recipientsCaps() external view returns (Recipient[] memory);\n\n // Errors\n error Cooldown();\n error NoDrawableAmount();\n error ZeroAddress();\n error OnlyMinter();\n\n // Methods\n function addRecipient(address recipient, uint256 amount) external;\n\n function removeRecipient(address recipient) external;\n\n function draw() external returns (uint256 _amount);\n\n function setKeep3rV1(address _keep3rV1) external;\n\n function setMinter(address _minter) external;\n\n function mint(uint256 _amount) external;\n\n function mint(address _account, uint256 _amount) external;\n\n function setKeep3rV1Governance(address _governance) external;\n\n function acceptKeep3rV1Governance() external;\n\n function dispute(address _keeper) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function addJob(address _job) external;\n\n function removeJob(address _job) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n}\n" + }, + "solidity/interfaces/IKeep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rHelperParameters contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelperParameters {\n // Structs\n\n /// @dev KP3R-WETH Pool address and isKP3RToken0\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\n struct TokenOraclePool {\n address poolAddress;\n bool isTKNToken0;\n }\n\n // Errors\n\n /// @notice Throws when pool does not have KP3R as token0 nor token1\n error InvalidOraclePool();\n\n // Events\n\n /// @notice Emitted when the kp3r weth pool is changed\n /// @param _address Address of the new kp3r weth pool\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\n\n /// @notice Emitted when the minimum boost multiplier is changed\n /// @param _minBoost The minimum boost multiplier\n event MinBoostChange(uint256 _minBoost);\n\n /// @notice Emitted when the maximum boost multiplier is changed\n /// @param _maxBoost The maximum boost multiplier\n event MaxBoostChange(uint256 _maxBoost);\n\n /// @notice Emitted when the target bond amount is changed\n /// @param _targetBond The target bond amount\n event TargetBondChange(uint256 _targetBond);\n\n /// @notice Emitted when the Keep3r V2 address is changed\n /// @param _keep3rV2 The address of Keep3r V2\n event Keep3rV2Change(address _keep3rV2);\n\n /// @notice Emitted when the work extra gas amount is changed\n /// @param _workExtraGas The work extra gas\n event WorkExtraGasChange(uint256 _workExtraGas);\n\n /// @notice Emitted when the quote twap time is changed\n /// @param _quoteTwapTime The twap time for quoting\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\n\n /// @notice Emitted when minimum rewarded gas fee is changed\n /// @param _minBaseFee The minimum rewarded gas fee\n event MinBaseFeeChange(uint256 _minBaseFee);\n\n /// @notice Emitted when minimum rewarded priority fee is changed\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\n event MinPriorityFeeChange(uint256 _minPriorityFee);\n\n // Variables\n\n /// @notice Address of KP3R token\n /// @return _kp3r Address of KP3R token\n // solhint-disable func-name-mixedcase\n function KP3R() external view returns (address _kp3r);\n\n /// @notice The boost base used to calculate the boost rewards for the keeper\n /// @return _base The boost base number\n function BOOST_BASE() external view returns (uint256 _base);\n\n /// @notice KP3R-WETH pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\n /// @return _multiplier The minimum boost multiplier\n function minBoost() external view returns (uint256 _multiplier);\n\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\n /// @return _multiplier The maximum boost multiplier\n function maxBoost() external view returns (uint256 _multiplier);\n\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\n /// @return _target The amount of KP3R that comforms the targetBond\n function targetBond() external view returns (uint256 _target);\n\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\n /// @return _workExtraGas The work unaccounted gas amount\n function workExtraGas() external view returns (uint256 _workExtraGas);\n\n /// @notice The twap time for quoting\n /// @return _quoteTwapTime The twap time\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\n\n /// @notice The minimum base fee that is used to calculate keeper rewards\n /// @return _minBaseFee The minimum rewarded gas fee\n function minBaseFee() external view returns (uint256 _minBaseFee);\n\n /// @notice The minimum priority fee that is also rewarded for keepers\n /// @return _minPriorityFee The minimum rewarded priority fee\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\n\n /// @notice Address of Keep3r V2\n /// @return _keep3rV2 Address of Keep3r V2\n function keep3rV2() external view returns (address _keep3rV2);\n\n // Methods\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function setKp3rWethPool(address _poolAddress) external;\n\n /// @notice Sets the minimum boost multiplier\n /// @param _minBoost The minimum boost multiplier\n function setMinBoost(uint256 _minBoost) external;\n\n /// @notice Sets the maximum boost multiplier\n /// @param _maxBoost The maximum boost multiplier\n function setMaxBoost(uint256 _maxBoost) external;\n\n /// @notice Sets the target bond amount\n /// @param _targetBond The target bond amount\n function setTargetBond(uint256 _targetBond) external;\n\n /// @notice Sets the Keep3r V2 address\n /// @param _keep3rV2 The address of Keep3r V2\n function setKeep3rV2(address _keep3rV2) external;\n\n /// @notice Sets the work extra gas amount\n /// @param _workExtraGas The work extra gas\n function setWorkExtraGas(uint256 _workExtraGas) external;\n\n /// @notice Sets the quote twap time\n /// @param _quoteTwapTime The twap time for quoting\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\n\n /// @notice Sets the minimum rewarded gas fee\n /// @param _minBaseFee The minimum rewarded gas fee\n function setMinBaseFee(uint256 _minBaseFee) external;\n\n /// @notice Sets the minimum rewarded gas priority fee\n /// @param _minPriorityFee The minimum rewarded priority fee\n function setMinPriorityFee(uint256 _minPriorityFee) external;\n}\n" + }, + "solidity/interfaces/IPairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n/// @title Pair Manager interface\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\ninterface IPairManager is IERC20Metadata {\n /// @notice Address of the factory from which the pair manager was created\n /// @return _factory The address of the PairManager Factory\n function factory() external view returns (address _factory);\n\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\n /// @return _pool The address of the pool\n function pool() external view returns (address _pool);\n\n /// @notice Token0 of the pool\n /// @return _token0 The address of token0\n function token0() external view returns (address _token0);\n\n /// @notice Token1 of the pool\n /// @return _token1 The address of token1\n function token1() external view returns (address _token1);\n}\n" + }, + "solidity/contracts/libraries/FullMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (~denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "solidity/contracts/peripherals/Keep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rParameters.sol';\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\n\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\n /// @inheritdoc IKeep3rDisputable\n function dispute(address _jobOrKeeper) external override onlyDisputer {\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\n disputes[_jobOrKeeper] = true;\n emit Dispute(_jobOrKeeper, msg.sender);\n }\n\n /// @inheritdoc IKeep3rDisputable\n function resolve(address _jobOrKeeper) external override onlyDisputer {\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\n disputes[_jobOrKeeper] = false;\n emit Resolve(_jobOrKeeper, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rKeeperFundable.sol';\nimport '../Keep3rDisputable.sol';\nimport '../../../interfaces/external/IKeep3rV1.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\n }\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function revoke(address _keeper) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _keepers.remove(_keeper);\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\n emit KeeperRevoke(_keeper, msg.sender);\n }\n\n function _slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) internal {\n if (_bonded != keep3rV1) {\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\n }\n bonds[_keeper][_bonded] -= _bondAmount;\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nimport '../../../interfaces/external/IKeep3rV1.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperFundable\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\n if (disputes[msg.sender]) revert Disputed();\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\n\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\n\n hasBonded[msg.sender] = true;\n pendingBonds[msg.sender][_bonding] += _amount;\n\n emit Bonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function activate(address _bonding) external override {\n address _keeper = msg.sender;\n if (disputes[_keeper]) revert Disputed();\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\n if (_canActivateAfter == 0) revert BondsUnexistent();\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\n\n if (firstSeen[_keeper] == 0) {\n firstSeen[_keeper] = block.timestamp;\n }\n _keepers.add(_keeper);\n\n uint256 _amount = pendingBonds[_keeper][_bonding];\n delete pendingBonds[_keeper][_bonding];\n\n // bond provided tokens\n bonds[_keeper][_bonding] += _amount;\n if (_bonding == keep3rV1) {\n totalBonds += _amount;\n _depositBonds(_amount);\n }\n\n emit Activation(_keeper, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function unbond(address _bonding, uint256 _amount) external override {\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\n bonds[msg.sender][_bonding] -= _amount;\n pendingUnbonds[msg.sender][_bonding] += _amount;\n\n emit Unbonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function withdraw(address _bonding) external override nonReentrant {\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\n if (disputes[msg.sender]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\n\n delete pendingUnbonds[msg.sender][_bonding];\n delete canWithdrawAfter[msg.sender][_bonding];\n\n if (_bonding == keep3rV1) _mint(_amount);\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(msg.sender, _bonding, _amount);\n }\n\n function _depositBonds(uint256 _amount) internal virtual {\n IKeep3rV1(keep3rV1).burn(_amount);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n// solhint-disable func-name-mixedcase\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\n // Structs\n struct Checkpoint {\n uint32 fromBlock;\n uint256 votes;\n }\n\n // Events\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event JobAdded(address indexed _job, uint256 _block, address _governance);\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\n event KeeperDispute(address indexed _keeper, uint256 _block);\n event KeeperResolved(address indexed _keeper, uint256 _block);\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\n\n // Variables\n function KPRH() external returns (address);\n\n function delegates(address _delegator) external view returns (address);\n\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\n\n function numCheckpoints(address _account) external view returns (uint32);\n\n function DOMAIN_TYPEHASH() external returns (bytes32);\n\n function DOMAINSEPARATOR() external returns (bytes32);\n\n function DELEGATION_TYPEHASH() external returns (bytes32);\n\n function PERMIT_TYPEHASH() external returns (bytes32);\n\n function nonces(address _user) external view returns (uint256);\n\n function BOND() external returns (uint256);\n\n function UNBOND() external returns (uint256);\n\n function LIQUIDITYBOND() external returns (uint256);\n\n function FEE() external returns (uint256);\n\n function BASE() external returns (uint256);\n\n function ETH() external returns (address);\n\n function bondings(address _user, address _bonding) external view returns (uint256);\n\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\n\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function bonds(address _keeper, address _bonding) external view returns (uint256);\n\n function votes(address _delegator) external view returns (uint256);\n\n function firstSeen(address _keeper) external view returns (uint256);\n\n function disputes(address _keeper) external view returns (bool);\n\n function lastJob(address _keeper) external view returns (uint256);\n\n function workCompleted(address _keeper) external view returns (uint256);\n\n function jobs(address _job) external view returns (bool);\n\n function credits(address _job, address _credit) external view returns (uint256);\n\n function liquidityProvided(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmountsUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function jobProposalDelay(address _job) external view returns (uint256);\n\n function liquidityApplied(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmount(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function keepers(address _keeper) external view returns (bool);\n\n function blacklist(address _keeper) external view returns (bool);\n\n function keeperList(uint256 _index) external view returns (address);\n\n function jobList(uint256 _index) external view returns (address);\n\n function governance() external returns (address);\n\n function pendingGovernance() external returns (address);\n\n function liquidityAccepted(address _liquidity) external view returns (bool);\n\n function liquidityPairs(uint256 _index) external view returns (address);\n\n // Methods\n function getCurrentVotes(address _account) external view returns (uint256);\n\n function addCreditETH(address _job) external payable;\n\n function addCredit(\n address _credit,\n address _job,\n uint256 _amount\n ) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function pairs() external view returns (address[] memory);\n\n function addLiquidityToJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function applyCreditToJob(\n address _provider,\n address _liquidity,\n address _job\n ) external;\n\n function unbondLiquidityFromJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function removeLiquidityFromJob(address _liquidity, address _job) external;\n\n function mint(uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n\n function worked(address _keeper) external;\n\n function receipt(\n address _credit,\n address _keeper,\n uint256 _amount\n ) external;\n\n function receiptETH(address _keeper, uint256 _amount) external;\n\n function addJob(address _job) external;\n\n function getJobs() external view returns (address[] memory);\n\n function removeJob(address _job) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function isKeeper(address _keeper) external returns (bool);\n\n function isMinKeeper(\n address _keeper,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function bond(address _bonding, uint256 _amount) external;\n\n function getKeepers() external view returns (address[] memory);\n\n function activate(address _bonding) external;\n\n function unbond(address _bonding, uint256 _amount) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function withdraw(address _bonding) external;\n\n function dispute(address _keeper) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function permit(\n address _owner,\n address _spender,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3r.sol';\n\ncontract Keep3rForTestnet is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3r.sol';\n\ncontract Keep3rForTest is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3r.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\n\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @param _governance Address of governance\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\n constructor(\n address _governance, // governance\n address _keep3rHelperSidechain, // helper\n address _wrappedKP3R, // keep3rV1\n address _keep3rEscrow // keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\n\n // Keep3rSidechainAccountance\n\n /// @inheritdoc IKeep3rSidechainAccountance\n function virtualReserves() external view override returns (int256 _virtualReserves) {\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\n }\n\n // Keep3rJobFundableLiquidity\n\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\n /// @param _liquidity Address of the liquidity token being approved\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\n /// @param _liquidity Address of the liquidity token being observed\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n\n // Will always ask for 2 accumulators in sidechain\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Keep3rJobsWorkable\n\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\n function worked(address) external pure override {\n revert Deprecated();\n }\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Uses a USD per gas unit payment mechanism\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\n if (_initialGas == 0) revert GasNotInitialized();\n // Gas used for quote calculations & payment is not rewarded\n uint256 _gasLeft = _getGasLeft();\n\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\n\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _kp3rPayment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\n }\n\n // Keep3rKeeperFundable\n\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\n function _depositBonds(uint256 _amount) internal virtual override {\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\n }\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// solhint-disable-next-line no-empty-blocks\n\nimport '../peripherals/IMintable.sol';\n\n/// @title Keep3rEscrow contract\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\ninterface IKeep3rEscrow is IMintable {\n /// @notice Emitted when Keep3rEscrow#deposit function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _sender The address that called the function\n /// @param _amount The amount of wKP3R the user deposited\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#mint function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _recipient The address that will received the newly minted wKP3R\n /// @param _amount The amount of wKP3R minted to the recipient\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\n /// @param _newWKP3R The address of the wKP3R contract\n event wKP3RSet(address _newWKP3R);\n\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\n error InsufficientBalance();\n\n /// @notice Lists the address of the wKP3R contract\n /// @return _wKP3RAddress The address of wKP3R\n function wKP3R() external view returns (address _wKP3RAddress);\n\n /// @notice Deposits wKP3R into the contract\n /// @param _amount The amount of wKP3R to deposit\n function deposit(uint256 _amount) external;\n\n /// @notice mints wKP3R to the recipient\n /// @param _amount The amount of wKP3R to mint\n function mint(uint256 _amount) external;\n\n /// @notice sets the wKP3R address\n /// @param _wKP3R the wKP3R address\n function setWKP3R(address _wKP3R) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../IKeep3rHelper.sol';\n\n/// @title Keep3rHelperSidechain contract\n/// @notice Contains all the helper functions for sidechain keep3r implementations\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\n // Events\n\n /// @notice The oracle for a liquidity has been saved\n /// @param _liquidity The address of the given liquidity\n /// @param _oraclePool The address of the oracle pool\n event OracleSet(address _liquidity, address _oraclePool);\n\n /// @notice Emitted when the WETH USD pool is changed\n /// @param _address Address of the new WETH USD pool\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\n\n /// Variables\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n /// @return _weth Address of WETH token\n // solhint-disable func-name-mixedcase\n function WETH() external view returns (address _weth);\n\n /// @return _oracle The address of the observable pool for given liquidity\n function oracle(address _liquidity) external view returns (address _oracle);\n\n /// @notice WETH-USD pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice Quotes USD to ETH\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\n /// @param _usd The amount of USD to quote to ETH\n /// @return _eth The resulting amount of ETH after quoting the USD\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\n\n /// Methods\n\n /// @notice Sets an oracle for a given liquidity\n /// @param _liquidity The address of the liquidity\n /// @param _oracle The address of the pool used to quote the liquidity from\n /// @dev The oracle must contain KP3R as either token0 or token1\n function setOracle(address _liquidity, address _oracle) external;\n\n /// @notice Sets an oracle for querying WETH/USD quote\n /// @param _poolAddress The address of the pool used as oracle\n /// @dev The oracle must contain WETH as either token0 or token1\n function setWethUsdPool(address _poolAddress) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IKeep3rJobs.sol';\n\n/// @title Keep3rJobWorkableRated contract\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\n /// @notice Throws when job contract calls deprecated worked(address) function\n error Deprecated();\n\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title IKeep3rSidechainAccountance interface\n/// @notice Implements a view to get the amount of credits that can be withdrawn\ninterface IKeep3rSidechainAccountance {\n /// @notice The surplus amount of wKP3Rs in escrow contract\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\n function virtualReserves() external view returns (int256 _virtualReserves);\n}\n" + }, + "solidity/interfaces/peripherals/IMintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IGovernable.sol';\nimport './IBaseErrors.sol';\n\n/// @title Mintable contract\n/// @notice Manages the minter role\ninterface IMintable is IBaseErrors, IGovernable {\n // Events\n\n /// @notice Emitted when governance sets a new minter\n /// @param _minter Address of the new minter\n event MinterSet(address _minter);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not the minter\n error OnlyMinter();\n\n // Variables\n\n /// @notice Stores the minter address\n /// @return _minter The minter addresss\n function minter() external view returns (address _minter);\n\n // Methods\n\n /// @notice Sets a new address to be the minter\n /// @param _minter The address set as the minter\n function setMinter(address _minter) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rSidechainForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTest is Keep3rSidechain {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _governance,\n address _keep3rHelper,\n address _wrappedKP3R,\n address _keep3rEscrow\n ) Keep3rSidechain(_governance, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n}\n" + }, + "solidity/for-test/JobRatedForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\n\ncontract JobRatedForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n uint256 public usdPerGasUnit = 1_000e9;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n}\n" + }, + "solidity/for-test/JobForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract JobForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/for-test/BasicJob.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract BasicJob {\n error KeeperNotValid();\n\n address public keep3r;\n uint256 public nonce;\n uint256[] public array;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external upkeep {}\n\n function workHard(uint256 _howHard) external upkeep {\n for (uint256 i = nonce; i < _howHard; i++) {\n nonce++;\n }\n }\n\n function workRefund(uint256 _howHard) external upkeep {\n for (uint256 i; i < _howHard; i++) {\n array.push(i);\n }\n\n while (array.length > 0) {\n array.pop();\n }\n }\n\n modifier upkeep() {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\n _;\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/peripherals/IBaseErrors.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/external/IKeep3rV1.sol';\nimport '../interfaces/IKeep3rHelperParameters.sol';\nimport './peripherals/Governable.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\n /// @inheritdoc IKeep3rHelperParameters\n address public immutable override KP3R;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public constant override BOOST_BASE = 10_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBoost = 11_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override maxBoost = 12_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override targetBond = 200 ether;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override workExtraGas = 34_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint32 public override quoteTwapTime = 10 minutes;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBaseFee = 15e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minPriorityFee = 2e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n address public override keep3rV2;\n\n /// @inheritdoc IKeep3rHelperParameters\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Governable(_governance) {\n KP3R = _kp3r;\n keep3rV2 = _keep3rV2;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setKp3rWethPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\n minBoost = _minBoost;\n emit MinBoostChange(minBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\n maxBoost = _maxBoost;\n emit MaxBoostChange(maxBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\n targetBond = _targetBond;\n emit TargetBondChange(targetBond);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\n if (_keep3rV2 == address(0)) revert ZeroAddress();\n keep3rV2 = _keep3rV2;\n emit Keep3rV2Change(keep3rV2);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\n workExtraGas = _workExtraGas;\n emit WorkExtraGasChange(workExtraGas);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\n _setQuoteTwapTime(_quoteTwapTime);\n }\n\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\n quoteTwapTime = _quoteTwapTime;\n emit QuoteTwapTimeChange(quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\n minBaseFee = _minBaseFee;\n emit MinBaseFeeChange(minBaseFee);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\n minPriorityFee = _minPriorityFee;\n emit MinPriorityFeeChange(minPriorityFee);\n }\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function _setKp3rWethPool(address _poolAddress) internal {\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\n\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\n\n return TokenOraclePool(_poolAddress, _isTKNToken0);\n }\n}\n" + }, + "solidity/contracts/libraries/TickMath.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n// solhint-disable\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n // Second inequality must be < because the price can never reach the price at the max tick\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport './pool/IUniswapV3PoolImmutables.sol';\nimport './pool/IUniswapV3PoolState.sol';\nimport './pool/IUniswapV3PoolDerivedState.sol';\nimport './pool/IUniswapV3PoolActions.sol';\nimport './pool/IUniswapV3PoolOwnerActions.sol';\nimport './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolEvents\n{\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// observationIndex The index of the last oracle observation that was written,\n /// observationCardinality The current maximum number of observations stored in the pool,\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper,\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return _liquidity The amount of liquidity in the position,\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 _liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// Returns initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" + }, + "solidity/for-test/UniV3PairManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport '../contracts/libraries/LiquidityAmounts.sol';\nimport '../contracts/libraries/FixedPoint96.sol';\nimport '../contracts/libraries/FullMath.sol';\nimport '../contracts/libraries/TickMath.sol';\nimport '../contracts/UniV3PairManager.sol';\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManagerForTest is UniV3PairManager {\n constructor(address _pool, address _governance) UniV3PairManager(_pool, _governance) {}\n\n function internalAddLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n external\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n return _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n }\n\n function internalPay(\n address token,\n address payer,\n address recipient,\n uint256 value\n ) external {\n return _pay(token, payer, recipient, value);\n }\n\n function internalMint(address dst, uint256 amount) external {\n return _mint(dst, amount);\n }\n\n function internalBurn(address dst, uint256 amount) external {\n return _burn(dst, amount);\n }\n\n function internalTransferTokens(\n address src,\n address dst,\n uint256 amount\n ) external {\n _transferTokens(src, dst, amount);\n }\n\n function internalSafeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) external {\n _safeTransferFrom(token, from, to, value);\n }\n\n receive() external payable {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "solidity/contracts/libraries/LiquidityAmounts.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport './FullMath.sol';\nimport './FixedPoint96.sol';\n\n// solhint-disable\nlibrary LiquidityAmounts {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/contracts/libraries/FixedPoint96.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nlibrary FixedPoint96 {\n // solhint-disable\n uint8 internal constant RESOLUTION = 96;\n uint256 internal constant Q96 = 0x1000000000000000000000000;\n}\n" + }, + "solidity/contracts/UniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport './libraries/LiquidityAmounts.sol';\nimport './libraries/FixedPoint96.sol';\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\n\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\nimport './peripherals/Governable.sol';\n\ncontract UniV3PairManager is IUniV3PairManager, Governable {\n /// @inheritdoc IERC20Metadata\n string public override name;\n\n /// @inheritdoc IERC20Metadata\n string public override symbol;\n\n /// @inheritdoc IERC20\n uint256 public override totalSupply;\n\n /// @inheritdoc IPairManager\n address public immutable override factory;\n\n /// @inheritdoc IPairManager\n address public immutable override token0;\n\n /// @inheritdoc IPairManager\n address public immutable override token1;\n\n /// @inheritdoc IPairManager\n address public immutable override pool;\n\n /// @inheritdoc IUniV3PairManager\n uint24 public immutable override fee;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioAX96;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioBX96;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickLower;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickUpper;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickSpacing;\n\n /// @notice Uniswap's maximum tick\n /// @dev Due to tick spacing, pools with different fees may have differences between _MAX_TICK and tickUpper. Use tickUpper to find the max tick of the pool.\n int24 private constant _MAX_TICK = 887272;\n\n /// @inheritdoc IERC20Metadata\n //solhint-disable-next-line const-name-snakecase\n uint8 public constant override decimals = 18;\n\n /// @inheritdoc IERC20\n mapping(address => mapping(address => uint256)) public override allowance;\n\n /// @inheritdoc IERC20\n mapping(address => uint256) public override balanceOf;\n\n /// @notice Struct that contains token0, token1, and fee of the Uniswap pool\n PoolKey private _poolKey;\n\n constructor(address _pool, address _governance) Governable(_governance) {\n uint24 _fee = IUniswapV3Pool(_pool).fee();\n address _token0 = IUniswapV3Pool(_pool).token0();\n address _token1 = IUniswapV3Pool(_pool).token1();\n int24 _tickSpacing = IUniswapV3Pool(_pool).tickSpacing();\n int24 _tickUpper = _MAX_TICK - (_MAX_TICK % _tickSpacing);\n int24 _tickLower = -_tickUpper;\n\n factory = msg.sender;\n pool = _pool;\n fee = _fee;\n tickSpacing = _tickSpacing;\n tickUpper = _tickUpper;\n tickLower = _tickLower;\n token0 = _token0;\n token1 = _token1;\n name = string(abi.encodePacked('Keep3rLP - ', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n symbol = string(abi.encodePacked('kLP-', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n\n sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(_tickLower);\n sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(_tickUpper);\n _poolKey = PoolKey({token0: _token0, token1: _token1, fee: _fee});\n }\n\n // This low-level function should be called from a contract which performs important safety checks\n /// @inheritdoc IUniV3PairManager\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint128 liquidity) {\n (liquidity, , ) = _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n _mint(to, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external override {\n MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));\n if (msg.sender != pool) revert OnlyPool();\n if (amount0Owed > 0) _pay(decoded._poolKey.token0, decoded.payer, pool, amount0Owed);\n if (amount1Owed > 0) _pay(decoded._poolKey.token1, decoded.payer, pool, amount1Owed);\n }\n\n /// @inheritdoc IUniV3PairManager\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint256 amount0, uint256 amount1) {\n (amount0, amount1) = IUniswapV3Pool(pool).burn(tickLower, tickUpper, liquidity);\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n\n IUniswapV3Pool(pool).collect(to, tickLower, tickUpper, uint128(amount0), uint128(amount1));\n _burn(msg.sender, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function collect() external override onlyGovernance returns (uint256 amount0, uint256 amount1) {\n (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n (amount0, amount1) = IUniswapV3Pool(pool).collect(governance, tickLower, tickUpper, tokensOwed0, tokensOwed1);\n }\n\n /// @inheritdoc IUniV3PairManager\n function position()\n external\n view\n override\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n )\n {\n (liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128, tokensOwed0, tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n }\n\n /// @inheritdoc IERC20\n function approve(address spender, uint256 amount) external override returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transfer(address to, uint256 amount) external override returns (bool) {\n _transferTokens(msg.sender, to, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool) {\n address spender = msg.sender;\n uint256 spenderAllowance = allowance[from][spender];\n\n if (spender != from && spenderAllowance != type(uint256).max) {\n uint256 newAllowance = spenderAllowance - amount;\n allowance[from][spender] = newAllowance;\n\n emit Approval(from, spender, newAllowance);\n }\n\n _transferTokens(from, to, amount);\n return true;\n }\n\n /// @notice Adds liquidity to an initialized pool\n /// @dev Reverts if the returned amount0 is less than amount0Min or if amount1 is less than amount1Min\n /// @dev This function calls the mint function of the corresponding Uniswap pool, which in turn calls UniswapV3Callback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @return liquidity The calculated liquidity we get for the token amounts we provided\n /// @return amount0 The amount of token0 we ended up providing\n /// @return amount1 The amount of token1 we ended up providing\n function _addLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n internal\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(pool).slot0();\n\n liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, amount0Desired, amount1Desired);\n\n (amount0, amount1) = IUniswapV3Pool(pool).mint(\n address(this),\n tickLower,\n tickUpper,\n liquidity,\n abi.encode(MintCallbackData({_poolKey: _poolKey, payer: msg.sender}))\n );\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n }\n\n /// @notice Transfers the passed-in token from the payer to the recipient for the corresponding value\n /// @param token The token to be transferred to the recipient\n /// @param from The address of the payer\n /// @param to The address of the passed-in tokens recipient\n /// @param value How much of that token to be transferred from payer to the recipient\n function _pay(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n _safeTransferFrom(token, from, to, value);\n }\n\n /// @notice Mints Keep3r credits to the passed-in address of recipient and increases total supply of Keep3r credits by the corresponding amount\n /// @param to The recipient of the Keep3r credits\n /// @param amount The amount Keep3r credits to be minted to the recipient\n function _mint(address to, uint256 amount) internal {\n totalSupply += amount;\n balanceOf[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @notice Burns Keep3r credits to the passed-in address of recipient and reduces total supply of Keep3r credits by the corresponding amount\n /// @param to The address that will get its Keep3r credits burned\n /// @param amount The amount Keep3r credits to be burned from the recipient/recipient\n function _burn(address to, uint256 amount) internal {\n totalSupply -= amount;\n balanceOf[to] -= amount;\n emit Transfer(to, address(0), amount);\n }\n\n /// @notice Transfers amount of Keep3r credits between two addresses\n /// @param from The user that transfers the Keep3r credits\n /// @param to The user that receives the Keep3r credits\n /// @param amount The amount of Keep3r credits to be transferred\n function _transferTokens(\n address from,\n address to,\n uint256 amount\n ) internal {\n balanceOf[from] -= amount;\n balanceOf[to] += amount;\n\n emit Transfer(from, to, amount);\n }\n\n /// @notice Transfers the passed-in token from the specified \"from\" to the specified \"to\" for the corresponding value\n /// @dev Reverts with IUniV3PairManager#UnsuccessfulTransfer if the transfer was not successful,\n /// or if the passed data length is different than 0 and the decoded data is not a boolean\n /// @param token The token to be transferred to the specified \"to\"\n /// @param from The address which is going to transfer the tokens\n /// @param value How much of that token to be transferred from \"from\" to \"to\"\n function _safeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert UnsuccessfulTransfer();\n }\n}\n" + }, + "solidity/interfaces/external/IWeth9.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IWeth9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256) external;\n}\n" + }, + "solidity/interfaces/IUniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IPairManager.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\nimport './peripherals/IGovernable.sol';\n\n/// @title Pair Manager contract\n/// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner\n/// so that the user can use it as liquidity for a Keep3rJob\ninterface IUniV3PairManager is IGovernable, IPairManager {\n // Structs\n struct PoolKey {\n address token0;\n address token1;\n uint24 fee;\n }\n\n /// @notice The data to be decoded by the UniswapV3MintCallback function\n struct MintCallbackData {\n PoolKey _poolKey; // Struct that contains token0, token1, and fee of the pool passed into the constructor\n address payer; // The address of the payer, which will be the msg.sender of the mint function\n }\n\n // Variables\n\n /// @notice The fee of the Uniswap pool passed into the constructor\n /// @return _fee The fee of the Uniswap pool passed into the constructor\n function fee() external view returns (uint24 _fee);\n\n /// @notice Highest tick in the Uniswap's curve\n /// @return _tickUpper The highest tick in the Uniswap's curve\n function tickUpper() external view returns (int24 _tickUpper);\n\n /// @notice Lowest tick in the Uniswap's curve\n /// @return _tickLower The lower tick in the Uniswap's curve\n function tickLower() external view returns (int24 _tickLower);\n\n /// @notice The pair tick spacing\n /// @return _tickSpacing The pair tick spacing\n function tickSpacing() external view returns (int24 _tickSpacing);\n\n /// @notice The sqrtRatioAX96 at the lowest tick (-887200) of the Uniswap pool\n /// @return _sqrtPriceA96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the lowest tick\n function sqrtRatioAX96() external view returns (uint160 _sqrtPriceA96);\n\n /// @notice The sqrtRatioBX96 at the highest tick (887200) of the Uniswap pool\n /// @return _sqrtPriceBX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the highest tick\n function sqrtRatioBX96() external view returns (uint160 _sqrtPriceBX96);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the pool\n error OnlyPool();\n\n /// @notice Throws when the slippage exceeds what the user is comfortable with\n error ExcessiveSlippage();\n\n /// @notice Throws when a transfer is unsuccessful\n error UnsuccessfulTransfer();\n\n // Methods\n\n /// @notice This function is called after a user calls IUniV3PairManager#mint function\n /// It ensures that any tokens owed to the pool are paid by the msg.sender of IUniV3PairManager#mint function\n /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity\n /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity\n /// @param data The encoded token0, token1, fee (_poolKey) and the payer (msg.sender) of the IUniV3PairManager#mint function\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external;\n\n /// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool\n /// @dev Triggers UniV3PairManager#uniswapV3MintCallback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @param to The address to which the kLP tokens are going to be minted to\n /// @return liquidity kLP tokens sent in exchange for the provision of tokens\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint128 liquidity);\n\n /// @notice Returns the pair manager's position in the corresponding UniswapV3 pool\n /// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager\n /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position\n /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position\n /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation\n /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation\n function position()\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees\n // owed to a specific position to the recipient, in this case, that recipient is the pair manager\n /// @dev The collected fees will be sent to governance\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect() external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity\n // in the entire range\n /// @param liquidity The amount of liquidity to be burned\n /// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)\n /// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)\n /// @param to The address that will receive the due fees\n /// @return amount0 The calculated amount of token0 that will be sent to the recipient\n /// @return amount1 The calculated amount of token1 that will be sent to the recipient\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint256 amount0, uint256 amount1);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "solidity/interfaces/IPairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IGovernable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ninterface IPairManagerFactory is IGovernable {\n // Variables\n\n /// @notice Maps the address of a Uniswap pool, to the address of the corresponding PairManager\n /// For example, the uniswap address of DAI-WETH, will return the Keep3r/DAI-WETH pair manager address\n /// @param _pool The address of the Uniswap pool\n /// @return _pairManager The address of the corresponding pair manager\n function pairManagers(address _pool) external view returns (address _pairManager);\n\n // Events\n\n /// @notice Emitted when a new pair manager is created\n /// @param _pool The address of the corresponding Uniswap pool\n /// @param _pairManager The address of the just-created pair manager\n event PairCreated(address _pool, address _pairManager);\n\n // Errors\n\n /// @notice Throws an error if the pair manager is already initialized\n error AlreadyInitialized();\n\n /// @notice Throws an error if the caller is not the owner\n error OnlyOwner();\n\n // Methods\n\n /// @notice Creates a new pair manager based on the address of a Uniswap pool\n /// For example, the uniswap address of DAI-WETH, will create the Keep3r/DAI-WETH pool\n /// @param _pool The address of the Uniswap pool the pair manager will be based of\n /// @return _pairManager The address of the just-created pair manager\n function createPairManager(address _pool) external returns (address _pairManager);\n}\n" + }, + "solidity/contracts/UniV3PairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IPairManagerFactory.sol';\nimport './UniV3PairManager.sol';\nimport './peripherals/Governable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ncontract UniV3PairManagerFactory is IPairManagerFactory, Governable {\n mapping(address => address) public override pairManagers;\n\n constructor(address _governance) Governable(_governance) {}\n\n ///@inheritdoc IPairManagerFactory\n function createPairManager(address _pool) external override returns (address _pairManager) {\n if (pairManagers[_pool] != address(0)) revert AlreadyInitialized();\n _pairManager = address(new UniV3PairManager(_pool, governance));\n pairManagers[_pool] = _pairManager;\n emit PairCreated(_pool, _pairManager);\n }\n}\n" + }, + "solidity/for-test/peripherals/GovernableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" + }, + "solidity/for-test/BridgeForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ncontract BridgeForTest is ERC20 {\n address public immutable kp3r;\n\n constructor(address _kp3r) ERC20('Wrapped KP3R', 'wKP3R') {\n kp3r = _kp3r;\n }\n\n function bridge(uint256 _amount) external {\n IERC20(kp3r).transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n }\n\n function bridgeBack(uint256 _amount) external {\n _burn(msg.sender, _amount);\n IERC20(kp3r).transfer(msg.sender, _amount);\n }\n}\n" + }, + "solidity/for-test/ERC20ForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(uint256 _amount) public {\n _mint(msg.sender, _amount);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(uint256 _amount) public {\n _burn(msg.sender, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n function deposit() external payable {\n // Function added for compatibility with WETH\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperFundableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperFundable.sol';\n\ncontract Keep3rKeeperFundableForTest is Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function isKeeper(address _keeper) external view returns (bool) {\n return _keepers.contains(_keeper);\n }\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/Mintable.sol';\nimport '../peripherals/DustCollector.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rEscrow\n address public override wKP3R;\n\n /// @param _governance Address of governance\n /// @param _wKP3R Address of wrapped KP3R implementation\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\n wKP3R = _wKP3R;\n }\n\n /// @inheritdoc IKeep3rEscrow\n function deposit(uint256 _amount) external override {\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function mint(uint256 _amount) external override onlyMinter {\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function setWKP3R(address _wKP3R) external override onlyGovernance {\n if (_wKP3R == address(0)) revert ZeroAddress();\n wKP3R = _wKP3R;\n emit wKP3RSet(wKP3R);\n }\n}\n" + }, + "solidity/contracts/peripherals/Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IMintable.sol';\nimport './Governable.sol';\n\nabstract contract Mintable is Governable, IMintable {\n /// @inheritdoc IMintable\n address public override minter;\n\n constructor(address _governance) Governable(_governance) {}\n\n /// @inheritdoc IMintable\n function setMinter(address _minter) external override onlyGovernance {\n if (_minter == address(0)) revert ZeroAddress();\n minter = _minter;\n emit MinterSet(_minter);\n }\n\n /// @notice Functions with this modifier can only be called by the minter;\n modifier onlyMinter() {\n if (msg.sender != minter) revert OnlyMinter();\n _;\n }\n}\n" + }, + "solidity/for-test/peripherals/DustCollectorForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/DustCollector.sol';\n\ncontract DustCollectorForTest is DustCollector {\n constructor() DustCollector() Governable(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rAccountanceForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rAccountance.sol';\n\ncontract Keep3rAccountanceForTest is Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor() Keep3rRoles(msg.sender) {}\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n\n function setKeeper(address keeper) external {\n _keepers.add(keeper);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableLiquidityForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol';\n\ncontract Keep3rJobFundableLiquidityForTest is Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external returns (bool) {\n return _jobLiquidities[_job].add(_liquidity);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewTickOrder(address _liquidity) external view returns (bool) {\n return _isKP3RToken0[_liquidity];\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function internalSettleJobAccountance(address _job) external {\n _settleJobAccountance(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobDisputable.sol';\n\ncontract Keep3rJobDisputableForTest is Keep3rJobDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function internalJobLiquidityCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobLiquidityCredits[_job];\n }\n\n function internalJobPeriodCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobPeriodCredits[_job];\n }\n\n function internalJobTokens(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobTokens[_job].length());\n for (uint256 i; i < _jobTokens[_job].length(); i++) {\n _tokens[i] = _jobTokens[_job].at(i);\n }\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobLiquidities[_job].length());\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n _tokens[i] = _jobLiquidities[_job].at(i);\n }\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rDisputable.sol';\n\ncontract Keep3rDisputableForTest is Keep3rDisputable {\n constructor() Keep3rParameters(address(0), address(0), address(0)) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperDisputable.sol';\n\ncontract Keep3rKeeperDisputableForTest is Keep3rKeeperDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function internalSlash(\n address _bonded,\n address _keeper,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external {\n _slash(_bonded, _keeper, _bondAmount, _unbondAmount);\n }\n\n function isKeeper(address _address) external view returns (bool _isKeeper) {\n _isKeeper = _keepers.contains(_address);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableCreditsForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableCredits.sol';\n\ncontract Keep3rJobFundableCreditsForTest is Keep3rJobFundableCredits {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job, address _jobOwner) external {\n _jobs.add(_job);\n jobOwner[_job] = _jobOwner;\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function isJobToken(address _job, address _token) external view returns (bool _contains) {\n _contains = _jobTokens[_job].contains(_token);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/IKeep3rHelper.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n /// @inheritdoc IKeep3rHelper\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelper\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\n // solhint-disable-next-line avoid-tx-origin\n return getRewardAmountFor(tx.origin, _gasUsed);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\n _bonds = Math.min(_bonds, targetBond);\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\n _rewardBoost = _cap * _getBasefee();\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\n }\n\n /// @inheritdoc IKeep3rHelper\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\n address _token0;\n address _token1;\n (_token0, _token1) = getPoolTokens(_pool);\n if (_token0 == KP3R) {\n return true;\n } else if (_token1 != KP3R) {\n revert LiquidityPairInvalid();\n }\n }\n\n /// @inheritdoc IKeep3rHelper\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n override\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n )\n {\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\n _tickCumulative1 = _uniswapResponse[0];\n if (_uniswapResponse.length > 1) {\n _tickCumulative2 = _uniswapResponse[1];\n }\n _success = true;\n } catch (bytes memory) {}\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n )\n {\n _oneEthQuote = quote(1 ether);\n _boost = getRewardBoostFor(_bonds);\n _extra = workExtraGas;\n }\n\n /// @inheritdoc IKeep3rHelper\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure override returns (uint256 _kp3rAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) public pure override returns (uint256 _quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\n }\n }\n\n /// @notice Gets the gas basefee cost to calculate keeper rewards\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTestnet is Keep3rHelper {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal pure override returns (uint256) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/Keep3rHelperForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTest is Keep3rHelper {\n uint256 public basefee;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal view override returns (uint256) {\n return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee();\n }\n\n function setBaseFee(uint256 _baseFee) external {\n basefee = _baseFee;\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rHelper.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\n /// @inheritdoc IKeep3rHelperSidechain\n mapping(address => address) public override oracle;\n /// @inheritdoc IKeep3rHelperSidechain\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n address public immutable override WETH;\n\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\n /// @param _governance Address of governance\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\n /// @dev Oracle pools should use 18 decimals tokens\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\n WETH = _weth;\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\n _setQuoteTwapTime(1 days);\n workExtraGas = 0;\n }\n\n /// @inheritdoc IKeep3rHelper\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\n oracle[_liquidity] = _oracle;\n emit OracleSet(_liquidity, _oracle);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n /// @dev Oracle is compatible with IUniswapV3Pool\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setWethUsdPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override(Keep3rHelper, IKeep3rHelper)\n returns (\n uint256 _boost,\n uint256 _oneUsdQuote,\n uint256 _extraGas\n )\n {\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\n _boost = getRewardBoostFor(_bonds);\n _extraGas = workExtraGas;\n }\n\n function _setWethUsdPool(address _poolAddress) internal {\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\n }\n\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechainForTestnet is Keep3rHelperSidechain {\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelperSidechain(_keep3rV2, _governance, _kp3r, _weth, _kp3rWethOracle, _wethUsdOracle) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rParametersForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rParameters.sol';\n\ncontract Keep3rParametersForTest is Keep3rParameters {\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobWorkableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobWorkable.sol';\n\ncontract Keep3rJobWorkableForTest is Keep3rJobWorkable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewGas() external view returns (uint256) {\n return _initialGas;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobMigrationForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobMigration.sol';\n\ncontract Keep3rJobMigrationForTest is Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(address => uint256) public settleJobAccountanceCallCount;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobTokenListLength(address _job) external view returns (uint256) {\n return _jobTokens[_job].length();\n }\n\n function viewJobLiquidityList(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewMigrationCreatedAt(address _fromJob, address _toJob) external view returns (uint256) {\n return _migrationCreatedAt[_fromJob][_toJob];\n }\n\n function isJob(address _job) external view returns (bool) {\n return _jobs.contains(_job);\n }\n\n function _settleJobAccountance(address _job) internal override {\n settleJobAccountanceCallCount[_job]++;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobManager.sol';\n\ncontract Keep3rJobManagerForTest is Keep3rJobManager {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rRoles(msg.sender) {}\n\n function isJob(address _job) external view returns (bool _isJob) {\n _isJob = _jobs.contains(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobOwnershipForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobOwnership.sol';\n\ncontract Keep3rJobOwnershipForTest is Keep3rJobOwnership {}\n" + }, + "solidity/for-test/libraries/LiquidityAmountsForTest.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/libraries/FullMath.sol';\nimport '../../contracts/libraries/FixedPoint96.sol';\n\n/// @dev Made this library into a contract to be able to calculate liquidity more precisely for tests\n\n// solhint-disable\ncontract LiquidityAmountsForTest {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) external pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) external pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/for-test/IUniswapV3PoolForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n// solhint-disable-next-line no-empty-blocks\ninterface IUniswapV3PoolForTest is IERC20Minimal, IUniswapV3Pool {\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Minimal ERC20 interface for Uniswap\n/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3\ninterface IERC20Minimal {\n /// @notice Returns the balance of a token\n /// @param account The account for which to look up the number of tokens it has, i.e. its balance\n /// @return The number of tokens held by the account\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Transfers the amount of token from the `msg.sender` to the recipient\n /// @param recipient The account that will receive the amount transferred\n /// @param amount The number of tokens to send from the sender to the recipient\n /// @return Returns true for a successful transfer, false for an unsuccessful transfer\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /// @notice Returns the current allowance given to a spender by an owner\n /// @param owner The account of the token owner\n /// @param spender The account of the token spender\n /// @return The current allowance granted by `owner` to `spender`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`\n /// @param spender The account which will be allowed to spend a given amount of the owners tokens\n /// @param amount The amount of tokens allowed to be used by `spender`\n /// @return Returns true for a successful approval, false for unsuccessful\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`\n /// @param sender The account from which the transfer will be initiated\n /// @param recipient The recipient of the transfer\n /// @param amount The amount of the transfer\n /// @return Returns true for a successful transfer, false for unsuccessful\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.\n /// @param from The account from which the tokens were sent, i.e. the balance decreased\n /// @param to The account to which the tokens were sent, i.e. the balance increased\n /// @param value The amount of tokens that were transferred\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.\n /// @param owner The account that approved spending of its tokens\n /// @param spender The account for which the spending allowance was modified\n /// @param value The new allowance from the owner to the spender\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 33 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimisticGoerli/solcInputs/8c968687fa7312972c014a5aac38beba.json b/deployments/optimisticGoerli/solcInputs/8c968687fa7312972c014a5aac38beba.json new file mode 100644 index 0000000..a83b63d --- /dev/null +++ b/deployments/optimisticGoerli/solcInputs/8c968687fa7312972c014a5aac38beba.json @@ -0,0 +1,334 @@ +{ + "language": "Solidity", + "sources": { + "solidity/contracts/Keep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport './peripherals/jobs/Keep3rJobs.sol';\nimport './peripherals/keepers/Keep3rKeepers.sol';\nimport './peripherals/DustCollector.sol';\n\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\n}\n" + }, + "solidity/interfaces/IKeep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobManager.sol';\nimport './Keep3rJobWorkable.sol';\nimport './Keep3rJobDisputable.sol';\n\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\nimport './Keep3rKeeperDisputable.sol';\n\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\n" + }, + "solidity/contracts/peripherals/DustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '../../contracts/peripherals/Governable.sol';\nimport '../../interfaces/peripherals/IDustCollector.sol';\n\nabstract contract DustCollector is IDustCollector, Governable {\n using SafeERC20 for IERC20;\n\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external override onlyGovernance {\n if (_to == address(0)) revert ZeroAddress();\n if (_token == _ETH_ADDRESS) {\n payable(_to).transfer(_amount);\n } else {\n IERC20(_token).safeTransfer(_to, _amount);\n }\n emit DustSent(_token, _amount, _to);\n }\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" + }, + "solidity/interfaces/peripherals/IBaseErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" + }, + "solidity/interfaces/peripherals/IGovernable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" + }, + "solidity/interfaces/peripherals/IDustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @inheritdoc IKeep3rJobManager\n function addJob(address _job) external override {\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\n if (hasBonded[_job]) revert AlreadyAKeeper();\n _jobs.add(_job);\n jobOwner[_job] = msg.sender;\n emit JobAddition(_job, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobMigration.sol';\nimport '../../../interfaces/IKeep3rHelper.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 internal _initialGas;\n\n /// @inheritdoc IKeep3rJobWorkable\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\n _initialGas = _getGasLeft();\n if (_keepers.contains(_keeper)) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external override returns (bool _isBondedKeeper) {\n _initialGas = _getGasLeft();\n if (\n _keepers.contains(_keeper) &&\n bonds[_keeper][_bond] >= _minBond &&\n workCompleted[_keeper] >= _earned &&\n block.timestamp - firstSeen[_keeper] >= _age\n ) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function worked(address _keeper) external virtual override {\n if (_initialGas == 0) revert GasNotInitialized();\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _gasLeft = _getGasLeft();\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n _gasLeft = _getGasLeft();\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function bondedPayment(address _keeper, uint256 _payment) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (disputes[_keeper]) revert Disputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_keeper, _amount);\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\n }\n\n function _bondedPayment(\n address _job,\n address _keeper,\n uint256 _payment\n ) internal {\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\n\n workedAt[_job] = block.timestamp;\n _jobLiquidityCredits[_job] -= _payment;\n bonds[_keeper][keep3rV1] += _payment;\n workCompleted[_keeper] += _payment;\n totalBonds += _payment;\n }\n\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\n /// @param _gasLeft Amount of gas left after working the job\n /// @param _extraGas Amount of expected unaccounted gas\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\n /// @return _payment Amount to be payed in KP3R tokens\n function _calculatePayment(\n uint256 _gasLeft,\n uint256 _extraGas,\n uint256 _oneEthQuote,\n uint256 _boost\n ) internal view returns (uint256 _payment) {\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\n }\n\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\n _gasLeft = (gasleft() * 64) / 63;\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\nimport '../Keep3rDisputable.sol';\n\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\n\n try IERC20(_token).transfer(governance, _amount) {} catch {}\n jobTokenCredits[_job][_token] -= _amount;\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit JobSlashToken(_job, _token, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobPendingOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\n jobPendingOwner[_job] = _newOwner;\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\n }\n\n /// @inheritdoc IKeep3rJobOwnership\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\n address _previousOwner = jobOwner[_job];\n\n jobOwner[_job] = jobPendingOwner[_job];\n delete jobPendingOwner[_job];\n\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\n }\n\n modifier onlyJobOwner(address _job) {\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\n _;\n }\n\n modifier onlyPendingJobOwner(address _job) {\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\nimport './Keep3rRoles.sol';\n\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @notice List of all enabled keepers\n EnumerableSet.AddressSet internal _keepers;\n\n /// @inheritdoc IKeep3rAccountance\n uint256 public override totalBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override workCompleted;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override firstSeen;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override disputes;\n\n /// @inheritdoc IKeep3rAccountance\n /// @notice Mapping (job => bonding => amount)\n mapping(address => mapping(address => uint256)) public override bonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\n\n /// @notice The current liquidity credits available for a job\n mapping(address => uint256) internal _jobLiquidityCredits;\n\n /// @notice Map the address of a job to its correspondent periodCredits\n mapping(address => uint256) internal _jobPeriodCredits;\n\n /// @notice Enumerable array of Job Tokens for Credits\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\n\n /// @notice List of liquidities that a job has (job => liquidities)\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\n\n /// @notice Liquidity pool to observe\n mapping(address => address) internal _liquidityPool;\n\n /// @notice Tracks if a pool has KP3R as token0\n mapping(address => bool) internal _isKP3RToken0;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override hasBonded;\n\n /// @notice List of all enabled jobs\n EnumerableSet.AddressSet internal _jobs;\n\n /// @inheritdoc IKeep3rAccountance\n function jobs() external view override returns (address[] memory _list) {\n _list = _jobs.values();\n }\n\n /// @inheritdoc IKeep3rAccountance\n function keepers() external view override returns (address[] memory _list) {\n _list = _keepers.values();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport './DustCollector.sol';\nimport './Governable.sol';\n\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override slashers;\n\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override disputers;\n\n constructor(address _governance) Governable(_governance) DustCollector() {}\n\n /// @inheritdoc IKeep3rRoles\n function addSlasher(address _slasher) external override onlyGovernance {\n if (_slasher == address(0)) revert ZeroAddress();\n if (slashers[_slasher]) revert SlasherExistent();\n slashers[_slasher] = true;\n emit SlasherAdded(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeSlasher(address _slasher) external override onlyGovernance {\n if (!slashers[_slasher]) revert SlasherUnexistent();\n delete slashers[_slasher];\n emit SlasherRemoved(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function addDisputer(address _disputer) external override onlyGovernance {\n if (_disputer == address(0)) revert ZeroAddress();\n if (disputers[_disputer]) revert DisputerExistent();\n disputers[_disputer] = true;\n emit DisputerAdded(_disputer);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeDisputer(address _disputer) external override onlyGovernance {\n if (!disputers[_disputer]) revert DisputerUnexistent();\n delete disputers[_disputer];\n emit DisputerRemoved(_disputer);\n }\n\n /// @notice Functions with this modifier can only be called by either a slasher or governance\n modifier onlySlasher {\n if (!slashers[msg.sender]) revert OnlySlasher();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by either a disputer or governance\n modifier onlyDisputer {\n if (!disputers[msg.sender]) revert OnlyDisputer();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Governable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public override governance;\n\n /// @inheritdoc IGovernable\n address public override pendingGovernance;\n\n constructor(address _governance) {\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\n governance = _governance;\n }\n\n /// @inheritdoc IGovernable\n function setGovernance(address _governance) external override onlyGovernance {\n pendingGovernance = _governance;\n emit GovernanceProposal(_governance);\n }\n\n /// @inheritdoc IGovernable\n function acceptGovernance() external override onlyPendingGovernance {\n governance = pendingGovernance;\n delete pendingGovernance;\n emit GovernanceSet(governance);\n }\n\n /// @notice Functions with this modifier can only be called by governance\n modifier onlyGovernance {\n if (msg.sender != governance) revert OnlyGovernance();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernance\n modifier onlyPendingGovernance {\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\n _;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\n\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobMigration\n mapping(address => address) public override pendingJobMigrations;\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\n\n /// @inheritdoc IKeep3rJobMigration\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\n if (_fromJob == _toJob) revert JobMigrationImpossible();\n\n pendingJobMigrations[_fromJob] = _toJob;\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\n\n emit JobMigrationRequested(_fromJob, _toJob);\n }\n\n /// @inheritdoc IKeep3rJobMigration\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\n\n // force job credits update for both jobs\n _settleJobAccountance(_fromJob);\n _settleJobAccountance(_toJob);\n\n // migrate tokens\n while (_jobTokens[_fromJob].length() > 0) {\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\n _jobTokens[_fromJob].remove(_tokenToMigrate);\n _jobTokens[_toJob].add(_tokenToMigrate);\n }\n\n // migrate liquidities\n while (_jobLiquidities[_fromJob].length() > 0) {\n address _liquidity = _jobLiquidities[_fromJob].at(0);\n\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\n delete liquidityAmount[_fromJob][_liquidity];\n\n _jobLiquidities[_toJob].add(_liquidity);\n _jobLiquidities[_fromJob].remove(_liquidity);\n }\n\n // migrate job balances\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\n delete _jobPeriodCredits[_fromJob];\n\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\n delete _jobLiquidityCredits[_fromJob];\n\n // stop _fromJob from being a job\n delete rewardedAt[_fromJob];\n _jobs.remove(_fromJob);\n\n // delete unused data slots\n delete jobOwner[_fromJob];\n delete jobPendingOwner[_fromJob];\n delete _migrationCreatedAt[_fromJob][_toJob];\n delete pendingJobMigrations[_fromJob];\n\n emit JobMigrationSuccessful(_fromJob, _toJob);\n }\n}\n" + }, + "solidity/interfaces/IKeep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rHelperParameters.sol';\n\n/// @title Keep3rHelper contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelper is IKeep3rHelperParameters {\n // Errors\n\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\n error LiquidityPairInvalid();\n\n // Methods\n // solhint-enable func-name-mixedcase\n\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\n /// @param _eth The amount of ETH\n /// @return _amountOut The amount of KP3R\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\n\n /// @notice Returns the amount of KP3R the keeper has bonded\n /// @param _keeper The address of the keeper to check\n /// @return _amountBonded The amount of KP3R the keeper has bonded\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\n /// @param _keeper The address of the keeper to check\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\n\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\n /// @return _rewardBoost The reward boost that corresponds to the keeper\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\n\n /// @notice Given a pool address, returns the underlying tokens of the pair\n /// @param _pool Address of the correspondant pool\n /// @return _token0 Address of the first token of the pair\n /// @return _token1 Address of the second token of the pair\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\n\n /// @notice Defines the order of the tokens in the pair for twap calculations\n /// @param _pool Address of the correspondant pool\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\n\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\n /// @param _pool Address of the pool to observe\n /// @param _secondsAgo Array with time references to observe\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\n /// @return _success Boolean indicating if the observe call was succesfull\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n );\n\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\n /// @param _bonds Amount of bonded KP3R owned by the keeper\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\n /// @return _extra Amount of extra gas that should be added to the gas spent\n function getPaymentParams(uint256 _bonds)\n external\n view\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n );\n\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\n /// @param _liquidityAmount Amount of liquidity to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _kp3rAmount);\n\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\n /// @param _baseAmount Amount of token to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _quoteAmount);\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice Cooldown between withdrawals\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override nonReentrant {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n // KP3R shouldn't be used for direct token payments\n if (_token == keep3rV1) revert TokenUnallowed();\n uint256 _before = IERC20(_token).balanceOf(address(this));\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\n uint256 _tokenFee = (_received * fee) / _BASE;\n jobTokenCredits[_job][_token] += _received - _tokenFee;\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\n IERC20(_token).safeTransfer(governance, _tokenFee);\n _jobTokens[_job].add(_token);\n\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\n }\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external override nonReentrant onlyJobOwner(_job) {\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\n if (disputes[_job]) revert JobDisputed();\n\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_receiver, _amount);\n\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/IPairManager.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '../../libraries/FullMath.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice List of liquidities that are accepted in the system\n EnumerableSet.AddressSet internal _approvedLiquidities;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override rewardedAt;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override workedAt;\n\n /// @notice Tracks an address and returns its TickCache\n mapping(address => TickCache) internal _tick;\n\n // Views\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approvedLiquidities() external view override returns (address[] memory _list) {\n _list = _approvedLiquidities.values();\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n _periodCredits += _getReward(\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\n );\n }\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n\n // If the job was rewarded in the past 1 period time\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\n // If the job has period credits, update minted job credits to new twap\n _liquidityCredits = _periodCredits > 0\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\n } else {\n // Else return a full period worth of credits if current credits have expired\n _liquidityCredits = _periodCredits;\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n uint256 _cooldown = block.timestamp;\n\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\n // Will calculate cooldown if it outdated\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will calculate cooldown from last reward reference in this period\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\n } else {\n // Will calculate cooldown from last reward timestamp\n _cooldown -= rewardedAt[_job];\n }\n } else {\n // Will calculate cooldown from period start if expired\n _cooldown -= _period(block.timestamp);\n }\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\n\n if (_tick[_liquidity].period == lastPeriod) {\n // Will only ask for current period accumulator if liquidity is outdated\n uint32[] memory _secondsAgo = new uint32[](1);\n int56 previousTick = _tick[_liquidity].current;\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - previousTick;\n } else if (_tick[_liquidity].period < lastPeriod) {\n // Will ask for 2 accumulators if liquidity is expired\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n }\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Methods\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n _settleJobAccountance(_job);\n _jobLiquidityCredits[_job] += _amount;\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\n delete _liquidityPool[_liquidity];\n delete _isKP3RToken0[_liquidity];\n delete _tick[_liquidity];\n\n emit LiquidityRevocation(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override nonReentrant {\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\n if (!_jobs.contains(_job)) revert JobUnavailable();\n\n _jobLiquidities[_job].add(_liquidity);\n\n _settleJobAccountance(_job);\n\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\n liquidityAmount[_job][_liquidity] += _amount;\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlyJobOwner(_job) {\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\n pendingUnbonds[_job][_liquidity] += _amount;\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit Unbonding(_job, _liquidity, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external override onlyJobOwner(_job) {\n if (_receiver == address(0)) revert ZeroAddress();\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\n if (disputes[_job]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[_job][_liquidity];\n\n delete pendingUnbonds[_job][_liquidity];\n delete canWithdrawAfter[_job][_liquidity];\n\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\n }\n\n // Internal functions\n\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\n if (rewardedAt[_job] < _period(block.timestamp)) {\n // Will exit function if job has been rewarded in current period\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\n // Will reset job to period syncronicity if a full period passed without rewards\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] = _period(block.timestamp);\n _rewarded = true;\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will reset job's syncronicity if last reward was more than epoch ago\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] += rewardPeriodTime;\n _rewarded = true;\n } else if (workedAt[_job] < _period(block.timestamp)) {\n // First keeper on period has to update job accountance to current twaps\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\n // Updating job accountance does not reward job\n }\n }\n }\n\n /// @notice Only called if _jobLiquidityCredits < payment\n function _rewardJobCredits(address _job) internal {\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\n rewardedAt[_job] = block.timestamp;\n }\n\n /// @notice Updates accountance for _jobPeriodCredits\n function _updateJobPeriod(address _job) internal {\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\n }\n\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n if (_tick[_liquidity].period != _period(block.timestamp)) {\n // Updates liquidity cache only if needed\n _tick[_liquidity] = observeLiquidity(_liquidity);\n }\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\n }\n }\n }\n\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\n function _unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) internal nonReentrant {\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\n\n // Ensures current twaps in job liquidities\n _updateJobPeriod(_job);\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\n\n // A liquidity can be revoked causing a job to have 0 periodCredits\n if (_jobPeriodCredits[_job] > 0) {\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\n }\n\n liquidityAmount[_job][_liquidity] -= _amount;\n if (liquidityAmount[_job][_liquidity] == 0) {\n _jobLiquidities[_job].remove(_liquidity);\n }\n }\n\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\n if (_timePassed < rewardPeriodTime) {\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\n } else _result = _multiplier;\n }\n\n /// @notice Returns the start of the period of the provided timestamp\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\n return _timestamp - (_timestamp % rewardPeriodTime);\n }\n\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\n }\n\n /// @notice Returns underlying KP3R amount for a given liquidity amount\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\n if (_tick[_liquidity].period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\n }\n }\n\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\n /// @dev Ensures a maximum of 1 period of credits\n function _settleJobAccountance(address _job) internal virtual {\n _updateJobCreditsIfNeeded(_job);\n _rewardJobCredits(_job);\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/IKeep3rHelper.sol';\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\nimport './Keep3rAccountance.sol';\n\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1Proxy;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rHelper;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override bondTime = 3 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override unbondTime = 14 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override liquidityMinimum = 3 ether;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override rewardPeriodTime = 5 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override inflationPeriod = 34 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override fee = 30;\n\n /// @notice The base that will be used to calculate the fee\n uint256 internal constant _BASE = 10_000;\n\n /// @notice The minimum reward period\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) {\n keep3rHelper = _keep3rHelper;\n keep3rV1 = _keep3rV1;\n keep3rV1Proxy = _keep3rV1Proxy;\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\n if (_keep3rHelper == address(0)) revert ZeroAddress();\n keep3rHelper = _keep3rHelper;\n emit Keep3rHelperChange(_keep3rHelper);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\n if (_keep3rV1 == address(0)) revert ZeroAddress();\n _mint(totalBonds);\n\n keep3rV1 = _keep3rV1;\n emit Keep3rV1Change(_keep3rV1);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\n keep3rV1Proxy = _keep3rV1Proxy;\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\n bondTime = _bondTime;\n emit BondTimeChange(_bondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\n unbondTime = _unbondTime;\n emit UnbondTimeChange(_unbondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\n liquidityMinimum = _liquidityMinimum;\n emit LiquidityMinimumChange(_liquidityMinimum);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\n rewardPeriodTime = _rewardPeriodTime;\n emit RewardPeriodTimeChange(_rewardPeriodTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\n inflationPeriod = _inflationPeriod;\n emit InflationPeriodChange(_inflationPeriod);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setFee(uint256 _fee) external override onlyGovernance {\n fee = _fee;\n emit FeeChange(_fee);\n }\n\n function _mint(uint256 _amount) internal {\n totalBonds -= _amount;\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IGovernable.sol';\n\ninterface IKeep3rV1Proxy is IGovernable {\n // Structs\n struct Recipient {\n address recipient;\n uint256 caps;\n }\n\n // Variables\n function keep3rV1() external view returns (address);\n\n function minter() external view returns (address);\n\n function next(address) external view returns (uint256);\n\n function caps(address) external view returns (uint256);\n\n function recipients() external view returns (address[] memory);\n\n function recipientsCaps() external view returns (Recipient[] memory);\n\n // Errors\n error Cooldown();\n error NoDrawableAmount();\n error ZeroAddress();\n error OnlyMinter();\n\n // Methods\n function addRecipient(address recipient, uint256 amount) external;\n\n function removeRecipient(address recipient) external;\n\n function draw() external returns (uint256 _amount);\n\n function setKeep3rV1(address _keep3rV1) external;\n\n function setMinter(address _minter) external;\n\n function mint(uint256 _amount) external;\n\n function mint(address _account, uint256 _amount) external;\n\n function setKeep3rV1Governance(address _governance) external;\n\n function acceptKeep3rV1Governance() external;\n\n function dispute(address _keeper) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function addJob(address _job) external;\n\n function removeJob(address _job) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n}\n" + }, + "solidity/interfaces/IKeep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rHelperParameters contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelperParameters {\n // Structs\n\n /// @dev KP3R-WETH Pool address and isKP3RToken0\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\n struct TokenOraclePool {\n address poolAddress;\n bool isTKNToken0;\n }\n\n // Errors\n\n /// @notice Throws when pool does not have KP3R as token0 nor token1\n error InvalidOraclePool();\n\n // Events\n\n /// @notice Emitted when the kp3r weth pool is changed\n /// @param _address Address of the new kp3r weth pool\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\n\n /// @notice Emitted when the minimum boost multiplier is changed\n /// @param _minBoost The minimum boost multiplier\n event MinBoostChange(uint256 _minBoost);\n\n /// @notice Emitted when the maximum boost multiplier is changed\n /// @param _maxBoost The maximum boost multiplier\n event MaxBoostChange(uint256 _maxBoost);\n\n /// @notice Emitted when the target bond amount is changed\n /// @param _targetBond The target bond amount\n event TargetBondChange(uint256 _targetBond);\n\n /// @notice Emitted when the Keep3r V2 address is changed\n /// @param _keep3rV2 The address of Keep3r V2\n event Keep3rV2Change(address _keep3rV2);\n\n /// @notice Emitted when the work extra gas amount is changed\n /// @param _workExtraGas The work extra gas\n event WorkExtraGasChange(uint256 _workExtraGas);\n\n /// @notice Emitted when the quote twap time is changed\n /// @param _quoteTwapTime The twap time for quoting\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\n\n /// @notice Emitted when minimum rewarded gas fee is changed\n /// @param _minBaseFee The minimum rewarded gas fee\n event MinBaseFeeChange(uint256 _minBaseFee);\n\n /// @notice Emitted when minimum rewarded priority fee is changed\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\n event MinPriorityFeeChange(uint256 _minPriorityFee);\n\n // Variables\n\n /// @notice Address of KP3R token\n /// @return _kp3r Address of KP3R token\n // solhint-disable func-name-mixedcase\n function KP3R() external view returns (address _kp3r);\n\n /// @notice The boost base used to calculate the boost rewards for the keeper\n /// @return _base The boost base number\n function BOOST_BASE() external view returns (uint256 _base);\n\n /// @notice KP3R-WETH pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\n /// @return _multiplier The minimum boost multiplier\n function minBoost() external view returns (uint256 _multiplier);\n\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\n /// @return _multiplier The maximum boost multiplier\n function maxBoost() external view returns (uint256 _multiplier);\n\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\n /// @return _target The amount of KP3R that comforms the targetBond\n function targetBond() external view returns (uint256 _target);\n\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\n /// @return _workExtraGas The work unaccounted gas amount\n function workExtraGas() external view returns (uint256 _workExtraGas);\n\n /// @notice The twap time for quoting\n /// @return _quoteTwapTime The twap time\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\n\n /// @notice The minimum base fee that is used to calculate keeper rewards\n /// @return _minBaseFee The minimum rewarded gas fee\n function minBaseFee() external view returns (uint256 _minBaseFee);\n\n /// @notice The minimum priority fee that is also rewarded for keepers\n /// @return _minPriorityFee The minimum rewarded priority fee\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\n\n /// @notice Address of Keep3r V2\n /// @return _keep3rV2 Address of Keep3r V2\n function keep3rV2() external view returns (address _keep3rV2);\n\n // Methods\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function setKp3rWethPool(address _poolAddress) external;\n\n /// @notice Sets the minimum boost multiplier\n /// @param _minBoost The minimum boost multiplier\n function setMinBoost(uint256 _minBoost) external;\n\n /// @notice Sets the maximum boost multiplier\n /// @param _maxBoost The maximum boost multiplier\n function setMaxBoost(uint256 _maxBoost) external;\n\n /// @notice Sets the target bond amount\n /// @param _targetBond The target bond amount\n function setTargetBond(uint256 _targetBond) external;\n\n /// @notice Sets the Keep3r V2 address\n /// @param _keep3rV2 The address of Keep3r V2\n function setKeep3rV2(address _keep3rV2) external;\n\n /// @notice Sets the work extra gas amount\n /// @param _workExtraGas The work extra gas\n function setWorkExtraGas(uint256 _workExtraGas) external;\n\n /// @notice Sets the quote twap time\n /// @param _quoteTwapTime The twap time for quoting\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\n\n /// @notice Sets the minimum rewarded gas fee\n /// @param _minBaseFee The minimum rewarded gas fee\n function setMinBaseFee(uint256 _minBaseFee) external;\n\n /// @notice Sets the minimum rewarded gas priority fee\n /// @param _minPriorityFee The minimum rewarded priority fee\n function setMinPriorityFee(uint256 _minPriorityFee) external;\n}\n" + }, + "solidity/interfaces/IPairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n/// @title Pair Manager interface\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\ninterface IPairManager is IERC20Metadata {\n /// @notice Address of the factory from which the pair manager was created\n /// @return _factory The address of the PairManager Factory\n function factory() external view returns (address _factory);\n\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\n /// @return _pool The address of the pool\n function pool() external view returns (address _pool);\n\n /// @notice Token0 of the pool\n /// @return _token0 The address of token0\n function token0() external view returns (address _token0);\n\n /// @notice Token1 of the pool\n /// @return _token1 The address of token1\n function token1() external view returns (address _token1);\n}\n" + }, + "solidity/contracts/libraries/FullMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (~denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "solidity/contracts/peripherals/Keep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rParameters.sol';\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\n\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\n /// @inheritdoc IKeep3rDisputable\n function dispute(address _jobOrKeeper) external override onlyDisputer {\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\n disputes[_jobOrKeeper] = true;\n emit Dispute(_jobOrKeeper, msg.sender);\n }\n\n /// @inheritdoc IKeep3rDisputable\n function resolve(address _jobOrKeeper) external override onlyDisputer {\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\n disputes[_jobOrKeeper] = false;\n emit Resolve(_jobOrKeeper, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rKeeperFundable.sol';\nimport '../Keep3rDisputable.sol';\nimport '../../../interfaces/external/IKeep3rV1.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\n }\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function revoke(address _keeper) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _keepers.remove(_keeper);\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\n emit KeeperRevoke(_keeper, msg.sender);\n }\n\n function _slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) internal {\n if (_bonded != keep3rV1) {\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\n }\n bonds[_keeper][_bonded] -= _bondAmount;\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nimport '../../../interfaces/external/IKeep3rV1.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperFundable\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\n if (disputes[msg.sender]) revert Disputed();\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\n\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\n\n hasBonded[msg.sender] = true;\n pendingBonds[msg.sender][_bonding] += _amount;\n\n emit Bonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function activate(address _bonding) external override {\n address _keeper = msg.sender;\n if (disputes[_keeper]) revert Disputed();\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\n if (_canActivateAfter == 0) revert BondsUnexistent();\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\n\n if (firstSeen[_keeper] == 0) {\n firstSeen[_keeper] = block.timestamp;\n }\n _keepers.add(_keeper);\n\n uint256 _amount = pendingBonds[_keeper][_bonding];\n delete pendingBonds[_keeper][_bonding];\n\n // bond provided tokens\n bonds[_keeper][_bonding] += _amount;\n if (_bonding == keep3rV1) {\n totalBonds += _amount;\n _depositBonds(_amount);\n }\n\n emit Activation(_keeper, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function unbond(address _bonding, uint256 _amount) external override {\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\n bonds[msg.sender][_bonding] -= _amount;\n pendingUnbonds[msg.sender][_bonding] += _amount;\n\n emit Unbonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function withdraw(address _bonding) external override nonReentrant {\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\n if (disputes[msg.sender]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\n\n delete pendingUnbonds[msg.sender][_bonding];\n delete canWithdrawAfter[msg.sender][_bonding];\n\n if (_bonding == keep3rV1) _mint(_amount);\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(msg.sender, _bonding, _amount);\n }\n\n function _depositBonds(uint256 _amount) internal virtual {\n IKeep3rV1(keep3rV1).burn(_amount);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n// solhint-disable func-name-mixedcase\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\n // Structs\n struct Checkpoint {\n uint32 fromBlock;\n uint256 votes;\n }\n\n // Events\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event JobAdded(address indexed _job, uint256 _block, address _governance);\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\n event KeeperDispute(address indexed _keeper, uint256 _block);\n event KeeperResolved(address indexed _keeper, uint256 _block);\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\n\n // Variables\n function KPRH() external returns (address);\n\n function delegates(address _delegator) external view returns (address);\n\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\n\n function numCheckpoints(address _account) external view returns (uint32);\n\n function DOMAIN_TYPEHASH() external returns (bytes32);\n\n function DOMAINSEPARATOR() external returns (bytes32);\n\n function DELEGATION_TYPEHASH() external returns (bytes32);\n\n function PERMIT_TYPEHASH() external returns (bytes32);\n\n function nonces(address _user) external view returns (uint256);\n\n function BOND() external returns (uint256);\n\n function UNBOND() external returns (uint256);\n\n function LIQUIDITYBOND() external returns (uint256);\n\n function FEE() external returns (uint256);\n\n function BASE() external returns (uint256);\n\n function ETH() external returns (address);\n\n function bondings(address _user, address _bonding) external view returns (uint256);\n\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\n\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function bonds(address _keeper, address _bonding) external view returns (uint256);\n\n function votes(address _delegator) external view returns (uint256);\n\n function firstSeen(address _keeper) external view returns (uint256);\n\n function disputes(address _keeper) external view returns (bool);\n\n function lastJob(address _keeper) external view returns (uint256);\n\n function workCompleted(address _keeper) external view returns (uint256);\n\n function jobs(address _job) external view returns (bool);\n\n function credits(address _job, address _credit) external view returns (uint256);\n\n function liquidityProvided(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmountsUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function jobProposalDelay(address _job) external view returns (uint256);\n\n function liquidityApplied(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmount(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function keepers(address _keeper) external view returns (bool);\n\n function blacklist(address _keeper) external view returns (bool);\n\n function keeperList(uint256 _index) external view returns (address);\n\n function jobList(uint256 _index) external view returns (address);\n\n function governance() external returns (address);\n\n function pendingGovernance() external returns (address);\n\n function liquidityAccepted(address _liquidity) external view returns (bool);\n\n function liquidityPairs(uint256 _index) external view returns (address);\n\n // Methods\n function getCurrentVotes(address _account) external view returns (uint256);\n\n function addCreditETH(address _job) external payable;\n\n function addCredit(\n address _credit,\n address _job,\n uint256 _amount\n ) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function pairs() external view returns (address[] memory);\n\n function addLiquidityToJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function applyCreditToJob(\n address _provider,\n address _liquidity,\n address _job\n ) external;\n\n function unbondLiquidityFromJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function removeLiquidityFromJob(address _liquidity, address _job) external;\n\n function mint(uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n\n function worked(address _keeper) external;\n\n function receipt(\n address _credit,\n address _keeper,\n uint256 _amount\n ) external;\n\n function receiptETH(address _keeper, uint256 _amount) external;\n\n function addJob(address _job) external;\n\n function getJobs() external view returns (address[] memory);\n\n function removeJob(address _job) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function isKeeper(address _keeper) external returns (bool);\n\n function isMinKeeper(\n address _keeper,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function bond(address _bonding, uint256 _amount) external;\n\n function getKeepers() external view returns (address[] memory);\n\n function activate(address _bonding) external;\n\n function unbond(address _bonding, uint256 _amount) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function withdraw(address _bonding) external;\n\n function dispute(address _keeper) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function permit(\n address _owner,\n address _spender,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3r.sol';\n\ncontract Keep3rForTestnet is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3r.sol';\n\ncontract Keep3rForTest is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3r.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\n\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @param _governance Address of governance\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\n constructor(\n address _governance, // governance\n address _keep3rHelperSidechain, // helper\n address _wrappedKP3R, // keep3rV1\n address _keep3rEscrow // keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\n\n // Keep3rSidechainAccountance\n\n /// @inheritdoc IKeep3rSidechainAccountance\n function virtualReserves() external view override returns (int256 _virtualReserves) {\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\n }\n\n // Keep3rJobFundableLiquidity\n\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\n /// @param _liquidity Address of the liquidity token being approved\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\n /// @param _liquidity Address of the liquidity token being observed\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n\n // Will always ask for 2 accumulators in sidechain\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Keep3rJobsWorkable\n\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\n function worked(address) external pure override {\n revert Deprecated();\n }\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Uses a USD per gas unit payment mechanism\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\n if (_initialGas == 0) revert GasNotInitialized();\n // Gas used for quote calculations & payment is not rewarded\n uint256 _gasLeft = _getGasLeft();\n\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\n\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _kp3rPayment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\n }\n\n // Keep3rKeeperFundable\n\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\n function _depositBonds(uint256 _amount) internal virtual override {\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\n }\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// solhint-disable-next-line no-empty-blocks\n\nimport '../peripherals/IMintable.sol';\n\n/// @title Keep3rEscrow contract\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\ninterface IKeep3rEscrow is IMintable {\n /// @notice Emitted when Keep3rEscrow#deposit function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _sender The address that called the function\n /// @param _amount The amount of wKP3R the user deposited\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#mint function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _recipient The address that will received the newly minted wKP3R\n /// @param _amount The amount of wKP3R minted to the recipient\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\n /// @param _newWKP3R The address of the wKP3R contract\n event wKP3RSet(address _newWKP3R);\n\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\n error InsufficientBalance();\n\n /// @notice Lists the address of the wKP3R contract\n /// @return _wKP3RAddress The address of wKP3R\n function wKP3R() external view returns (address _wKP3RAddress);\n\n /// @notice Deposits wKP3R into the contract\n /// @param _amount The amount of wKP3R to deposit\n function deposit(uint256 _amount) external;\n\n /// @notice mints wKP3R to the recipient\n /// @param _amount The amount of wKP3R to mint\n function mint(uint256 _amount) external;\n\n /// @notice sets the wKP3R address\n /// @param _wKP3R the wKP3R address\n function setWKP3R(address _wKP3R) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../IKeep3rHelper.sol';\n\n/// @title Keep3rHelperSidechain contract\n/// @notice Contains all the helper functions for sidechain keep3r implementations\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\n // Events\n\n /// @notice The oracle for a liquidity has been saved\n /// @param _liquidity The address of the given liquidity\n /// @param _oraclePool The address of the oracle pool\n event OracleSet(address _liquidity, address _oraclePool);\n\n /// @notice Emitted when the WETH USD pool is changed\n /// @param _address Address of the new WETH USD pool\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\n\n /// Variables\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n /// @return _weth Address of WETH token\n // solhint-disable func-name-mixedcase\n function WETH() external view returns (address _weth);\n\n /// @return _oracle The address of the observable pool for given liquidity\n function oracle(address _liquidity) external view returns (address _oracle);\n\n /// @notice WETH-USD pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice Quotes USD to ETH\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\n /// @param _usd The amount of USD to quote to ETH\n /// @return _eth The resulting amount of ETH after quoting the USD\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\n\n /// Methods\n\n /// @notice Sets an oracle for a given liquidity\n /// @param _liquidity The address of the liquidity\n /// @param _oracle The address of the pool used to quote the liquidity from\n /// @dev The oracle must contain KP3R as either token0 or token1\n function setOracle(address _liquidity, address _oracle) external;\n\n /// @notice Sets an oracle for querying WETH/USD quote\n /// @param _poolAddress The address of the pool used as oracle\n /// @dev The oracle must contain WETH as either token0 or token1\n function setWethUsdPool(address _poolAddress) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IKeep3rJobs.sol';\n\n/// @title Keep3rJobWorkableRated contract\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\n /// @notice Throws when job contract calls deprecated worked(address) function\n error Deprecated();\n\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title IKeep3rSidechainAccountance interface\n/// @notice Implements a view to get the amount of credits that can be withdrawn\ninterface IKeep3rSidechainAccountance {\n /// @notice The surplus amount of wKP3Rs in escrow contract\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\n function virtualReserves() external view returns (int256 _virtualReserves);\n}\n" + }, + "solidity/interfaces/peripherals/IMintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IGovernable.sol';\nimport './IBaseErrors.sol';\n\n/// @title Mintable contract\n/// @notice Manages the minter role\ninterface IMintable is IBaseErrors, IGovernable {\n // Events\n\n /// @notice Emitted when governance sets a new minter\n /// @param _minter Address of the new minter\n event MinterSet(address _minter);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not the minter\n error OnlyMinter();\n\n // Variables\n\n /// @notice Stores the minter address\n /// @return _minter The minter addresss\n function minter() external view returns (address _minter);\n\n // Methods\n\n /// @notice Sets a new address to be the minter\n /// @param _minter The address set as the minter\n function setMinter(address _minter) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rSidechainForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTest is Keep3rSidechain {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _governance,\n address _keep3rHelper,\n address _wrappedKP3R,\n address _keep3rEscrow\n ) Keep3rSidechain(_governance, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n}\n" + }, + "solidity/for-test/JobRatedForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\n\ncontract JobRatedForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n uint256 public usdPerGasUnit = 1_000e9;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n}\n" + }, + "solidity/for-test/JobForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract JobForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/for-test/BasicJob.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract BasicJob {\n error KeeperNotValid();\n\n address public keep3r;\n uint256 public nonce;\n uint256[] public array;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external upkeep {}\n\n function workHard(uint256 _howHard) external upkeep {\n for (uint256 i = nonce; i < _howHard; i++) {\n nonce++;\n }\n }\n\n function workRefund(uint256 _howHard) external upkeep {\n for (uint256 i; i < _howHard; i++) {\n array.push(i);\n }\n\n while (array.length > 0) {\n array.pop();\n }\n }\n\n modifier upkeep() {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\n _;\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/peripherals/IBaseErrors.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/external/IKeep3rV1.sol';\nimport '../interfaces/IKeep3rHelperParameters.sol';\nimport './peripherals/Governable.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\n /// @inheritdoc IKeep3rHelperParameters\n address public immutable override KP3R;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public constant override BOOST_BASE = 10_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBoost = 11_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override maxBoost = 12_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override targetBond = 200 ether;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override workExtraGas = 34_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint32 public override quoteTwapTime = 10 minutes;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBaseFee = 15e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minPriorityFee = 2e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n address public override keep3rV2;\n\n /// @inheritdoc IKeep3rHelperParameters\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Governable(_governance) {\n KP3R = _kp3r;\n keep3rV2 = _keep3rV2;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setKp3rWethPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\n minBoost = _minBoost;\n emit MinBoostChange(minBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\n maxBoost = _maxBoost;\n emit MaxBoostChange(maxBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\n targetBond = _targetBond;\n emit TargetBondChange(targetBond);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\n if (_keep3rV2 == address(0)) revert ZeroAddress();\n keep3rV2 = _keep3rV2;\n emit Keep3rV2Change(keep3rV2);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\n workExtraGas = _workExtraGas;\n emit WorkExtraGasChange(workExtraGas);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\n _setQuoteTwapTime(_quoteTwapTime);\n }\n\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\n quoteTwapTime = _quoteTwapTime;\n emit QuoteTwapTimeChange(quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\n minBaseFee = _minBaseFee;\n emit MinBaseFeeChange(minBaseFee);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\n minPriorityFee = _minPriorityFee;\n emit MinPriorityFeeChange(minPriorityFee);\n }\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function _setKp3rWethPool(address _poolAddress) internal {\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\n\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\n\n return TokenOraclePool(_poolAddress, _isTKNToken0);\n }\n}\n" + }, + "solidity/contracts/libraries/TickMath.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n// solhint-disable\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n // Second inequality must be < because the price can never reach the price at the max tick\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport './pool/IUniswapV3PoolImmutables.sol';\nimport './pool/IUniswapV3PoolState.sol';\nimport './pool/IUniswapV3PoolDerivedState.sol';\nimport './pool/IUniswapV3PoolActions.sol';\nimport './pool/IUniswapV3PoolOwnerActions.sol';\nimport './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolEvents\n{\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// observationIndex The index of the last oracle observation that was written,\n /// observationCardinality The current maximum number of observations stored in the pool,\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper,\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return _liquidity The amount of liquidity in the position,\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 _liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// Returns initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" + }, + "solidity/for-test/UniV3PairManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport '../contracts/libraries/LiquidityAmounts.sol';\nimport '../contracts/libraries/FixedPoint96.sol';\nimport '../contracts/libraries/FullMath.sol';\nimport '../contracts/libraries/TickMath.sol';\nimport '../contracts/UniV3PairManager.sol';\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManagerForTest is UniV3PairManager {\n constructor(address _pool, address _governance) UniV3PairManager(_pool, _governance) {}\n\n function internalAddLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n external\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n return _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n }\n\n function internalPay(\n address token,\n address payer,\n address recipient,\n uint256 value\n ) external {\n return _pay(token, payer, recipient, value);\n }\n\n function internalMint(address dst, uint256 amount) external {\n return _mint(dst, amount);\n }\n\n function internalBurn(address dst, uint256 amount) external {\n return _burn(dst, amount);\n }\n\n function internalTransferTokens(\n address src,\n address dst,\n uint256 amount\n ) external {\n _transferTokens(src, dst, amount);\n }\n\n function internalSafeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) external {\n _safeTransferFrom(token, from, to, value);\n }\n\n receive() external payable {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "solidity/contracts/libraries/LiquidityAmounts.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport './FullMath.sol';\nimport './FixedPoint96.sol';\n\n// solhint-disable\nlibrary LiquidityAmounts {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/contracts/libraries/FixedPoint96.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nlibrary FixedPoint96 {\n // solhint-disable\n uint8 internal constant RESOLUTION = 96;\n uint256 internal constant Q96 = 0x1000000000000000000000000;\n}\n" + }, + "solidity/contracts/UniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport './libraries/LiquidityAmounts.sol';\nimport './libraries/FixedPoint96.sol';\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\n\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\nimport './peripherals/Governable.sol';\n\ncontract UniV3PairManager is IUniV3PairManager, Governable {\n /// @inheritdoc IERC20Metadata\n string public override name;\n\n /// @inheritdoc IERC20Metadata\n string public override symbol;\n\n /// @inheritdoc IERC20\n uint256 public override totalSupply;\n\n /// @inheritdoc IPairManager\n address public immutable override factory;\n\n /// @inheritdoc IPairManager\n address public immutable override token0;\n\n /// @inheritdoc IPairManager\n address public immutable override token1;\n\n /// @inheritdoc IPairManager\n address public immutable override pool;\n\n /// @inheritdoc IUniV3PairManager\n uint24 public immutable override fee;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioAX96;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioBX96;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickLower;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickUpper;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickSpacing;\n\n /// @notice Uniswap's maximum tick\n /// @dev Due to tick spacing, pools with different fees may have differences between _MAX_TICK and tickUpper. Use tickUpper to find the max tick of the pool.\n int24 private constant _MAX_TICK = 887272;\n\n /// @inheritdoc IERC20Metadata\n //solhint-disable-next-line const-name-snakecase\n uint8 public constant override decimals = 18;\n\n /// @inheritdoc IERC20\n mapping(address => mapping(address => uint256)) public override allowance;\n\n /// @inheritdoc IERC20\n mapping(address => uint256) public override balanceOf;\n\n /// @notice Struct that contains token0, token1, and fee of the Uniswap pool\n PoolKey private _poolKey;\n\n constructor(address _pool, address _governance) Governable(_governance) {\n uint24 _fee = IUniswapV3Pool(_pool).fee();\n address _token0 = IUniswapV3Pool(_pool).token0();\n address _token1 = IUniswapV3Pool(_pool).token1();\n int24 _tickSpacing = IUniswapV3Pool(_pool).tickSpacing();\n int24 _tickUpper = _MAX_TICK - (_MAX_TICK % _tickSpacing);\n int24 _tickLower = -_tickUpper;\n\n factory = msg.sender;\n pool = _pool;\n fee = _fee;\n tickSpacing = _tickSpacing;\n tickUpper = _tickUpper;\n tickLower = _tickLower;\n token0 = _token0;\n token1 = _token1;\n name = string(abi.encodePacked('Keep3rLP - ', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n symbol = string(abi.encodePacked('kLP-', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n\n sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(_tickLower);\n sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(_tickUpper);\n _poolKey = PoolKey({token0: _token0, token1: _token1, fee: _fee});\n }\n\n // This low-level function should be called from a contract which performs important safety checks\n /// @inheritdoc IUniV3PairManager\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint128 liquidity) {\n (liquidity, , ) = _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n _mint(to, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external override {\n MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));\n if (msg.sender != pool) revert OnlyPool();\n if (amount0Owed > 0) _pay(decoded._poolKey.token0, decoded.payer, pool, amount0Owed);\n if (amount1Owed > 0) _pay(decoded._poolKey.token1, decoded.payer, pool, amount1Owed);\n }\n\n /// @inheritdoc IUniV3PairManager\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint256 amount0, uint256 amount1) {\n (amount0, amount1) = IUniswapV3Pool(pool).burn(tickLower, tickUpper, liquidity);\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n\n IUniswapV3Pool(pool).collect(to, tickLower, tickUpper, uint128(amount0), uint128(amount1));\n _burn(msg.sender, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function collect() external override onlyGovernance returns (uint256 amount0, uint256 amount1) {\n (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n (amount0, amount1) = IUniswapV3Pool(pool).collect(governance, tickLower, tickUpper, tokensOwed0, tokensOwed1);\n }\n\n /// @inheritdoc IUniV3PairManager\n function position()\n external\n view\n override\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n )\n {\n (liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128, tokensOwed0, tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n }\n\n /// @inheritdoc IERC20\n function approve(address spender, uint256 amount) external override returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transfer(address to, uint256 amount) external override returns (bool) {\n _transferTokens(msg.sender, to, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool) {\n address spender = msg.sender;\n uint256 spenderAllowance = allowance[from][spender];\n\n if (spender != from && spenderAllowance != type(uint256).max) {\n uint256 newAllowance = spenderAllowance - amount;\n allowance[from][spender] = newAllowance;\n\n emit Approval(from, spender, newAllowance);\n }\n\n _transferTokens(from, to, amount);\n return true;\n }\n\n /// @notice Adds liquidity to an initialized pool\n /// @dev Reverts if the returned amount0 is less than amount0Min or if amount1 is less than amount1Min\n /// @dev This function calls the mint function of the corresponding Uniswap pool, which in turn calls UniswapV3Callback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @return liquidity The calculated liquidity we get for the token amounts we provided\n /// @return amount0 The amount of token0 we ended up providing\n /// @return amount1 The amount of token1 we ended up providing\n function _addLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n internal\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(pool).slot0();\n\n liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, amount0Desired, amount1Desired);\n\n (amount0, amount1) = IUniswapV3Pool(pool).mint(\n address(this),\n tickLower,\n tickUpper,\n liquidity,\n abi.encode(MintCallbackData({_poolKey: _poolKey, payer: msg.sender}))\n );\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n }\n\n /// @notice Transfers the passed-in token from the payer to the recipient for the corresponding value\n /// @param token The token to be transferred to the recipient\n /// @param from The address of the payer\n /// @param to The address of the passed-in tokens recipient\n /// @param value How much of that token to be transferred from payer to the recipient\n function _pay(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n _safeTransferFrom(token, from, to, value);\n }\n\n /// @notice Mints Keep3r credits to the passed-in address of recipient and increases total supply of Keep3r credits by the corresponding amount\n /// @param to The recipient of the Keep3r credits\n /// @param amount The amount Keep3r credits to be minted to the recipient\n function _mint(address to, uint256 amount) internal {\n totalSupply += amount;\n balanceOf[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @notice Burns Keep3r credits to the passed-in address of recipient and reduces total supply of Keep3r credits by the corresponding amount\n /// @param to The address that will get its Keep3r credits burned\n /// @param amount The amount Keep3r credits to be burned from the recipient/recipient\n function _burn(address to, uint256 amount) internal {\n totalSupply -= amount;\n balanceOf[to] -= amount;\n emit Transfer(to, address(0), amount);\n }\n\n /// @notice Transfers amount of Keep3r credits between two addresses\n /// @param from The user that transfers the Keep3r credits\n /// @param to The user that receives the Keep3r credits\n /// @param amount The amount of Keep3r credits to be transferred\n function _transferTokens(\n address from,\n address to,\n uint256 amount\n ) internal {\n balanceOf[from] -= amount;\n balanceOf[to] += amount;\n\n emit Transfer(from, to, amount);\n }\n\n /// @notice Transfers the passed-in token from the specified \"from\" to the specified \"to\" for the corresponding value\n /// @dev Reverts with IUniV3PairManager#UnsuccessfulTransfer if the transfer was not successful,\n /// or if the passed data length is different than 0 and the decoded data is not a boolean\n /// @param token The token to be transferred to the specified \"to\"\n /// @param from The address which is going to transfer the tokens\n /// @param value How much of that token to be transferred from \"from\" to \"to\"\n function _safeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert UnsuccessfulTransfer();\n }\n}\n" + }, + "solidity/interfaces/external/IWeth9.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IWeth9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256) external;\n}\n" + }, + "solidity/interfaces/IUniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IPairManager.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\nimport './peripherals/IGovernable.sol';\n\n/// @title Pair Manager contract\n/// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner\n/// so that the user can use it as liquidity for a Keep3rJob\ninterface IUniV3PairManager is IGovernable, IPairManager {\n // Structs\n struct PoolKey {\n address token0;\n address token1;\n uint24 fee;\n }\n\n /// @notice The data to be decoded by the UniswapV3MintCallback function\n struct MintCallbackData {\n PoolKey _poolKey; // Struct that contains token0, token1, and fee of the pool passed into the constructor\n address payer; // The address of the payer, which will be the msg.sender of the mint function\n }\n\n // Variables\n\n /// @notice The fee of the Uniswap pool passed into the constructor\n /// @return _fee The fee of the Uniswap pool passed into the constructor\n function fee() external view returns (uint24 _fee);\n\n /// @notice Highest tick in the Uniswap's curve\n /// @return _tickUpper The highest tick in the Uniswap's curve\n function tickUpper() external view returns (int24 _tickUpper);\n\n /// @notice Lowest tick in the Uniswap's curve\n /// @return _tickLower The lower tick in the Uniswap's curve\n function tickLower() external view returns (int24 _tickLower);\n\n /// @notice The pair tick spacing\n /// @return _tickSpacing The pair tick spacing\n function tickSpacing() external view returns (int24 _tickSpacing);\n\n /// @notice The sqrtRatioAX96 at the lowest tick (-887200) of the Uniswap pool\n /// @return _sqrtPriceA96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the lowest tick\n function sqrtRatioAX96() external view returns (uint160 _sqrtPriceA96);\n\n /// @notice The sqrtRatioBX96 at the highest tick (887200) of the Uniswap pool\n /// @return _sqrtPriceBX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the highest tick\n function sqrtRatioBX96() external view returns (uint160 _sqrtPriceBX96);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the pool\n error OnlyPool();\n\n /// @notice Throws when the slippage exceeds what the user is comfortable with\n error ExcessiveSlippage();\n\n /// @notice Throws when a transfer is unsuccessful\n error UnsuccessfulTransfer();\n\n // Methods\n\n /// @notice This function is called after a user calls IUniV3PairManager#mint function\n /// It ensures that any tokens owed to the pool are paid by the msg.sender of IUniV3PairManager#mint function\n /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity\n /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity\n /// @param data The encoded token0, token1, fee (_poolKey) and the payer (msg.sender) of the IUniV3PairManager#mint function\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external;\n\n /// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool\n /// @dev Triggers UniV3PairManager#uniswapV3MintCallback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @param to The address to which the kLP tokens are going to be minted to\n /// @return liquidity kLP tokens sent in exchange for the provision of tokens\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint128 liquidity);\n\n /// @notice Returns the pair manager's position in the corresponding UniswapV3 pool\n /// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager\n /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position\n /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position\n /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation\n /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation\n function position()\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees\n // owed to a specific position to the recipient, in this case, that recipient is the pair manager\n /// @dev The collected fees will be sent to governance\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect() external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity\n // in the entire range\n /// @param liquidity The amount of liquidity to be burned\n /// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)\n /// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)\n /// @param to The address that will receive the due fees\n /// @return amount0 The calculated amount of token0 that will be sent to the recipient\n /// @return amount1 The calculated amount of token1 that will be sent to the recipient\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint256 amount0, uint256 amount1);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "solidity/interfaces/IPairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IGovernable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ninterface IPairManagerFactory is IGovernable {\n // Variables\n\n /// @notice Maps the address of a Uniswap pool, to the address of the corresponding PairManager\n /// For example, the uniswap address of DAI-WETH, will return the Keep3r/DAI-WETH pair manager address\n /// @param _pool The address of the Uniswap pool\n /// @return _pairManager The address of the corresponding pair manager\n function pairManagers(address _pool) external view returns (address _pairManager);\n\n // Events\n\n /// @notice Emitted when a new pair manager is created\n /// @param _pool The address of the corresponding Uniswap pool\n /// @param _pairManager The address of the just-created pair manager\n event PairCreated(address _pool, address _pairManager);\n\n // Errors\n\n /// @notice Throws an error if the pair manager is already initialized\n error AlreadyInitialized();\n\n /// @notice Throws an error if the caller is not the owner\n error OnlyOwner();\n\n // Methods\n\n /// @notice Creates a new pair manager based on the address of a Uniswap pool\n /// For example, the uniswap address of DAI-WETH, will create the Keep3r/DAI-WETH pool\n /// @param _pool The address of the Uniswap pool the pair manager will be based of\n /// @return _pairManager The address of the just-created pair manager\n function createPairManager(address _pool) external returns (address _pairManager);\n}\n" + }, + "solidity/contracts/UniV3PairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IPairManagerFactory.sol';\nimport './UniV3PairManager.sol';\nimport './peripherals/Governable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ncontract UniV3PairManagerFactory is IPairManagerFactory, Governable {\n mapping(address => address) public override pairManagers;\n\n constructor(address _governance) Governable(_governance) {}\n\n ///@inheritdoc IPairManagerFactory\n function createPairManager(address _pool) external override returns (address _pairManager) {\n if (pairManagers[_pool] != address(0)) revert AlreadyInitialized();\n _pairManager = address(new UniV3PairManager(_pool, governance));\n pairManagers[_pool] = _pairManager;\n emit PairCreated(_pool, _pairManager);\n }\n}\n" + }, + "solidity/for-test/peripherals/GovernableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" + }, + "solidity/for-test/BridgeForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ncontract BridgeForTest is ERC20 {\n address public immutable kp3r;\n\n constructor(address _kp3r) ERC20('Wrapped KP3R', 'wKP3R') {\n kp3r = _kp3r;\n }\n\n function bridge(uint256 _amount) external {\n IERC20(kp3r).transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n }\n\n function bridgeBack(uint256 _amount) external {\n _burn(msg.sender, _amount);\n IERC20(kp3r).transfer(msg.sender, _amount);\n }\n}\n" + }, + "solidity/for-test/ERC20ForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(uint256 _amount) public {\n _mint(msg.sender, _amount);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(uint256 _amount) public {\n _burn(msg.sender, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n function deposit() external payable {\n // Function added for compatibility with WETH\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperFundableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperFundable.sol';\n\ncontract Keep3rKeeperFundableForTest is Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function isKeeper(address _keeper) external view returns (bool) {\n return _keepers.contains(_keeper);\n }\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/Mintable.sol';\nimport '../peripherals/DustCollector.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rEscrow\n address public override wKP3R;\n\n /// @param _governance Address of governance\n /// @param _wKP3R Address of wrapped KP3R implementation\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\n wKP3R = _wKP3R;\n }\n\n /// @inheritdoc IKeep3rEscrow\n function deposit(uint256 _amount) external override {\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function mint(uint256 _amount) external override onlyMinter {\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function setWKP3R(address _wKP3R) external override onlyGovernance {\n if (_wKP3R == address(0)) revert ZeroAddress();\n wKP3R = _wKP3R;\n emit wKP3RSet(wKP3R);\n }\n}\n" + }, + "solidity/contracts/peripherals/Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IMintable.sol';\nimport './Governable.sol';\n\nabstract contract Mintable is Governable, IMintable {\n /// @inheritdoc IMintable\n address public override minter;\n\n constructor(address _governance) Governable(_governance) {}\n\n /// @inheritdoc IMintable\n function setMinter(address _minter) external override onlyGovernance {\n if (_minter == address(0)) revert ZeroAddress();\n minter = _minter;\n emit MinterSet(_minter);\n }\n\n /// @notice Functions with this modifier can only be called by the minter;\n modifier onlyMinter() {\n if (msg.sender != minter) revert OnlyMinter();\n _;\n }\n}\n" + }, + "solidity/for-test/peripherals/DustCollectorForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/DustCollector.sol';\n\ncontract DustCollectorForTest is DustCollector {\n constructor() DustCollector() Governable(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rAccountanceForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rAccountance.sol';\n\ncontract Keep3rAccountanceForTest is Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor() Keep3rRoles(msg.sender) {}\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n\n function setKeeper(address keeper) external {\n _keepers.add(keeper);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableLiquidityForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol';\n\ncontract Keep3rJobFundableLiquidityForTest is Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external returns (bool) {\n return _jobLiquidities[_job].add(_liquidity);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewTickOrder(address _liquidity) external view returns (bool) {\n return _isKP3RToken0[_liquidity];\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function internalSettleJobAccountance(address _job) external {\n _settleJobAccountance(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobDisputable.sol';\n\ncontract Keep3rJobDisputableForTest is Keep3rJobDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function internalJobLiquidityCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobLiquidityCredits[_job];\n }\n\n function internalJobPeriodCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobPeriodCredits[_job];\n }\n\n function internalJobTokens(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobTokens[_job].length());\n for (uint256 i; i < _jobTokens[_job].length(); i++) {\n _tokens[i] = _jobTokens[_job].at(i);\n }\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobLiquidities[_job].length());\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n _tokens[i] = _jobLiquidities[_job].at(i);\n }\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rDisputable.sol';\n\ncontract Keep3rDisputableForTest is Keep3rDisputable {\n constructor() Keep3rParameters(address(0), address(0), address(0)) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperDisputable.sol';\n\ncontract Keep3rKeeperDisputableForTest is Keep3rKeeperDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function internalSlash(\n address _bonded,\n address _keeper,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external {\n _slash(_bonded, _keeper, _bondAmount, _unbondAmount);\n }\n\n function isKeeper(address _address) external view returns (bool _isKeeper) {\n _isKeeper = _keepers.contains(_address);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableCreditsForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableCredits.sol';\n\ncontract Keep3rJobFundableCreditsForTest is Keep3rJobFundableCredits {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job, address _jobOwner) external {\n _jobs.add(_job);\n jobOwner[_job] = _jobOwner;\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function isJobToken(address _job, address _token) external view returns (bool _contains) {\n _contains = _jobTokens[_job].contains(_token);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/IKeep3rHelper.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n /// @inheritdoc IKeep3rHelper\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelper\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\n // solhint-disable-next-line avoid-tx-origin\n return getRewardAmountFor(tx.origin, _gasUsed);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\n _bonds = Math.min(_bonds, targetBond);\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\n _rewardBoost = _cap * _getBasefee();\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\n }\n\n /// @inheritdoc IKeep3rHelper\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\n address _token0;\n address _token1;\n (_token0, _token1) = getPoolTokens(_pool);\n if (_token0 == KP3R) {\n return true;\n } else if (_token1 != KP3R) {\n revert LiquidityPairInvalid();\n }\n }\n\n /// @inheritdoc IKeep3rHelper\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n override\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n )\n {\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\n _tickCumulative1 = _uniswapResponse[0];\n if (_uniswapResponse.length > 1) {\n _tickCumulative2 = _uniswapResponse[1];\n }\n _success = true;\n } catch (bytes memory) {}\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n )\n {\n _oneEthQuote = quote(1 ether);\n _boost = getRewardBoostFor(_bonds);\n _extra = workExtraGas;\n }\n\n /// @inheritdoc IKeep3rHelper\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure override returns (uint256 _kp3rAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) public pure override returns (uint256 _quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\n }\n }\n\n /// @notice Gets the gas basefee cost to calculate keeper rewards\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTestnet is Keep3rHelper {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal pure override returns (uint256) {\n return 1;\n }\n\n /// @dev Overrides oracle validation that uses KP3R and WETH addresses\n function _validateOraclePool(address _poolAddress, address) internal view virtual override returns (TokenOraclePool memory _oraclePool) {\n return TokenOraclePool(_poolAddress, true);\n }\n\n /// @dev Overrides token comparison with KP3R address\n function isKP3RToken0(address) public view virtual override returns (bool) {\n return true;\n }\n}\n" + }, + "solidity/for-test/Keep3rHelperForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTest is Keep3rHelper {\n uint256 public basefee;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal view override returns (uint256) {\n return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee();\n }\n\n function setBaseFee(uint256 _baseFee) external {\n basefee = _baseFee;\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rHelper.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\n /// @inheritdoc IKeep3rHelperSidechain\n mapping(address => address) public override oracle;\n /// @inheritdoc IKeep3rHelperSidechain\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n address public immutable override WETH;\n\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\n /// @param _governance Address of governance\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\n /// @dev Oracle pools should use 18 decimals tokens\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\n WETH = _weth;\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\n _setQuoteTwapTime(1 days);\n workExtraGas = 0;\n }\n\n /// @inheritdoc IKeep3rHelper\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\n oracle[_liquidity] = _oracle;\n emit OracleSet(_liquidity, _oracle);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n /// @dev Oracle is compatible with IUniswapV3Pool\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setWethUsdPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override(Keep3rHelper, IKeep3rHelper)\n returns (\n uint256 _boost,\n uint256 _oneUsdQuote,\n uint256 _extraGas\n )\n {\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\n _boost = getRewardBoostFor(_bonds);\n _extraGas = workExtraGas;\n }\n\n function _setWethUsdPool(address _poolAddress) internal {\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\n }\n\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechainForTestnet is Keep3rHelperSidechain {\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelperSidechain(_keep3rV2, _governance, _kp3r, _weth, _kp3rWethOracle, _wethUsdOracle) {}\n\n /// @dev Overrides oracle validation that uses KP3R and WETH addresses\n function _validateOraclePool(address _poolAddress, address) internal view virtual override returns (TokenOraclePool memory _oraclePool) {\n return TokenOraclePool(_poolAddress, true);\n }\n\n /// @dev Overrides token comparison with KP3R address\n function isKP3RToken0(address) public view virtual override returns (bool) {\n return true;\n }\n\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256) {\n return _usd / 1000;\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rParametersForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rParameters.sol';\n\ncontract Keep3rParametersForTest is Keep3rParameters {\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobWorkableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobWorkable.sol';\n\ncontract Keep3rJobWorkableForTest is Keep3rJobWorkable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewGas() external view returns (uint256) {\n return _initialGas;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobMigrationForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobMigration.sol';\n\ncontract Keep3rJobMigrationForTest is Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(address => uint256) public settleJobAccountanceCallCount;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobTokenListLength(address _job) external view returns (uint256) {\n return _jobTokens[_job].length();\n }\n\n function viewJobLiquidityList(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewMigrationCreatedAt(address _fromJob, address _toJob) external view returns (uint256) {\n return _migrationCreatedAt[_fromJob][_toJob];\n }\n\n function isJob(address _job) external view returns (bool) {\n return _jobs.contains(_job);\n }\n\n function _settleJobAccountance(address _job) internal override {\n settleJobAccountanceCallCount[_job]++;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobManager.sol';\n\ncontract Keep3rJobManagerForTest is Keep3rJobManager {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rRoles(msg.sender) {}\n\n function isJob(address _job) external view returns (bool _isJob) {\n _isJob = _jobs.contains(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobOwnershipForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobOwnership.sol';\n\ncontract Keep3rJobOwnershipForTest is Keep3rJobOwnership {}\n" + }, + "solidity/for-test/libraries/LiquidityAmountsForTest.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/libraries/FullMath.sol';\nimport '../../contracts/libraries/FixedPoint96.sol';\n\n/// @dev Made this library into a contract to be able to calculate liquidity more precisely for tests\n\n// solhint-disable\ncontract LiquidityAmountsForTest {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) external pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) external pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/for-test/IUniswapV3PoolForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n// solhint-disable-next-line no-empty-blocks\ninterface IUniswapV3PoolForTest is IERC20Minimal, IUniswapV3Pool {\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Minimal ERC20 interface for Uniswap\n/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3\ninterface IERC20Minimal {\n /// @notice Returns the balance of a token\n /// @param account The account for which to look up the number of tokens it has, i.e. its balance\n /// @return The number of tokens held by the account\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Transfers the amount of token from the `msg.sender` to the recipient\n /// @param recipient The account that will receive the amount transferred\n /// @param amount The number of tokens to send from the sender to the recipient\n /// @return Returns true for a successful transfer, false for an unsuccessful transfer\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /// @notice Returns the current allowance given to a spender by an owner\n /// @param owner The account of the token owner\n /// @param spender The account of the token spender\n /// @return The current allowance granted by `owner` to `spender`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`\n /// @param spender The account which will be allowed to spend a given amount of the owners tokens\n /// @param amount The amount of tokens allowed to be used by `spender`\n /// @return Returns true for a successful approval, false for unsuccessful\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`\n /// @param sender The account from which the transfer will be initiated\n /// @param recipient The recipient of the transfer\n /// @param amount The amount of the transfer\n /// @return Returns true for a successful transfer, false for unsuccessful\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.\n /// @param from The account from which the tokens were sent, i.e. the balance decreased\n /// @param to The account to which the tokens were sent, i.e. the balance increased\n /// @param value The amount of tokens that were transferred\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.\n /// @param owner The account that approved spending of its tokens\n /// @param spender The account for which the spending allowance was modified\n /// @param value The new allowance from the owner to the spender\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 33 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimisticGoerli/solcInputs/f7e3e740337524d02345ab2e7585c15c.json b/deployments/optimisticGoerli/solcInputs/f7e3e740337524d02345ab2e7585c15c.json new file mode 100644 index 0000000..e7e246e --- /dev/null +++ b/deployments/optimisticGoerli/solcInputs/f7e3e740337524d02345ab2e7585c15c.json @@ -0,0 +1,334 @@ +{ + "language": "Solidity", + "sources": { + "solidity/contracts/Keep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport './peripherals/jobs/Keep3rJobs.sol';\nimport './peripherals/keepers/Keep3rKeepers.sol';\nimport './peripherals/DustCollector.sol';\n\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {}\n}\n" + }, + "solidity/interfaces/IKeep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobManager.sol';\nimport './Keep3rJobWorkable.sol';\nimport './Keep3rJobDisputable.sol';\n\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\nimport './Keep3rKeeperDisputable.sol';\n\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\n" + }, + "solidity/contracts/peripherals/DustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '../../contracts/peripherals/Governable.sol';\nimport '../../interfaces/peripherals/IDustCollector.sol';\n\nabstract contract DustCollector is IDustCollector, Governable {\n using SafeERC20 for IERC20;\n\n address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external override onlyGovernance {\n if (_to == address(0)) revert ZeroAddress();\n if (_token == _ETH_ADDRESS) {\n payable(_to).transfer(_amount);\n } else {\n IERC20(_token).safeTransfer(_to, _amount);\n }\n emit DustSent(_token, _amount, _to);\n }\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governance or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governance or a slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governance to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governance when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governance to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governance to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\nimport './IGovernable.sol';\nimport './IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" + }, + "solidity/interfaces/peripherals/IBaseErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Throws if a variable is assigned to the zero address\n error ZeroAddress();\n}\n" + }, + "solidity/interfaces/peripherals/IGovernable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Governable contract\n/// @notice Manages the governance role\ninterface IGovernable {\n // Events\n\n /// @notice Emitted when pendingGovernance accepts to be governance\n /// @param _governance Address of the new governance\n event GovernanceSet(address _governance);\n\n /// @notice Emitted when a new governance is proposed\n /// @param _pendingGovernance Address that is proposed to be the new governance\n event GovernanceProposal(address _pendingGovernance);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not governance\n error OnlyGovernance();\n\n /// @notice Throws if the caller of the function is not pendingGovernance\n error OnlyPendingGovernance();\n\n /// @notice Throws if trying to set governance to zero address\n error NoGovernanceZeroAddress();\n\n // Variables\n\n /// @notice Stores the governance address\n /// @return _governance The governance addresss\n function governance() external view returns (address _governance);\n\n /// @notice Stores the pendingGovernance address\n /// @return _pendingGovernance The pendingGovernance addresss\n function pendingGovernance() external view returns (address _pendingGovernance);\n\n // Methods\n\n /// @notice Proposes a new address to be governance\n /// @param _governance The address being proposed as the new governance\n function setGovernance(address _governance) external;\n\n /// @notice Changes the governance from the current governance to the previously proposed address\n function acceptGovernance() external;\n}\n" + }, + "solidity/interfaces/peripherals/IDustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IBaseErrors.sol';\n\ninterface IDustCollector is IBaseErrors {\n /// @notice Emitted when dust is sent\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address which will receive the funds\n event DustSent(address _token, uint256 _amount, address _to);\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(\n address _token,\n uint256 _amount,\n address _to\n ) external;\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @inheritdoc IKeep3rJobManager\n function addJob(address _job) external override {\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\n if (hasBonded[_job]) revert AlreadyAKeeper();\n _jobs.add(_job);\n jobOwner[_job] = msg.sender;\n emit JobAddition(_job, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobMigration.sol';\nimport '../../../interfaces/IKeep3rHelper.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 internal _initialGas;\n\n /// @inheritdoc IKeep3rJobWorkable\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\n _initialGas = _getGasLeft();\n if (_keepers.contains(_keeper)) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external override returns (bool _isBondedKeeper) {\n _initialGas = _getGasLeft();\n if (\n _keepers.contains(_keeper) &&\n bonds[_keeper][_bond] >= _minBond &&\n workCompleted[_keeper] >= _earned &&\n block.timestamp - firstSeen[_keeper] >= _age\n ) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function worked(address _keeper) external virtual override {\n if (_initialGas == 0) revert GasNotInitialized();\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _gasLeft = _getGasLeft();\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n _gasLeft = _getGasLeft();\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function bondedPayment(address _keeper, uint256 _payment) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (disputes[_keeper]) revert Disputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_keeper, _amount);\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\n }\n\n function _bondedPayment(\n address _job,\n address _keeper,\n uint256 _payment\n ) internal {\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\n\n workedAt[_job] = block.timestamp;\n _jobLiquidityCredits[_job] -= _payment;\n bonds[_keeper][keep3rV1] += _payment;\n workCompleted[_keeper] += _payment;\n totalBonds += _payment;\n }\n\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\n /// @param _gasLeft Amount of gas left after working the job\n /// @param _extraGas Amount of expected unaccounted gas\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\n /// @return _payment Amount to be payed in KP3R tokens\n function _calculatePayment(\n uint256 _gasLeft,\n uint256 _extraGas,\n uint256 _oneEthQuote,\n uint256 _boost\n ) internal view returns (uint256 _payment) {\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\n }\n\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\n _gasLeft = (gasleft() * 64) / 63;\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\nimport '../Keep3rDisputable.sol';\n\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\n\n try IERC20(_token).transfer(governance, _amount) {} catch {}\n jobTokenCredits[_job][_token] -= _amount;\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit JobSlashToken(_job, _token, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n try IERC20(_liquidity).transfer(governance, _amount) {} catch {}\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobPendingOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\n jobPendingOwner[_job] = _newOwner;\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\n }\n\n /// @inheritdoc IKeep3rJobOwnership\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\n address _previousOwner = jobOwner[_job];\n\n jobOwner[_job] = jobPendingOwner[_job];\n delete jobPendingOwner[_job];\n\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\n }\n\n modifier onlyJobOwner(address _job) {\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\n _;\n }\n\n modifier onlyPendingJobOwner(address _job) {\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\nimport './Keep3rRoles.sol';\n\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @notice List of all enabled keepers\n EnumerableSet.AddressSet internal _keepers;\n\n /// @inheritdoc IKeep3rAccountance\n uint256 public override totalBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override workCompleted;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override firstSeen;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override disputes;\n\n /// @inheritdoc IKeep3rAccountance\n /// @notice Mapping (job => bonding => amount)\n mapping(address => mapping(address => uint256)) public override bonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\n\n /// @notice The current liquidity credits available for a job\n mapping(address => uint256) internal _jobLiquidityCredits;\n\n /// @notice Map the address of a job to its correspondent periodCredits\n mapping(address => uint256) internal _jobPeriodCredits;\n\n /// @notice Enumerable array of Job Tokens for Credits\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\n\n /// @notice List of liquidities that a job has (job => liquidities)\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\n\n /// @notice Liquidity pool to observe\n mapping(address => address) internal _liquidityPool;\n\n /// @notice Tracks if a pool has KP3R as token0\n mapping(address => bool) internal _isKP3RToken0;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override hasBonded;\n\n /// @notice List of all enabled jobs\n EnumerableSet.AddressSet internal _jobs;\n\n /// @inheritdoc IKeep3rAccountance\n function jobs() external view override returns (address[] memory _list) {\n _list = _jobs.values();\n }\n\n /// @inheritdoc IKeep3rAccountance\n function keepers() external view override returns (address[] memory _list) {\n _list = _keepers.values();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport './DustCollector.sol';\nimport './Governable.sol';\n\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override slashers;\n\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override disputers;\n\n constructor(address _governance) Governable(_governance) DustCollector() {}\n\n /// @inheritdoc IKeep3rRoles\n function addSlasher(address _slasher) external override onlyGovernance {\n if (_slasher == address(0)) revert ZeroAddress();\n if (slashers[_slasher]) revert SlasherExistent();\n slashers[_slasher] = true;\n emit SlasherAdded(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeSlasher(address _slasher) external override onlyGovernance {\n if (!slashers[_slasher]) revert SlasherUnexistent();\n delete slashers[_slasher];\n emit SlasherRemoved(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function addDisputer(address _disputer) external override onlyGovernance {\n if (_disputer == address(0)) revert ZeroAddress();\n if (disputers[_disputer]) revert DisputerExistent();\n disputers[_disputer] = true;\n emit DisputerAdded(_disputer);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeDisputer(address _disputer) external override onlyGovernance {\n if (!disputers[_disputer]) revert DisputerUnexistent();\n delete disputers[_disputer];\n emit DisputerRemoved(_disputer);\n }\n\n /// @notice Functions with this modifier can only be called by either a slasher or governance\n modifier onlySlasher {\n if (!slashers[msg.sender]) revert OnlySlasher();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by either a disputer or governance\n modifier onlyDisputer {\n if (!disputers[msg.sender]) revert OnlyDisputer();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Governable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IGovernable.sol';\n\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public override governance;\n\n /// @inheritdoc IGovernable\n address public override pendingGovernance;\n\n constructor(address _governance) {\n if (_governance == address(0)) revert NoGovernanceZeroAddress();\n governance = _governance;\n }\n\n /// @inheritdoc IGovernable\n function setGovernance(address _governance) external override onlyGovernance {\n pendingGovernance = _governance;\n emit GovernanceProposal(_governance);\n }\n\n /// @inheritdoc IGovernable\n function acceptGovernance() external override onlyPendingGovernance {\n governance = pendingGovernance;\n delete pendingGovernance;\n emit GovernanceSet(governance);\n }\n\n /// @notice Functions with this modifier can only be called by governance\n modifier onlyGovernance {\n if (msg.sender != governance) revert OnlyGovernance();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernance\n modifier onlyPendingGovernance {\n if (msg.sender != pendingGovernance) revert OnlyPendingGovernance();\n _;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\n\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobMigration\n mapping(address => address) public override pendingJobMigrations;\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\n\n /// @inheritdoc IKeep3rJobMigration\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\n if (_fromJob == _toJob) revert JobMigrationImpossible();\n\n pendingJobMigrations[_fromJob] = _toJob;\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\n\n emit JobMigrationRequested(_fromJob, _toJob);\n }\n\n /// @inheritdoc IKeep3rJobMigration\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\n\n // force job credits update for both jobs\n _settleJobAccountance(_fromJob);\n _settleJobAccountance(_toJob);\n\n // migrate tokens\n while (_jobTokens[_fromJob].length() > 0) {\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\n _jobTokens[_fromJob].remove(_tokenToMigrate);\n _jobTokens[_toJob].add(_tokenToMigrate);\n }\n\n // migrate liquidities\n while (_jobLiquidities[_fromJob].length() > 0) {\n address _liquidity = _jobLiquidities[_fromJob].at(0);\n\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\n delete liquidityAmount[_fromJob][_liquidity];\n\n _jobLiquidities[_toJob].add(_liquidity);\n _jobLiquidities[_fromJob].remove(_liquidity);\n }\n\n // migrate job balances\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\n delete _jobPeriodCredits[_fromJob];\n\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\n delete _jobLiquidityCredits[_fromJob];\n\n // stop _fromJob from being a job\n delete rewardedAt[_fromJob];\n _jobs.remove(_fromJob);\n\n // delete unused data slots\n delete jobOwner[_fromJob];\n delete jobPendingOwner[_fromJob];\n delete _migrationCreatedAt[_fromJob][_toJob];\n delete pendingJobMigrations[_fromJob];\n\n emit JobMigrationSuccessful(_fromJob, _toJob);\n }\n}\n" + }, + "solidity/interfaces/IKeep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rHelperParameters.sol';\n\n/// @title Keep3rHelper contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelper is IKeep3rHelperParameters {\n // Errors\n\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\n error LiquidityPairInvalid();\n\n // Methods\n // solhint-enable func-name-mixedcase\n\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\n /// @param _eth The amount of ETH\n /// @return _amountOut The amount of KP3R\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\n\n /// @notice Returns the amount of KP3R the keeper has bonded\n /// @param _keeper The address of the keeper to check\n /// @return _amountBonded The amount of KP3R the keeper has bonded\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\n /// @param _keeper The address of the keeper to check\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\n\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\n /// @return _rewardBoost The reward boost that corresponds to the keeper\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\n\n /// @notice Given a pool address, returns the underlying tokens of the pair\n /// @param _pool Address of the correspondant pool\n /// @return _token0 Address of the first token of the pair\n /// @return _token1 Address of the second token of the pair\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\n\n /// @notice Defines the order of the tokens in the pair for twap calculations\n /// @param _pool Address of the correspondant pool\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\n\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\n /// @param _pool Address of the pool to observe\n /// @param _secondsAgo Array with time references to observe\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\n /// @return _success Boolean indicating if the observe call was succesfull\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n );\n\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\n /// @param _bonds Amount of bonded KP3R owned by the keeper\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\n /// @return _extra Amount of extra gas that should be added to the gas spent\n function getPaymentParams(uint256 _bonds)\n external\n view\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n );\n\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\n /// @param _liquidityAmount Amount of liquidity to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _kp3rAmount);\n\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\n /// @param _baseAmount Amount of token to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _quoteAmount);\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice Cooldown between withdrawals\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override nonReentrant {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n // KP3R shouldn't be used for direct token payments\n if (_token == keep3rV1) revert TokenUnallowed();\n uint256 _before = IERC20(_token).balanceOf(address(this));\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\n uint256 _tokenFee = (_received * fee) / _BASE;\n jobTokenCredits[_job][_token] += _received - _tokenFee;\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\n IERC20(_token).safeTransfer(governance, _tokenFee);\n _jobTokens[_job].add(_token);\n\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\n }\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external override nonReentrant onlyJobOwner(_job) {\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\n if (disputes[_job]) revert JobDisputed();\n\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_receiver, _amount);\n\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/IPairManager.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '../../libraries/FullMath.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice List of liquidities that are accepted in the system\n EnumerableSet.AddressSet internal _approvedLiquidities;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override rewardedAt;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override workedAt;\n\n /// @notice Tracks an address and returns its TickCache\n mapping(address => TickCache) internal _tick;\n\n // Views\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approvedLiquidities() external view override returns (address[] memory _list) {\n _list = _approvedLiquidities.values();\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n _periodCredits += _getReward(\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\n );\n }\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n\n // If the job was rewarded in the past 1 period time\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\n // If the job has period credits, update minted job credits to new twap\n _liquidityCredits = _periodCredits > 0\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\n } else {\n // Else return a full period worth of credits if current credits have expired\n _liquidityCredits = _periodCredits;\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n uint256 _cooldown = block.timestamp;\n\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\n // Will calculate cooldown if it outdated\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will calculate cooldown from last reward reference in this period\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\n } else {\n // Will calculate cooldown from last reward timestamp\n _cooldown -= rewardedAt[_job];\n }\n } else {\n // Will calculate cooldown from period start if expired\n _cooldown -= _period(block.timestamp);\n }\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\n\n if (_tick[_liquidity].period == lastPeriod) {\n // Will only ask for current period accumulator if liquidity is outdated\n uint32[] memory _secondsAgo = new uint32[](1);\n int56 previousTick = _tick[_liquidity].current;\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - previousTick;\n } else if (_tick[_liquidity].period < lastPeriod) {\n // Will ask for 2 accumulators if liquidity is expired\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n }\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Methods\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n _settleJobAccountance(_job);\n _jobLiquidityCredits[_job] += _amount;\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function revokeLiquidity(address _liquidity) external override onlyGovernance {\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\n delete _liquidityPool[_liquidity];\n delete _isKP3RToken0[_liquidity];\n delete _tick[_liquidity];\n\n emit LiquidityRevocation(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override nonReentrant {\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\n if (!_jobs.contains(_job)) revert JobUnavailable();\n\n _jobLiquidities[_job].add(_liquidity);\n\n _settleJobAccountance(_job);\n\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\n liquidityAmount[_job][_liquidity] += _amount;\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlyJobOwner(_job) {\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\n pendingUnbonds[_job][_liquidity] += _amount;\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit Unbonding(_job, _liquidity, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external override onlyJobOwner(_job) {\n if (_receiver == address(0)) revert ZeroAddress();\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\n if (disputes[_job]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[_job][_liquidity];\n\n delete pendingUnbonds[_job][_liquidity];\n delete canWithdrawAfter[_job][_liquidity];\n\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\n }\n\n // Internal functions\n\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\n if (rewardedAt[_job] < _period(block.timestamp)) {\n // Will exit function if job has been rewarded in current period\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\n // Will reset job to period syncronicity if a full period passed without rewards\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] = _period(block.timestamp);\n _rewarded = true;\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will reset job's syncronicity if last reward was more than epoch ago\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] += rewardPeriodTime;\n _rewarded = true;\n } else if (workedAt[_job] < _period(block.timestamp)) {\n // First keeper on period has to update job accountance to current twaps\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\n // Updating job accountance does not reward job\n }\n }\n }\n\n /// @notice Only called if _jobLiquidityCredits < payment\n function _rewardJobCredits(address _job) internal {\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\n rewardedAt[_job] = block.timestamp;\n }\n\n /// @notice Updates accountance for _jobPeriodCredits\n function _updateJobPeriod(address _job) internal {\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\n }\n\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n if (_tick[_liquidity].period != _period(block.timestamp)) {\n // Updates liquidity cache only if needed\n _tick[_liquidity] = observeLiquidity(_liquidity);\n }\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\n }\n }\n }\n\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\n function _unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) internal nonReentrant {\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\n\n // Ensures current twaps in job liquidities\n _updateJobPeriod(_job);\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\n\n // A liquidity can be revoked causing a job to have 0 periodCredits\n if (_jobPeriodCredits[_job] > 0) {\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\n }\n\n liquidityAmount[_job][_liquidity] -= _amount;\n if (liquidityAmount[_job][_liquidity] == 0) {\n _jobLiquidities[_job].remove(_liquidity);\n }\n }\n\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\n if (_timePassed < rewardPeriodTime) {\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\n } else _result = _multiplier;\n }\n\n /// @notice Returns the start of the period of the provided timestamp\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\n return _timestamp - (_timestamp % rewardPeriodTime);\n }\n\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\n }\n\n /// @notice Returns underlying KP3R amount for a given liquidity amount\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\n if (_tick[_liquidity].period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\n }\n }\n\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\n /// @dev Ensures a maximum of 1 period of credits\n function _settleJobAccountance(address _job) internal virtual {\n _updateJobCreditsIfNeeded(_job);\n _rewardJobCredits(_job);\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/IKeep3rHelper.sol';\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\nimport './Keep3rAccountance.sol';\n\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1Proxy;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rHelper;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override bondTime = 3 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override unbondTime = 14 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override liquidityMinimum = 3 ether;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override rewardPeriodTime = 5 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override inflationPeriod = 34 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override fee = 30;\n\n /// @notice The base that will be used to calculate the fee\n uint256 internal constant _BASE = 10_000;\n\n /// @notice The minimum reward period\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) {\n keep3rHelper = _keep3rHelper;\n keep3rV1 = _keep3rV1;\n keep3rV1Proxy = _keep3rV1Proxy;\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance {\n if (_keep3rHelper == address(0)) revert ZeroAddress();\n keep3rHelper = _keep3rHelper;\n emit Keep3rHelperChange(_keep3rHelper);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance {\n if (_keep3rV1 == address(0)) revert ZeroAddress();\n _mint(totalBonds);\n\n keep3rV1 = _keep3rV1;\n emit Keep3rV1Change(_keep3rV1);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance {\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\n keep3rV1Proxy = _keep3rV1Proxy;\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setBondTime(uint256 _bondTime) external override onlyGovernance {\n bondTime = _bondTime;\n emit BondTimeChange(_bondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernance {\n unbondTime = _unbondTime;\n emit UnbondTimeChange(_unbondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance {\n liquidityMinimum = _liquidityMinimum;\n emit LiquidityMinimumChange(_liquidityMinimum);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance {\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\n rewardPeriodTime = _rewardPeriodTime;\n emit RewardPeriodTimeChange(_rewardPeriodTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance {\n inflationPeriod = _inflationPeriod;\n emit InflationPeriodChange(_inflationPeriod);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setFee(uint256 _fee) external override onlyGovernance {\n fee = _fee;\n emit FeeChange(_fee);\n }\n\n function _mint(uint256 _amount) internal {\n totalBonds -= _amount;\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IGovernable.sol';\n\ninterface IKeep3rV1Proxy is IGovernable {\n // Structs\n struct Recipient {\n address recipient;\n uint256 caps;\n }\n\n // Variables\n function keep3rV1() external view returns (address);\n\n function minter() external view returns (address);\n\n function next(address) external view returns (uint256);\n\n function caps(address) external view returns (uint256);\n\n function recipients() external view returns (address[] memory);\n\n function recipientsCaps() external view returns (Recipient[] memory);\n\n // Errors\n error Cooldown();\n error NoDrawableAmount();\n error ZeroAddress();\n error OnlyMinter();\n\n // Methods\n function addRecipient(address recipient, uint256 amount) external;\n\n function removeRecipient(address recipient) external;\n\n function draw() external returns (uint256 _amount);\n\n function setKeep3rV1(address _keep3rV1) external;\n\n function setMinter(address _minter) external;\n\n function mint(uint256 _amount) external;\n\n function mint(address _account, uint256 _amount) external;\n\n function setKeep3rV1Governance(address _governance) external;\n\n function acceptKeep3rV1Governance() external;\n\n function dispute(address _keeper) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function addJob(address _job) external;\n\n function removeJob(address _job) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n}\n" + }, + "solidity/interfaces/IKeep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rHelperParameters contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelperParameters {\n // Structs\n\n /// @dev KP3R-WETH Pool address and isKP3RToken0\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\n struct TokenOraclePool {\n address poolAddress;\n bool isTKNToken0;\n }\n\n // Errors\n\n /// @notice Throws when pool does not have KP3R as token0 nor token1\n error InvalidOraclePool();\n\n // Events\n\n /// @notice Emitted when the kp3r weth pool is changed\n /// @param _address Address of the new kp3r weth pool\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\n\n /// @notice Emitted when the minimum boost multiplier is changed\n /// @param _minBoost The minimum boost multiplier\n event MinBoostChange(uint256 _minBoost);\n\n /// @notice Emitted when the maximum boost multiplier is changed\n /// @param _maxBoost The maximum boost multiplier\n event MaxBoostChange(uint256 _maxBoost);\n\n /// @notice Emitted when the target bond amount is changed\n /// @param _targetBond The target bond amount\n event TargetBondChange(uint256 _targetBond);\n\n /// @notice Emitted when the Keep3r V2 address is changed\n /// @param _keep3rV2 The address of Keep3r V2\n event Keep3rV2Change(address _keep3rV2);\n\n /// @notice Emitted when the work extra gas amount is changed\n /// @param _workExtraGas The work extra gas\n event WorkExtraGasChange(uint256 _workExtraGas);\n\n /// @notice Emitted when the quote twap time is changed\n /// @param _quoteTwapTime The twap time for quoting\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\n\n /// @notice Emitted when minimum rewarded gas fee is changed\n /// @param _minBaseFee The minimum rewarded gas fee\n event MinBaseFeeChange(uint256 _minBaseFee);\n\n /// @notice Emitted when minimum rewarded priority fee is changed\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\n event MinPriorityFeeChange(uint256 _minPriorityFee);\n\n // Variables\n\n /// @notice Address of KP3R token\n /// @return _kp3r Address of KP3R token\n // solhint-disable func-name-mixedcase\n function KP3R() external view returns (address _kp3r);\n\n /// @notice The boost base used to calculate the boost rewards for the keeper\n /// @return _base The boost base number\n function BOOST_BASE() external view returns (uint256 _base);\n\n /// @notice KP3R-WETH pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address\n function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\n /// @return _multiplier The minimum boost multiplier\n function minBoost() external view returns (uint256 _multiplier);\n\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\n /// @return _multiplier The maximum boost multiplier\n function maxBoost() external view returns (uint256 _multiplier);\n\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\n /// @return _target The amount of KP3R that comforms the targetBond\n function targetBond() external view returns (uint256 _target);\n\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\n /// @return _workExtraGas The work unaccounted gas amount\n function workExtraGas() external view returns (uint256 _workExtraGas);\n\n /// @notice The twap time for quoting\n /// @return _quoteTwapTime The twap time\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\n\n /// @notice The minimum base fee that is used to calculate keeper rewards\n /// @return _minBaseFee The minimum rewarded gas fee\n function minBaseFee() external view returns (uint256 _minBaseFee);\n\n /// @notice The minimum priority fee that is also rewarded for keepers\n /// @return _minPriorityFee The minimum rewarded priority fee\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\n\n /// @notice Address of Keep3r V2\n /// @return _keep3rV2 Address of Keep3r V2\n function keep3rV2() external view returns (address _keep3rV2);\n\n // Methods\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function setKp3rWethPool(address _poolAddress) external;\n\n /// @notice Sets the minimum boost multiplier\n /// @param _minBoost The minimum boost multiplier\n function setMinBoost(uint256 _minBoost) external;\n\n /// @notice Sets the maximum boost multiplier\n /// @param _maxBoost The maximum boost multiplier\n function setMaxBoost(uint256 _maxBoost) external;\n\n /// @notice Sets the target bond amount\n /// @param _targetBond The target bond amount\n function setTargetBond(uint256 _targetBond) external;\n\n /// @notice Sets the Keep3r V2 address\n /// @param _keep3rV2 The address of Keep3r V2\n function setKeep3rV2(address _keep3rV2) external;\n\n /// @notice Sets the work extra gas amount\n /// @param _workExtraGas The work extra gas\n function setWorkExtraGas(uint256 _workExtraGas) external;\n\n /// @notice Sets the quote twap time\n /// @param _quoteTwapTime The twap time for quoting\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\n\n /// @notice Sets the minimum rewarded gas fee\n /// @param _minBaseFee The minimum rewarded gas fee\n function setMinBaseFee(uint256 _minBaseFee) external;\n\n /// @notice Sets the minimum rewarded gas priority fee\n /// @param _minPriorityFee The minimum rewarded priority fee\n function setMinPriorityFee(uint256 _minPriorityFee) external;\n}\n" + }, + "solidity/interfaces/IPairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n/// @title Pair Manager interface\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\ninterface IPairManager is IERC20Metadata {\n /// @notice Address of the factory from which the pair manager was created\n /// @return _factory The address of the PairManager Factory\n function factory() external view returns (address _factory);\n\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\n /// @return _pool The address of the pool\n function pool() external view returns (address _pool);\n\n /// @notice Token0 of the pool\n /// @return _token0 The address of token0\n function token0() external view returns (address _token0);\n\n /// @notice Token1 of the pool\n /// @return _token1 The address of token1\n function token1() external view returns (address _token1);\n}\n" + }, + "solidity/contracts/libraries/FullMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (~denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "solidity/contracts/peripherals/Keep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rParameters.sol';\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\n\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\n /// @inheritdoc IKeep3rDisputable\n function dispute(address _jobOrKeeper) external override onlyDisputer {\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\n disputes[_jobOrKeeper] = true;\n emit Dispute(_jobOrKeeper, msg.sender);\n }\n\n /// @inheritdoc IKeep3rDisputable\n function resolve(address _jobOrKeeper) external override onlyDisputer {\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\n disputes[_jobOrKeeper] = false;\n emit Resolve(_jobOrKeeper, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rKeeperFundable.sol';\nimport '../Keep3rDisputable.sol';\nimport '../../../interfaces/external/IKeep3rV1.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\n }\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function revoke(address _keeper) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _keepers.remove(_keeper);\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\n emit KeeperRevoke(_keeper, msg.sender);\n }\n\n function _slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) internal {\n if (_bonded != keep3rV1) {\n try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\n }\n bonds[_keeper][_bonded] -= _bondAmount;\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nimport '../../../interfaces/external/IKeep3rV1.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperFundable\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\n if (disputes[msg.sender]) revert Disputed();\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\n\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\n\n hasBonded[msg.sender] = true;\n pendingBonds[msg.sender][_bonding] += _amount;\n\n emit Bonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function activate(address _bonding) external override {\n address _keeper = msg.sender;\n if (disputes[_keeper]) revert Disputed();\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\n if (_canActivateAfter == 0) revert BondsUnexistent();\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\n\n if (firstSeen[_keeper] == 0) {\n firstSeen[_keeper] = block.timestamp;\n }\n _keepers.add(_keeper);\n\n uint256 _amount = pendingBonds[_keeper][_bonding];\n delete pendingBonds[_keeper][_bonding];\n\n // bond provided tokens\n bonds[_keeper][_bonding] += _amount;\n if (_bonding == keep3rV1) {\n totalBonds += _amount;\n _depositBonds(_amount);\n }\n\n emit Activation(_keeper, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function unbond(address _bonding, uint256 _amount) external override {\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\n bonds[msg.sender][_bonding] -= _amount;\n pendingUnbonds[msg.sender][_bonding] += _amount;\n\n emit Unbonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function withdraw(address _bonding) external override nonReentrant {\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\n if (disputes[msg.sender]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\n\n delete pendingUnbonds[msg.sender][_bonding];\n delete canWithdrawAfter[msg.sender][_bonding];\n\n if (_bonding == keep3rV1) _mint(_amount);\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(msg.sender, _bonding, _amount);\n }\n\n function _depositBonds(uint256 _amount) internal virtual {\n IKeep3rV1(keep3rV1).burn(_amount);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n// solhint-disable func-name-mixedcase\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\n // Structs\n struct Checkpoint {\n uint32 fromBlock;\n uint256 votes;\n }\n\n // Events\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event JobAdded(address indexed _job, uint256 _block, address _governance);\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\n event KeeperDispute(address indexed _keeper, uint256 _block);\n event KeeperResolved(address indexed _keeper, uint256 _block);\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\n\n // Variables\n function KPRH() external returns (address);\n\n function delegates(address _delegator) external view returns (address);\n\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\n\n function numCheckpoints(address _account) external view returns (uint32);\n\n function DOMAIN_TYPEHASH() external returns (bytes32);\n\n function DOMAINSEPARATOR() external returns (bytes32);\n\n function DELEGATION_TYPEHASH() external returns (bytes32);\n\n function PERMIT_TYPEHASH() external returns (bytes32);\n\n function nonces(address _user) external view returns (uint256);\n\n function BOND() external returns (uint256);\n\n function UNBOND() external returns (uint256);\n\n function LIQUIDITYBOND() external returns (uint256);\n\n function FEE() external returns (uint256);\n\n function BASE() external returns (uint256);\n\n function ETH() external returns (address);\n\n function bondings(address _user, address _bonding) external view returns (uint256);\n\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\n\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function bonds(address _keeper, address _bonding) external view returns (uint256);\n\n function votes(address _delegator) external view returns (uint256);\n\n function firstSeen(address _keeper) external view returns (uint256);\n\n function disputes(address _keeper) external view returns (bool);\n\n function lastJob(address _keeper) external view returns (uint256);\n\n function workCompleted(address _keeper) external view returns (uint256);\n\n function jobs(address _job) external view returns (bool);\n\n function credits(address _job, address _credit) external view returns (uint256);\n\n function liquidityProvided(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmountsUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function jobProposalDelay(address _job) external view returns (uint256);\n\n function liquidityApplied(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmount(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function keepers(address _keeper) external view returns (bool);\n\n function blacklist(address _keeper) external view returns (bool);\n\n function keeperList(uint256 _index) external view returns (address);\n\n function jobList(uint256 _index) external view returns (address);\n\n function governance() external returns (address);\n\n function pendingGovernance() external returns (address);\n\n function liquidityAccepted(address _liquidity) external view returns (bool);\n\n function liquidityPairs(uint256 _index) external view returns (address);\n\n // Methods\n function getCurrentVotes(address _account) external view returns (uint256);\n\n function addCreditETH(address _job) external payable;\n\n function addCredit(\n address _credit,\n address _job,\n uint256 _amount\n ) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function pairs() external view returns (address[] memory);\n\n function addLiquidityToJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function applyCreditToJob(\n address _provider,\n address _liquidity,\n address _job\n ) external;\n\n function unbondLiquidityFromJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function removeLiquidityFromJob(address _liquidity, address _job) external;\n\n function mint(uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n\n function worked(address _keeper) external;\n\n function receipt(\n address _credit,\n address _keeper,\n uint256 _amount\n ) external;\n\n function receiptETH(address _keeper, uint256 _amount) external;\n\n function addJob(address _job) external;\n\n function getJobs() external view returns (address[] memory);\n\n function removeJob(address _job) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function isKeeper(address _keeper) external returns (bool);\n\n function isMinKeeper(\n address _keeper,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function bond(address _bonding, uint256 _amount) external;\n\n function getKeepers() external view returns (address[] memory);\n\n function activate(address _bonding) external;\n\n function unbond(address _bonding, uint256 _amount) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function withdraw(address _bonding) external;\n\n function dispute(address _keeper) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function permit(\n address _owner,\n address _spender,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3r.sol';\n\ncontract Keep3rForTestnet is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3r.sol';\n\ncontract Keep3rForTest is Keep3r {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3r.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\n\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @param _governance Address of governance\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\n constructor(\n address _governance, // governance\n address _keep3rHelperSidechain, // helper\n address _wrappedKP3R, // keep3rV1\n address _keep3rEscrow // keep3rV1Proxy\n ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\n\n // Keep3rSidechainAccountance\n\n /// @inheritdoc IKeep3rSidechainAccountance\n function virtualReserves() external view override returns (int256 _virtualReserves) {\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\n }\n\n // Keep3rJobFundableLiquidity\n\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\n /// @param _liquidity Address of the liquidity token being approved\n function approveLiquidity(address _liquidity) external virtual override onlyGovernance {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\n /// @param _liquidity Address of the liquidity token being observed\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n\n // Will always ask for 2 accumulators in sidechain\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Keep3rJobsWorkable\n\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\n function worked(address) external pure override {\n revert Deprecated();\n }\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Uses a USD per gas unit payment mechanism\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\n if (_initialGas == 0) revert GasNotInitialized();\n // Gas used for quote calculations & payment is not rewarded\n uint256 _gasLeft = _getGasLeft();\n\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\n\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _kp3rPayment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\n }\n\n // Keep3rKeeperFundable\n\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\n function _depositBonds(uint256 _amount) internal virtual override {\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\n }\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// solhint-disable-next-line no-empty-blocks\n\nimport '../peripherals/IMintable.sol';\n\n/// @title Keep3rEscrow contract\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\ninterface IKeep3rEscrow is IMintable {\n /// @notice Emitted when Keep3rEscrow#deposit function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _sender The address that called the function\n /// @param _amount The amount of wKP3R the user deposited\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#mint function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _recipient The address that will received the newly minted wKP3R\n /// @param _amount The amount of wKP3R minted to the recipient\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\n /// @param _newWKP3R The address of the wKP3R contract\n event wKP3RSet(address _newWKP3R);\n\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\n error InsufficientBalance();\n\n /// @notice Lists the address of the wKP3R contract\n /// @return _wKP3RAddress The address of wKP3R\n function wKP3R() external view returns (address _wKP3RAddress);\n\n /// @notice Deposits wKP3R into the contract\n /// @param _amount The amount of wKP3R to deposit\n function deposit(uint256 _amount) external;\n\n /// @notice mints wKP3R to the recipient\n /// @param _amount The amount of wKP3R to mint\n function mint(uint256 _amount) external;\n\n /// @notice sets the wKP3R address\n /// @param _wKP3R the wKP3R address\n function setWKP3R(address _wKP3R) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../IKeep3rHelper.sol';\n\n/// @title Keep3rHelperSidechain contract\n/// @notice Contains all the helper functions for sidechain keep3r implementations\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\n // Events\n\n /// @notice The oracle for a liquidity has been saved\n /// @param _liquidity The address of the given liquidity\n /// @param _oraclePool The address of the oracle pool\n event OracleSet(address _liquidity, address _oraclePool);\n\n /// @notice Emitted when the WETH USD pool is changed\n /// @param _address Address of the new WETH USD pool\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n event WethUSDPoolChange(address _address, bool _isWETHToken0);\n\n /// Variables\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n /// @return _weth Address of WETH token\n // solhint-disable func-name-mixedcase\n function WETH() external view returns (address _weth);\n\n /// @return _oracle The address of the observable pool for given liquidity\n function oracle(address _liquidity) external view returns (address _oracle);\n\n /// @notice WETH-USD pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address\n function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0);\n\n /// @notice Quotes USD to ETH\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\n /// @param _usd The amount of USD to quote to ETH\n /// @return _eth The resulting amount of ETH after quoting the USD\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\n\n /// Methods\n\n /// @notice Sets an oracle for a given liquidity\n /// @param _liquidity The address of the liquidity\n /// @param _oracle The address of the pool used to quote the liquidity from\n /// @dev The oracle must contain KP3R as either token0 or token1\n function setOracle(address _liquidity, address _oracle) external;\n\n /// @notice Sets an oracle for querying WETH/USD quote\n /// @param _poolAddress The address of the pool used as oracle\n /// @dev The oracle must contain WETH as either token0 or token1\n function setWethUsdPool(address _poolAddress) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IKeep3rJobs.sol';\n\n/// @title Keep3rJobWorkableRated contract\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\n /// @notice Throws when job contract calls deprecated worked(address) function\n error Deprecated();\n\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title IKeep3rSidechainAccountance interface\n/// @notice Implements a view to get the amount of credits that can be withdrawn\ninterface IKeep3rSidechainAccountance {\n /// @notice The surplus amount of wKP3Rs in escrow contract\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\n function virtualReserves() external view returns (int256 _virtualReserves);\n}\n" + }, + "solidity/interfaces/peripherals/IMintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IGovernable.sol';\nimport './IBaseErrors.sol';\n\n/// @title Mintable contract\n/// @notice Manages the minter role\ninterface IMintable is IBaseErrors, IGovernable {\n // Events\n\n /// @notice Emitted when governance sets a new minter\n /// @param _minter Address of the new minter\n event MinterSet(address _minter);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not the minter\n error OnlyMinter();\n\n // Variables\n\n /// @notice Stores the minter address\n /// @return _minter The minter addresss\n function minter() external view returns (address _minter);\n\n // Methods\n\n /// @notice Sets a new address to be the minter\n /// @param _minter The address set as the minter\n function setMinter(address _minter) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\n constructor(\n address _governance,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rSidechainForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTest is Keep3rSidechain {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _governance,\n address _keep3rHelper,\n address _wrappedKP3R,\n address _keep3rEscrow\n ) Keep3rSidechain(_governance, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n}\n" + }, + "solidity/for-test/JobRatedForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\n\ncontract JobRatedForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n uint256 public usdPerGasUnit = 1;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n}\n" + }, + "solidity/for-test/JobForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract JobForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/for-test/BasicJob.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract BasicJob {\n error KeeperNotValid();\n\n address public keep3r;\n uint256 public nonce;\n uint256[] public array;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external upkeep {}\n\n function workHard(uint256 _howHard) external upkeep {\n for (uint256 i = nonce; i < _howHard; i++) {\n nonce++;\n }\n }\n\n function workRefund(uint256 _howHard) external upkeep {\n for (uint256 i; i < _howHard; i++) {\n array.push(i);\n }\n\n while (array.length > 0) {\n array.pop();\n }\n }\n\n modifier upkeep() {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\n _;\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/peripherals/IBaseErrors.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/external/IKeep3rV1.sol';\nimport '../interfaces/IKeep3rHelperParameters.sol';\nimport './peripherals/Governable.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\n /// @inheritdoc IKeep3rHelperParameters\n address public immutable override KP3R;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public constant override BOOST_BASE = 10_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBoost = 11_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override maxBoost = 12_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override targetBond = 200 ether;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override workExtraGas = 34_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint32 public override quoteTwapTime = 10 minutes;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBaseFee = 15e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minPriorityFee = 2e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n address public override keep3rV2;\n\n /// @inheritdoc IKeep3rHelperParameters\n IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Governable(_governance) {\n KP3R = _kp3r;\n keep3rV2 = _keep3rV2;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKp3rWethPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setKp3rWethPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBoost(uint256 _minBoost) external override onlyGovernance {\n minBoost = _minBoost;\n emit MinBoostChange(minBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernance {\n maxBoost = _maxBoost;\n emit MaxBoostChange(maxBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setTargetBond(uint256 _targetBond) external override onlyGovernance {\n targetBond = _targetBond;\n emit TargetBondChange(targetBond);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKeep3rV2(address _keep3rV2) external override onlyGovernance {\n if (_keep3rV2 == address(0)) revert ZeroAddress();\n keep3rV2 = _keep3rV2;\n emit Keep3rV2Change(keep3rV2);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance {\n workExtraGas = _workExtraGas;\n emit WorkExtraGasChange(workExtraGas);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance {\n _setQuoteTwapTime(_quoteTwapTime);\n }\n\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\n quoteTwapTime = _quoteTwapTime;\n emit QuoteTwapTimeChange(quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance {\n minBaseFee = _minBaseFee;\n emit MinBaseFeeChange(minBaseFee);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance {\n minPriorityFee = _minPriorityFee;\n emit MinPriorityFeeChange(minPriorityFee);\n }\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function _setKp3rWethPool(address _poolAddress) internal {\n kp3rWethPool = _validateOraclePool(_poolAddress, KP3R);\n emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0);\n }\n\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) {\n bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\n\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\n\n return TokenOraclePool(_poolAddress, _isTKNToken0);\n }\n}\n" + }, + "solidity/contracts/libraries/TickMath.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n// solhint-disable\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n // Second inequality must be < because the price can never reach the price at the max tick\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport './pool/IUniswapV3PoolImmutables.sol';\nimport './pool/IUniswapV3PoolState.sol';\nimport './pool/IUniswapV3PoolDerivedState.sol';\nimport './pool/IUniswapV3PoolActions.sol';\nimport './pool/IUniswapV3PoolOwnerActions.sol';\nimport './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolEvents\n{\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// observationIndex The index of the last oracle observation that was written,\n /// observationCardinality The current maximum number of observations stored in the pool,\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper,\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return _liquidity The amount of liquidity in the position,\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 _liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// Returns initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" + }, + "solidity/for-test/UniV3PairManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport '../contracts/libraries/LiquidityAmounts.sol';\nimport '../contracts/libraries/FixedPoint96.sol';\nimport '../contracts/libraries/FullMath.sol';\nimport '../contracts/libraries/TickMath.sol';\nimport '../contracts/UniV3PairManager.sol';\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManagerForTest is UniV3PairManager {\n constructor(address _pool, address _governance) UniV3PairManager(_pool, _governance) {}\n\n function internalAddLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n external\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n return _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n }\n\n function internalPay(\n address token,\n address payer,\n address recipient,\n uint256 value\n ) external {\n return _pay(token, payer, recipient, value);\n }\n\n function internalMint(address dst, uint256 amount) external {\n return _mint(dst, amount);\n }\n\n function internalBurn(address dst, uint256 amount) external {\n return _burn(dst, amount);\n }\n\n function internalTransferTokens(\n address src,\n address dst,\n uint256 amount\n ) external {\n _transferTokens(src, dst, amount);\n }\n\n function internalSafeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) external {\n _safeTransferFrom(token, from, to, value);\n }\n\n receive() external payable {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "solidity/contracts/libraries/LiquidityAmounts.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport './FullMath.sol';\nimport './FixedPoint96.sol';\n\n// solhint-disable\nlibrary LiquidityAmounts {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/contracts/libraries/FixedPoint96.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nlibrary FixedPoint96 {\n // solhint-disable\n uint8 internal constant RESOLUTION = 96;\n uint256 internal constant Q96 = 0x1000000000000000000000000;\n}\n" + }, + "solidity/contracts/UniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport './libraries/LiquidityAmounts.sol';\nimport './libraries/FixedPoint96.sol';\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\n\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\nimport './peripherals/Governable.sol';\n\ncontract UniV3PairManager is IUniV3PairManager, Governable {\n /// @inheritdoc IERC20Metadata\n string public override name;\n\n /// @inheritdoc IERC20Metadata\n string public override symbol;\n\n /// @inheritdoc IERC20\n uint256 public override totalSupply;\n\n /// @inheritdoc IPairManager\n address public immutable override factory;\n\n /// @inheritdoc IPairManager\n address public immutable override token0;\n\n /// @inheritdoc IPairManager\n address public immutable override token1;\n\n /// @inheritdoc IPairManager\n address public immutable override pool;\n\n /// @inheritdoc IUniV3PairManager\n uint24 public immutable override fee;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioAX96;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioBX96;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickLower;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickUpper;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickSpacing;\n\n /// @notice Uniswap's maximum tick\n /// @dev Due to tick spacing, pools with different fees may have differences between _MAX_TICK and tickUpper. Use tickUpper to find the max tick of the pool.\n int24 private constant _MAX_TICK = 887272;\n\n /// @inheritdoc IERC20Metadata\n //solhint-disable-next-line const-name-snakecase\n uint8 public constant override decimals = 18;\n\n /// @inheritdoc IERC20\n mapping(address => mapping(address => uint256)) public override allowance;\n\n /// @inheritdoc IERC20\n mapping(address => uint256) public override balanceOf;\n\n /// @notice Struct that contains token0, token1, and fee of the Uniswap pool\n PoolKey private _poolKey;\n\n constructor(address _pool, address _governance) Governable(_governance) {\n uint24 _fee = IUniswapV3Pool(_pool).fee();\n address _token0 = IUniswapV3Pool(_pool).token0();\n address _token1 = IUniswapV3Pool(_pool).token1();\n int24 _tickSpacing = IUniswapV3Pool(_pool).tickSpacing();\n int24 _tickUpper = _MAX_TICK - (_MAX_TICK % _tickSpacing);\n int24 _tickLower = -_tickUpper;\n\n factory = msg.sender;\n pool = _pool;\n fee = _fee;\n tickSpacing = _tickSpacing;\n tickUpper = _tickUpper;\n tickLower = _tickLower;\n token0 = _token0;\n token1 = _token1;\n name = string(abi.encodePacked('Keep3rLP - ', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n symbol = string(abi.encodePacked('kLP-', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n\n sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(_tickLower);\n sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(_tickUpper);\n _poolKey = PoolKey({token0: _token0, token1: _token1, fee: _fee});\n }\n\n // This low-level function should be called from a contract which performs important safety checks\n /// @inheritdoc IUniV3PairManager\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint128 liquidity) {\n (liquidity, , ) = _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n _mint(to, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external override {\n MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));\n if (msg.sender != pool) revert OnlyPool();\n if (amount0Owed > 0) _pay(decoded._poolKey.token0, decoded.payer, pool, amount0Owed);\n if (amount1Owed > 0) _pay(decoded._poolKey.token1, decoded.payer, pool, amount1Owed);\n }\n\n /// @inheritdoc IUniV3PairManager\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint256 amount0, uint256 amount1) {\n (amount0, amount1) = IUniswapV3Pool(pool).burn(tickLower, tickUpper, liquidity);\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n\n IUniswapV3Pool(pool).collect(to, tickLower, tickUpper, uint128(amount0), uint128(amount1));\n _burn(msg.sender, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function collect() external override onlyGovernance returns (uint256 amount0, uint256 amount1) {\n (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n (amount0, amount1) = IUniswapV3Pool(pool).collect(governance, tickLower, tickUpper, tokensOwed0, tokensOwed1);\n }\n\n /// @inheritdoc IUniV3PairManager\n function position()\n external\n view\n override\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n )\n {\n (liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128, tokensOwed0, tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n }\n\n /// @inheritdoc IERC20\n function approve(address spender, uint256 amount) external override returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transfer(address to, uint256 amount) external override returns (bool) {\n _transferTokens(msg.sender, to, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool) {\n address spender = msg.sender;\n uint256 spenderAllowance = allowance[from][spender];\n\n if (spender != from && spenderAllowance != type(uint256).max) {\n uint256 newAllowance = spenderAllowance - amount;\n allowance[from][spender] = newAllowance;\n\n emit Approval(from, spender, newAllowance);\n }\n\n _transferTokens(from, to, amount);\n return true;\n }\n\n /// @notice Adds liquidity to an initialized pool\n /// @dev Reverts if the returned amount0 is less than amount0Min or if amount1 is less than amount1Min\n /// @dev This function calls the mint function of the corresponding Uniswap pool, which in turn calls UniswapV3Callback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @return liquidity The calculated liquidity we get for the token amounts we provided\n /// @return amount0 The amount of token0 we ended up providing\n /// @return amount1 The amount of token1 we ended up providing\n function _addLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n internal\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(pool).slot0();\n\n liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, amount0Desired, amount1Desired);\n\n (amount0, amount1) = IUniswapV3Pool(pool).mint(\n address(this),\n tickLower,\n tickUpper,\n liquidity,\n abi.encode(MintCallbackData({_poolKey: _poolKey, payer: msg.sender}))\n );\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n }\n\n /// @notice Transfers the passed-in token from the payer to the recipient for the corresponding value\n /// @param token The token to be transferred to the recipient\n /// @param from The address of the payer\n /// @param to The address of the passed-in tokens recipient\n /// @param value How much of that token to be transferred from payer to the recipient\n function _pay(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n _safeTransferFrom(token, from, to, value);\n }\n\n /// @notice Mints Keep3r credits to the passed-in address of recipient and increases total supply of Keep3r credits by the corresponding amount\n /// @param to The recipient of the Keep3r credits\n /// @param amount The amount Keep3r credits to be minted to the recipient\n function _mint(address to, uint256 amount) internal {\n totalSupply += amount;\n balanceOf[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @notice Burns Keep3r credits to the passed-in address of recipient and reduces total supply of Keep3r credits by the corresponding amount\n /// @param to The address that will get its Keep3r credits burned\n /// @param amount The amount Keep3r credits to be burned from the recipient/recipient\n function _burn(address to, uint256 amount) internal {\n totalSupply -= amount;\n balanceOf[to] -= amount;\n emit Transfer(to, address(0), amount);\n }\n\n /// @notice Transfers amount of Keep3r credits between two addresses\n /// @param from The user that transfers the Keep3r credits\n /// @param to The user that receives the Keep3r credits\n /// @param amount The amount of Keep3r credits to be transferred\n function _transferTokens(\n address from,\n address to,\n uint256 amount\n ) internal {\n balanceOf[from] -= amount;\n balanceOf[to] += amount;\n\n emit Transfer(from, to, amount);\n }\n\n /// @notice Transfers the passed-in token from the specified \"from\" to the specified \"to\" for the corresponding value\n /// @dev Reverts with IUniV3PairManager#UnsuccessfulTransfer if the transfer was not successful,\n /// or if the passed data length is different than 0 and the decoded data is not a boolean\n /// @param token The token to be transferred to the specified \"to\"\n /// @param from The address which is going to transfer the tokens\n /// @param value How much of that token to be transferred from \"from\" to \"to\"\n function _safeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert UnsuccessfulTransfer();\n }\n}\n" + }, + "solidity/interfaces/external/IWeth9.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IWeth9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256) external;\n}\n" + }, + "solidity/interfaces/IUniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IPairManager.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\nimport './peripherals/IGovernable.sol';\n\n/// @title Pair Manager contract\n/// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner\n/// so that the user can use it as liquidity for a Keep3rJob\ninterface IUniV3PairManager is IGovernable, IPairManager {\n // Structs\n struct PoolKey {\n address token0;\n address token1;\n uint24 fee;\n }\n\n /// @notice The data to be decoded by the UniswapV3MintCallback function\n struct MintCallbackData {\n PoolKey _poolKey; // Struct that contains token0, token1, and fee of the pool passed into the constructor\n address payer; // The address of the payer, which will be the msg.sender of the mint function\n }\n\n // Variables\n\n /// @notice The fee of the Uniswap pool passed into the constructor\n /// @return _fee The fee of the Uniswap pool passed into the constructor\n function fee() external view returns (uint24 _fee);\n\n /// @notice Highest tick in the Uniswap's curve\n /// @return _tickUpper The highest tick in the Uniswap's curve\n function tickUpper() external view returns (int24 _tickUpper);\n\n /// @notice Lowest tick in the Uniswap's curve\n /// @return _tickLower The lower tick in the Uniswap's curve\n function tickLower() external view returns (int24 _tickLower);\n\n /// @notice The pair tick spacing\n /// @return _tickSpacing The pair tick spacing\n function tickSpacing() external view returns (int24 _tickSpacing);\n\n /// @notice The sqrtRatioAX96 at the lowest tick (-887200) of the Uniswap pool\n /// @return _sqrtPriceA96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the lowest tick\n function sqrtRatioAX96() external view returns (uint160 _sqrtPriceA96);\n\n /// @notice The sqrtRatioBX96 at the highest tick (887200) of the Uniswap pool\n /// @return _sqrtPriceBX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the highest tick\n function sqrtRatioBX96() external view returns (uint160 _sqrtPriceBX96);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the pool\n error OnlyPool();\n\n /// @notice Throws when the slippage exceeds what the user is comfortable with\n error ExcessiveSlippage();\n\n /// @notice Throws when a transfer is unsuccessful\n error UnsuccessfulTransfer();\n\n // Methods\n\n /// @notice This function is called after a user calls IUniV3PairManager#mint function\n /// It ensures that any tokens owed to the pool are paid by the msg.sender of IUniV3PairManager#mint function\n /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity\n /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity\n /// @param data The encoded token0, token1, fee (_poolKey) and the payer (msg.sender) of the IUniV3PairManager#mint function\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external;\n\n /// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool\n /// @dev Triggers UniV3PairManager#uniswapV3MintCallback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @param to The address to which the kLP tokens are going to be minted to\n /// @return liquidity kLP tokens sent in exchange for the provision of tokens\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint128 liquidity);\n\n /// @notice Returns the pair manager's position in the corresponding UniswapV3 pool\n /// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager\n /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position\n /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position\n /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation\n /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation\n function position()\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees\n // owed to a specific position to the recipient, in this case, that recipient is the pair manager\n /// @dev The collected fees will be sent to governance\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect() external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity\n // in the entire range\n /// @param liquidity The amount of liquidity to be burned\n /// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)\n /// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)\n /// @param to The address that will receive the due fees\n /// @return amount0 The calculated amount of token0 that will be sent to the recipient\n /// @return amount1 The calculated amount of token1 that will be sent to the recipient\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint256 amount0, uint256 amount1);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "solidity/interfaces/IPairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IGovernable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ninterface IPairManagerFactory is IGovernable {\n // Variables\n\n /// @notice Maps the address of a Uniswap pool, to the address of the corresponding PairManager\n /// For example, the uniswap address of DAI-WETH, will return the Keep3r/DAI-WETH pair manager address\n /// @param _pool The address of the Uniswap pool\n /// @return _pairManager The address of the corresponding pair manager\n function pairManagers(address _pool) external view returns (address _pairManager);\n\n // Events\n\n /// @notice Emitted when a new pair manager is created\n /// @param _pool The address of the corresponding Uniswap pool\n /// @param _pairManager The address of the just-created pair manager\n event PairCreated(address _pool, address _pairManager);\n\n // Errors\n\n /// @notice Throws an error if the pair manager is already initialized\n error AlreadyInitialized();\n\n /// @notice Throws an error if the caller is not the owner\n error OnlyOwner();\n\n // Methods\n\n /// @notice Creates a new pair manager based on the address of a Uniswap pool\n /// For example, the uniswap address of DAI-WETH, will create the Keep3r/DAI-WETH pool\n /// @param _pool The address of the Uniswap pool the pair manager will be based of\n /// @return _pairManager The address of the just-created pair manager\n function createPairManager(address _pool) external returns (address _pairManager);\n}\n" + }, + "solidity/contracts/UniV3PairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IPairManagerFactory.sol';\nimport './UniV3PairManager.sol';\nimport './peripherals/Governable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ncontract UniV3PairManagerFactory is IPairManagerFactory, Governable {\n mapping(address => address) public override pairManagers;\n\n constructor(address _governance) Governable(_governance) {}\n\n ///@inheritdoc IPairManagerFactory\n function createPairManager(address _pool) external override returns (address _pairManager) {\n if (pairManagers[_pool] != address(0)) revert AlreadyInitialized();\n _pairManager = address(new UniV3PairManager(_pool, governance));\n pairManagers[_pool] = _pairManager;\n emit PairCreated(_pool, _pairManager);\n }\n}\n" + }, + "solidity/for-test/peripherals/GovernableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Governable.sol';\n\ncontract GovernableForTest is Governable {\n constructor(address _governor) Governable(_governor) {}\n}\n" + }, + "solidity/for-test/BridgeForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ncontract BridgeForTest is ERC20 {\n address public immutable kp3r;\n\n constructor(address _kp3r) ERC20('Wrapped KP3R', 'wKP3R') {\n kp3r = _kp3r;\n }\n\n function bridge(uint256 _amount) external {\n IERC20(kp3r).transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n }\n\n function bridgeBack(uint256 _amount) external {\n _burn(msg.sender, _amount);\n IERC20(kp3r).transfer(msg.sender, _amount);\n }\n}\n" + }, + "solidity/for-test/ERC20ForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(uint256 _amount) public {\n _mint(msg.sender, _amount);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(uint256 _amount) public {\n _burn(msg.sender, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n function deposit() external payable {\n // Function added for compatibility with WETH\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperFundableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperFundable.sol';\n\ncontract Keep3rKeeperFundableForTest is Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function isKeeper(address _keeper) external view returns (bool) {\n return _keepers.contains(_keeper);\n }\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/Mintable.sol';\nimport '../peripherals/DustCollector.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rEscrow\n address public override wKP3R;\n\n /// @param _governance Address of governance\n /// @param _wKP3R Address of wrapped KP3R implementation\n constructor(address _governance, address _wKP3R) Mintable(_governance) {\n wKP3R = _wKP3R;\n }\n\n /// @inheritdoc IKeep3rEscrow\n function deposit(uint256 _amount) external override {\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function mint(uint256 _amount) external override onlyMinter {\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function setWKP3R(address _wKP3R) external override onlyGovernance {\n if (_wKP3R == address(0)) revert ZeroAddress();\n wKP3R = _wKP3R;\n emit wKP3RSet(wKP3R);\n }\n}\n" + }, + "solidity/contracts/peripherals/Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IMintable.sol';\nimport './Governable.sol';\n\nabstract contract Mintable is Governable, IMintable {\n /// @inheritdoc IMintable\n address public override minter;\n\n constructor(address _governance) Governable(_governance) {}\n\n /// @inheritdoc IMintable\n function setMinter(address _minter) external override onlyGovernance {\n if (_minter == address(0)) revert ZeroAddress();\n minter = _minter;\n emit MinterSet(_minter);\n }\n\n /// @notice Functions with this modifier can only be called by the minter;\n modifier onlyMinter() {\n if (msg.sender != minter) revert OnlyMinter();\n _;\n }\n}\n" + }, + "solidity/for-test/peripherals/DustCollectorForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/DustCollector.sol';\n\ncontract DustCollectorForTest is DustCollector {\n constructor() DustCollector() Governable(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rAccountanceForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rAccountance.sol';\n\ncontract Keep3rAccountanceForTest is Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor() Keep3rRoles(msg.sender) {}\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n\n function setKeeper(address keeper) external {\n _keepers.add(keeper);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableLiquidityForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol';\n\ncontract Keep3rJobFundableLiquidityForTest is Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external returns (bool) {\n return _jobLiquidities[_job].add(_liquidity);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewTickOrder(address _liquidity) external view returns (bool) {\n return _isKP3RToken0[_liquidity];\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function internalSettleJobAccountance(address _job) external {\n _settleJobAccountance(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobDisputable.sol';\n\ncontract Keep3rJobDisputableForTest is Keep3rJobDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function internalJobLiquidityCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobLiquidityCredits[_job];\n }\n\n function internalJobPeriodCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobPeriodCredits[_job];\n }\n\n function internalJobTokens(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobTokens[_job].length());\n for (uint256 i; i < _jobTokens[_job].length(); i++) {\n _tokens[i] = _jobTokens[_job].at(i);\n }\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobLiquidities[_job].length());\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n _tokens[i] = _jobLiquidities[_job].at(i);\n }\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rDisputable.sol';\n\ncontract Keep3rDisputableForTest is Keep3rDisputable {\n constructor() Keep3rParameters(address(0), address(0), address(0)) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperDisputable.sol';\n\ncontract Keep3rKeeperDisputableForTest is Keep3rKeeperDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function internalSlash(\n address _bonded,\n address _keeper,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external {\n _slash(_bonded, _keeper, _bondAmount, _unbondAmount);\n }\n\n function isKeeper(address _address) external view returns (bool _isKeeper) {\n _isKeeper = _keepers.contains(_address);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableCreditsForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableCredits.sol';\n\ncontract Keep3rJobFundableCreditsForTest is Keep3rJobFundableCredits {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job, address _jobOwner) external {\n _jobs.add(_job);\n jobOwner[_job] = _jobOwner;\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function isJobToken(address _job, address _token) external view returns (bool _contains) {\n _contains = _jobTokens[_job].contains(_token);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/IKeep3rHelper.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n /// @inheritdoc IKeep3rHelper\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelper\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\n // solhint-disable-next-line avoid-tx-origin\n return getRewardAmountFor(tx.origin, _gasUsed);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\n _bonds = Math.min(_bonds, targetBond);\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\n _rewardBoost = _cap * _getBasefee();\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\n }\n\n /// @inheritdoc IKeep3rHelper\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\n address _token0;\n address _token1;\n (_token0, _token1) = getPoolTokens(_pool);\n if (_token0 == KP3R) {\n return true;\n } else if (_token1 != KP3R) {\n revert LiquidityPairInvalid();\n }\n }\n\n /// @inheritdoc IKeep3rHelper\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n override\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n )\n {\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\n _tickCumulative1 = _uniswapResponse[0];\n if (_uniswapResponse.length > 1) {\n _tickCumulative2 = _uniswapResponse[1];\n }\n _success = true;\n } catch (bytes memory) {}\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n )\n {\n _oneEthQuote = quote(1 ether);\n _boost = getRewardBoostFor(_bonds);\n _extra = workExtraGas;\n }\n\n /// @inheritdoc IKeep3rHelper\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure override returns (uint256 _kp3rAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) public pure override returns (uint256 _quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\n }\n }\n\n /// @notice Gets the gas basefee cost to calculate keeper rewards\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTestnet is Keep3rHelper {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal pure override returns (uint256) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/Keep3rHelperForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTest is Keep3rHelper {\n uint256 public basefee;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governance,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {}\n\n function _getBasefee() internal view override returns (uint256) {\n return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee();\n }\n\n function setBaseFee(uint256 _baseFee) external {\n basefee = _baseFee;\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rHelper.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\n /// @inheritdoc IKeep3rHelperSidechain\n mapping(address => address) public override oracle;\n /// @inheritdoc IKeep3rHelperSidechain\n IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool;\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n address public immutable override WETH;\n\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\n /// @param _governance Address of governance\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\n /// @dev Oracle pools should use 18 decimals tokens\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) {\n WETH = _weth;\n wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth);\n _setQuoteTwapTime(1 days);\n workExtraGas = 0;\n }\n\n /// @inheritdoc IKeep3rHelper\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setOracle(address _liquidity, address _oracle) external override onlyGovernance {\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\n oracle[_liquidity] = _oracle;\n emit OracleSet(_liquidity, _oracle);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n /// @dev Oracle is compatible with IUniswapV3Pool\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setWethUsdPool(address _poolAddress) external override onlyGovernance {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setWethUsdPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override(Keep3rHelper, IKeep3rHelper)\n returns (\n uint256 _boost,\n uint256 _oneUsdQuote,\n uint256 _extraGas\n )\n {\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\n _boost = getRewardBoostFor(_bonds);\n _extraGas = workExtraGas;\n }\n\n function _setWethUsdPool(address _poolAddress) internal {\n wethUSDPool = _validateOraclePool(_poolAddress, WETH);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0);\n }\n\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechainForTestnet is Keep3rHelperSidechain {\n constructor(\n address _keep3rV2,\n address _governance,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle\n ) Keep3rHelperSidechain(_keep3rV2, _governance, _kp3r, _weth, _kp3rWethOracle, _wethUsdOracle) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rParametersForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rParameters.sol';\n\ncontract Keep3rParametersForTest is Keep3rParameters {\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobWorkableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobWorkable.sol';\n\ncontract Keep3rJobWorkableForTest is Keep3rJobWorkable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewGas() external view returns (uint256) {\n return _initialGas;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobMigrationForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobMigration.sol';\n\ncontract Keep3rJobMigrationForTest is Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(address => uint256) public settleJobAccountanceCallCount;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobTokenListLength(address _job) external view returns (uint256) {\n return _jobTokens[_job].length();\n }\n\n function viewJobLiquidityList(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewMigrationCreatedAt(address _fromJob, address _toJob) external view returns (uint256) {\n return _migrationCreatedAt[_fromJob][_toJob];\n }\n\n function isJob(address _job) external view returns (bool) {\n return _jobs.contains(_job);\n }\n\n function _settleJobAccountance(address _job) internal override {\n settleJobAccountanceCallCount[_job]++;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobManager.sol';\n\ncontract Keep3rJobManagerForTest is Keep3rJobManager {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rRoles(msg.sender) {}\n\n function isJob(address _job) external view returns (bool _isJob) {\n _isJob = _jobs.contains(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobOwnershipForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobOwnership.sol';\n\ncontract Keep3rJobOwnershipForTest is Keep3rJobOwnership {}\n" + }, + "solidity/for-test/libraries/LiquidityAmountsForTest.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/libraries/FullMath.sol';\nimport '../../contracts/libraries/FixedPoint96.sol';\n\n/// @dev Made this library into a contract to be able to calculate liquidity more precisely for tests\n\n// solhint-disable\ncontract LiquidityAmountsForTest {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) external pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) external pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/for-test/IUniswapV3PoolForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n// solhint-disable-next-line no-empty-blocks\ninterface IUniswapV3PoolForTest is IERC20Minimal, IUniswapV3Pool {\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Minimal ERC20 interface for Uniswap\n/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3\ninterface IERC20Minimal {\n /// @notice Returns the balance of a token\n /// @param account The account for which to look up the number of tokens it has, i.e. its balance\n /// @return The number of tokens held by the account\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Transfers the amount of token from the `msg.sender` to the recipient\n /// @param recipient The account that will receive the amount transferred\n /// @param amount The number of tokens to send from the sender to the recipient\n /// @return Returns true for a successful transfer, false for an unsuccessful transfer\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /// @notice Returns the current allowance given to a spender by an owner\n /// @param owner The account of the token owner\n /// @param spender The account of the token spender\n /// @return The current allowance granted by `owner` to `spender`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`\n /// @param spender The account which will be allowed to spend a given amount of the owners tokens\n /// @param amount The amount of tokens allowed to be used by `spender`\n /// @return Returns true for a successful approval, false for unsuccessful\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`\n /// @param sender The account from which the transfer will be initiated\n /// @param recipient The recipient of the transfer\n /// @param amount The amount of the transfer\n /// @return Returns true for a successful transfer, false for unsuccessful\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.\n /// @param from The account from which the tokens were sent, i.e. the balance decreased\n /// @param to The account to which the tokens were sent, i.e. the balance increased\n /// @param value The amount of tokens that were transferred\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.\n /// @param owner The account that approved spending of its tokens\n /// @param spender The account for which the spending allowance was modified\n /// @param value The new allowance from the owner to the spender\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 33 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimisticGoerli/wkLP.json b/deployments/optimisticGoerli/wkLP.json new file mode 100644 index 0000000..96691da --- /dev/null +++ b/deployments/optimisticGoerli/wkLP.json @@ -0,0 +1,189 @@ +{ + "address": "0xA437aC90d360c7645f25f30ddE201a94fe137Af5", + "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" + } + ], + "numDeployments": 3 +} \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 053dccc..0a162e0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,15 +24,15 @@ The Keep3r Network also supports staking in Optimism and Polygon, where the paym | Chain (`chainId`) | Implementation | Address | | -------- | -------- | -------- | | Ethereum (`1`) | Keep3r | `0xeb02addCfD8B773A5FFA6B9d1FE99c566f8c44CC` | -| Optimism (`10`) | Keep3rSidechain | `TBD` | +| Optimism (`10`) | Keep3rSidechain | `0x745a50320B6eB8FF281f1664Fc6713991661B129` | | Polygon (`137`) | Keep3rSidechain | `TBD` | #### Testnet environment | Chain (`chainId`) | Implementation | Address | | -------- | -------- | -------- | -| Goerli (`5`) | Keep3rForTestnet | `0x229d018065019c3164B899F4B9c2d4ffEae9B92b` | -| Goerli (`5`) | JobForTest | `0x214DfEBeEfd0BeE69Aba7F22Ea5438797879a4a4` | -| OPGoerli (`420`) | Keep3rSidechainForTestnet | `0x3C9636ab56aced6C845d6D13805901A0a0B13b51` | -| OPGoerli (`420`) | JobRatedForTest | `0x8276688087b581A9e9d18FD88FbB5E66bAa43682` | +| Goerli (`5`) | Keep3rForTestnet | `0x85063437C02Ba7F4f82F898859e4992380DEd3bb` | +| Goerli (`5`) | JobForTest | `0xa2c7A15FFc02e00cdeedBba56c41dAaed84f8734` | +| OPGoerli (`420`) | Keep3rSidechainForTestnet | `0x85063437C02Ba7F4f82F898859e4992380DEd3bb` | +| OPGoerli (`420`) | JobRatedForTest | `0x9abB5cfF47b9F604351a6f0730d9fe39Fb620B2b` | > ForTestnet implementations allow instant bonding and unbonding, and use a free-to-mint ERC20 as KP3Rv1. diff --git a/hardhat.config.ts b/hardhat.config.ts index b7d7a11..86307d4 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -20,6 +20,9 @@ const config: HardhatUserConfig = { hardhat: { hardfork: 'london', allowUnlimitedContractSize: true, + companionNetworks: { + mainnet: 'hardhat', + }, }, } : { @@ -33,6 +36,13 @@ const config: HardhatUserConfig = { url: process.env.MAINNET_HTTPS_URL, accounts: [process.env.MAINNET_PRIVATE_KEY as string], }, + optimisticEthereum: { + url: process.env.OPTIMISM_HTTPS_URL, + accounts: [process.env.OPTIMISM_PRIVATE_KEY as string], + companionNetworks: { + mainnet: 'mainnet', + }, + }, goerli: { url: process.env.GOERLI_HTTPS_URL, accounts: [process.env.GOERLI_PRIVATE_KEY as string], @@ -40,6 +50,9 @@ const config: HardhatUserConfig = { optimisticGoerli: { url: process.env.OP_GOERLI_HTTPS_URL, accounts: [process.env.OP_GOERLI_PRIVATE_KEY as string], + companionNetworks: { + mainnet: 'goerli', + }, }, }, solidity: { @@ -49,7 +62,7 @@ const config: HardhatUserConfig = { settings: { optimizer: { enabled: true, - runs: 33, + runs: 200, }, outputSelection: { '*': { @@ -71,6 +84,8 @@ const config: HardhatUserConfig = { etherscan: { apiKey: { mainnet: process.env.ETHERSCAN_API_KEY as string, + optimisticEthereum: process.env.OPTIMISTIC_ETHERSCAN_API_KEY as string, + goerli: process.env.GOERLI_ETHERSCAN_API_KEY as string, optimisticGoerli: process.env.OP_GOERLI_ETHERSCAN_API_KEY as string, }, }, diff --git a/package.json b/package.json index 48f4866..66616bb 100644 --- a/package.json +++ b/package.json @@ -38,11 +38,11 @@ "coverage": "TEST=true hardhat coverage", "docs": "./docgen.sh", "deploy": "hardhat deploy", - "deploy:testnet": "yarn deploy --network goerli --tags testnet-keep3r", - "deploy:testnet:job": "yarn deploy --network goerli --tags job-for-test", + "deploy:testnet": "yarn deploy --network goerli --tags job-for-test", "deploy:testnet:verify": "yarn deploy --network goerli --tags verify-testnet", - "deploy:sidechain:testnet": "yarn deploy --network optimisticGoerli --tags approve-testnet-liquidity", - "deploy:sidechain:testnet:job": "yarn deploy --network optimisticGoerli --tags job-rated-for-test", + "deploy:sidechain": "yarn deploy --network optimisticEthereum --tags keep3r-sidechain", + "deploy:sidechain:verify": "yarn deploy --network optimisticEthereum --tags verify-sidechain", + "deploy:sidechain:testnet": "yarn deploy --network optimisticGoerli --tags job-rated-for-test", "deploy:sidechain:testnet:verify": "yarn deploy --network optimisticGoerli --tags verify-sidechain-testnet", "fork:node": "cross-env FORK=true hardhat node", "fork:script": "cross-env FORK=true hardhat run", diff --git a/solidity/contracts/sidechain/Keep3rEscrow.sol b/solidity/contracts/sidechain/Keep3rEscrow.sol index a94be4b..797d07d 100644 --- a/solidity/contracts/sidechain/Keep3rEscrow.sol +++ b/solidity/contracts/sidechain/Keep3rEscrow.sol @@ -1,5 +1,22 @@ // SPDX-License-Identifier: MIT +/* + +Coded for The Keep3r Network with ♥ by + +██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░ +██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗ +██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║ +██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║ +██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝ +╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░ + +https://defi.sucks + +Commit hash: ead559c8dc4361349b7222741c2399447e255d8e + +*/ + pragma solidity >=0.8.4 <0.9.0; import '../peripherals/Mintable.sol'; diff --git a/solidity/contracts/sidechain/Keep3rHelperSidechain.sol b/solidity/contracts/sidechain/Keep3rHelperSidechain.sol index 60594da..dd9f304 100644 --- a/solidity/contracts/sidechain/Keep3rHelperSidechain.sol +++ b/solidity/contracts/sidechain/Keep3rHelperSidechain.sol @@ -1,5 +1,22 @@ // SPDX-License-Identifier: MIT +/* + +Coded for The Keep3r Network with ♥ by + +██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░ +██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗ +██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║ +██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║ +██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝ +╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░ + +https://defi.sucks + +Commit hash: ead559c8dc4361349b7222741c2399447e255d8e + +*/ + pragma solidity >=0.8.4 <0.9.0; import '../Keep3rHelper.sol'; diff --git a/solidity/contracts/sidechain/Keep3rSidechain.sol b/solidity/contracts/sidechain/Keep3rSidechain.sol index 39412f6..6b1b00c 100644 --- a/solidity/contracts/sidechain/Keep3rSidechain.sol +++ b/solidity/contracts/sidechain/Keep3rSidechain.sol @@ -13,6 +13,8 @@ Coded for The Keep3r Network with ♥ by https://defi.sucks +Commit hash: ead559c8dc4361349b7222741c2399447e255d8e + */ pragma solidity >=0.8.4 <0.9.0; diff --git a/solidity/for-test/JobRatedForTest.sol b/solidity/for-test/JobRatedForTest.sol index 514275e..0e31d02 100644 --- a/solidity/for-test/JobRatedForTest.sol +++ b/solidity/for-test/JobRatedForTest.sol @@ -8,7 +8,7 @@ contract JobRatedForTest { error InvalidKeeper(); address public keep3r; uint256 public nonce; - uint256 public usdPerGasUnit = 1_000e9; + uint256 public usdPerGasUnit = 1; constructor(address _keep3r) { keep3r = _keep3r; diff --git a/solidity/for-test/testnet/Keep3rHelperForTestnet.sol b/solidity/for-test/testnet/Keep3rHelperForTestnet.sol index ab0bc57..221196a 100644 --- a/solidity/for-test/testnet/Keep3rHelperForTestnet.sol +++ b/solidity/for-test/testnet/Keep3rHelperForTestnet.sol @@ -14,14 +14,4 @@ contract Keep3rHelperForTestnet is Keep3rHelper { function _getBasefee() internal pure override returns (uint256) { return 1; } - - /// @dev Overrides oracle validation that uses KP3R and WETH addresses - function _validateOraclePool(address _poolAddress, address) internal view virtual override returns (TokenOraclePool memory _oraclePool) { - return TokenOraclePool(_poolAddress, true); - } - - /// @dev Overrides token comparison with KP3R address - function isKP3RToken0(address) public view virtual override returns (bool) { - return true; - } } diff --git a/solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol b/solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol deleted file mode 100644 index 11589ba..0000000 --- a/solidity/for-test/testnet/Keep3rHelperSidechainForTestnet.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.4 <0.9.0; - -import '../../contracts/sidechain/Keep3rHelperSidechain.sol'; - -contract Keep3rHelperSidechainForTestnet is Keep3rHelperSidechain { - constructor( - address _keep3rV2, - address _governance, - address _kp3r, - address _weth, - address _kp3rWethOracle, - address _wethUsdOracle - ) Keep3rHelperSidechain(_keep3rV2, _governance, _kp3r, _weth, _kp3rWethOracle, _wethUsdOracle) {} - - /// @dev Overrides oracle validation that uses KP3R and WETH addresses - function _validateOraclePool(address _poolAddress, address) internal view virtual override returns (TokenOraclePool memory _oraclePool) { - return TokenOraclePool(_poolAddress, true); - } - - /// @dev Overrides token comparison with KP3R address - function isKP3RToken0(address) public view virtual override returns (bool) { - return true; - } - - function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256) { - return _usd / 1000; - } -} diff --git a/test/e2e/deployment-fixtures.spec.ts b/test/e2e/deployment-fixtures.spec.ts index d597828..35f3660 100644 --- a/test/e2e/deployment-fixtures.spec.ts +++ b/test/e2e/deployment-fixtures.spec.ts @@ -189,7 +189,7 @@ describe('@skip-on-coverage Fixture', () => { kp3rV1 = (await getContractFromFixture('KP3Rv1', 'ERC20')) as Type.ERC20ForTest; keep3r = (await getContractFromFixture('Keep3rSidechainForTestnet')) as Type.Keep3r; const keep3rEscrow = (await getContractFromFixture('Keep3rEscrow')) as Type.Keep3rEscrow; - const keep3rHelper = (await getContractFromFixture('Keep3rHelperSidechainForTestnet')) as Type.Keep3rHelperSidechain; + const keep3rHelper = (await getContractFromFixture('Keep3rHelperSidechain')) as Type.Keep3rHelperSidechain; const kp3rWethOracle = await getContractFromFixture('Kp3rWethOracle', 'IUniswapV3Pool'); // instant keeper activation @@ -197,6 +197,7 @@ describe('@skip-on-coverage Fixture', () => { await keep3r.activate(kp3rV1.address); wkLP = kp3rV1; // uses KP3Rv1 as wkLP (hardhat environment) + await keep3rEscrow.setMinter(keep3r.address); await keep3rHelper.setOracle(wkLP.address, kp3rWethOracle.address); await keep3r.approveLiquidity(wkLP.address); @@ -207,6 +208,7 @@ describe('@skip-on-coverage Fixture', () => { const jobForTest = await common.createJobRatedForTest(keep3r.address, signer); await keep3r.addJob(jobForTest.address); + await evm.advanceTimeAndBlock(5 * 86400); await common.forceCreditsToJob(keep3r, jobForTest.address); await jobForTest.work(); @@ -231,10 +233,10 @@ describe('@skip-on-coverage Fixture', () => { it('should deploy a workable job', async () => { await kp3rV1.connect(whale).transfer(signer.address, toUnit(100)); + await evm.advanceTimeAndBlock(86400); await deployments.fixture(['job-rated-for-test'], { keepExistingDeployments: true }); const jobForTest = (await getContractFromFixture('BasicJob', 'JobRatedForTest')) as Type.BasicJob; - await evm.advanceTimeAndBlock(86400); await jobForTest.work(); }); }); diff --git a/utils/constants.ts b/utils/constants.ts index dd54233..c5a2874 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -2,12 +2,14 @@ export const addressRegistry = { // TOKENS kp3rV1: { 1: '0x1ceb5cb57c4d4e2b2433641b95dd330a33185a44', // Keep3rV1 + 10: '0x3975e0292bEF3Fca8feF414f01E120652Ac60A69', // nextKP3R 5: '0x16F63C5036d3F48A239358656a8f123eCE85789C', // KP3RforTest 420: '0x3Db593146464816F10d4eBA4743C76A5A4D08425', // wKP3RforTest 31337: '0x1ceb5cb57c4d4e2b2433641b95dd330a33185a44', }, weth: { 1: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + 10: '0x4200000000000000000000000000000000000006', 5: '0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6', 420: '0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6', 31337: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', @@ -17,9 +19,15 @@ export const addressRegistry = { 5: '0x16F63C5036d3F48A239358656a8f123eCE85789C', // KP3RforTest 31337: '0x976b01c02c636Dd5901444B941442FD70b86dcd5', }, + wkLP: { + 10: '0xAfe2Bbc98AF9fcFf73596Ebe1327B27d8A16d06b', // nextKLP + 420: '0xA437aC90d360c7645f25f30ddE201a94fe137Af5', // wkLP + 31337: '0x1ceb5cb57c4d4e2b2433641b95dd330a33185a44', // kLP + }, // GOVERNANCE governor: { 1: '0x0D5Dc686d0a2ABBfDaFDFb4D0533E886517d4E83', + 10: '0x7d6daDb31dBeBc68c8A0b2cCfE5C1f26F24bD41d', 5: 0, // deployer 420: 0, 31337: 0, @@ -27,11 +35,13 @@ export const addressRegistry = { // ORACLES kp3rWethOracle: { 1: '0x11b7a6bc0259ed6cf9db8f499988f9ecc7167bf5', // UniV3Pool - 5: '0x050BBA5E4abde750Ea5610D8412cD46171C665e7', // UniV3Pool + 10: '0x4Ab2c969C64302e5d931e5cEf4755392DC005604', // SidechainOracle + 5: '0x317ceCd3eB02158f97DF0B67B788edCda4E066e5', // UniV3Pool 420: '0x4ECFF2c532d47D7be3D957E4a332AB134cad1fd9', // SidechainOracle 31337: '0x11b7a6bc0259ed6cf9db8f499988f9ecc7167bf5', }, wethUsdOracle: { + 10: '0x03af20bdaaffb4cc0a521796a223f7d85e2aac31', // WETH-DAI 0.3% 420: '0x4ECFF2c532d47D7be3D957E4a332AB134cad1fd9', // SidechainOracle 31337: '0x60594a405d53811d3bc4766596efd80fd545a270', // UniV3Pool }, From 70c8619abd9d85192f76c76785efde37bdea9c4d Mon Sep 17 00:00:00 2001 From: 0xJabberwock <102967621+0xJabberwock@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:46:32 -0300 Subject: [PATCH 2/4] feat: added @defi-wonderland/solidity-utils * feat: added @defi-wonderland/solidity-utils * feat: docgen (+ import order) * feat: moved IBaseErrors.sol to @defi-wonderland/solidity-utils * fix: governance() vs governor() --- docs/technical/IKeep3rHelperParameters.md | 3 + docs/technical/IUniV3PairManager.md | 2 +- docs/technical/external/IKeep3rV1Proxy.md | 24 ++++++ docs/technical/peripherals/IBaseErrors.md | 10 --- docs/technical/peripherals/IDustCollector.md | 24 ------ docs/technical/peripherals/IGovernable.md | 51 ------------ .../peripherals/IKeep3rAccountance.md | 7 ++ .../peripherals/IKeep3rDisputable.md | 4 +- .../peripherals/IKeep3rJobDisputable.md | 4 +- .../peripherals/IKeep3rKeeperDisputable.md | 2 +- .../peripherals/IKeep3rParameters.md | 2 +- docs/technical/peripherals/IMintable.md | 2 +- .../sidechain/IKeep3rSidechainAccountance.md | 7 -- hardhat.config.ts | 2 +- package.json | 3 +- solidity/contracts/Keep3r.sol | 6 +- solidity/contracts/Keep3rHelper.sol | 4 +- solidity/contracts/Keep3rHelperParameters.sol | 26 +++--- solidity/contracts/UniV3PairManager.sol | 9 +-- .../contracts/UniV3PairManagerFactory.sol | 6 +- .../contracts/peripherals/DustCollector.sol | 28 ------- solidity/contracts/peripherals/Governable.sol | 42 ---------- .../peripherals/Keep3rParameters.sol | 18 ++--- .../contracts/peripherals/Keep3rRoles.sol | 14 ++-- solidity/contracts/peripherals/Mintable.sol | 6 +- .../peripherals/jobs/Keep3rJobDisputable.sol | 4 +- .../jobs/Keep3rJobFundableCredits.sol | 2 +- .../jobs/Keep3rJobFundableLiquidity.sol | 6 +- .../keepers/Keep3rKeeperDisputable.sol | 2 +- solidity/contracts/sidechain/Keep3rEscrow.sol | 8 +- .../sidechain/Keep3rHelperSidechain.sol | 10 +-- .../contracts/sidechain/Keep3rSidechain.sol | 8 +- solidity/for-test/Keep3rForTest.sol | 4 +- solidity/for-test/Keep3rHelperForTest.sol | 4 +- solidity/for-test/Keep3rSidechainForTest.sol | 4 +- solidity/for-test/UniV3PairManagerForTest.sol | 2 +- .../peripherals/DustCollectorForTest.sol | 8 -- .../peripherals/GovernableForTest.sol | 8 -- .../for-test/testnet/Keep3rForTestnet.sol | 4 +- .../testnet/Keep3rHelperForTestnet.sol | 4 +- .../testnet/Keep3rSidechainForTestnet.sol | 4 +- solidity/interfaces/IPairManagerFactory.sol | 2 +- solidity/interfaces/IUniV3PairManager.sol | 4 +- .../interfaces/external/IKeep3rV1Proxy.sol | 15 +++- .../interfaces/peripherals/IBaseErrors.sol | 8 -- .../interfaces/peripherals/IDustCollector.sol | 23 ------ .../interfaces/peripherals/IGovernable.sol | 46 ----------- .../peripherals/IKeep3rDisputable.sol | 4 +- .../interfaces/peripherals/IKeep3rJobs.sol | 4 +- .../interfaces/peripherals/IKeep3rKeepers.sol | 2 +- .../peripherals/IKeep3rParameters.sol | 4 +- .../interfaces/peripherals/IKeep3rRoles.sol | 8 +- solidity/interfaces/peripherals/IMintable.sol | 6 +- test/e2e/basic-job.spec.ts | 14 ++-- test/e2e/common.ts | 28 +++---- test/e2e/deployment-fixtures.spec.ts | 11 ++- test/e2e/job.spec.ts | 10 +-- test/e2e/keep3r-escrow.spec.ts | 18 ++--- test/e2e/keep3r-multichain.spec.ts | 16 ++-- test/e2e/keeper-job-interaction.spec.ts | 10 +-- test/e2e/keeper.spec.ts | 6 +- test/e2e/univ3-pair-factory.spec.ts | 10 +-- test/e2e/univ3-pair-manager.spec.ts | 24 +++--- test/unit/Keep3r.spec.ts | 10 +-- test/unit/Keep3rHelper.spec.ts | 15 ++-- test/unit/Keep3rHelperParameters.spec.ts | 38 ++++----- test/unit/UniV3PairFactory.spec.ts | 10 +-- test/unit/UniV3PairManager.spec.ts | 76 +++++++++--------- test/unit/peripherals/DustCollector.spec.ts | 80 ------------------- test/unit/peripherals/Governable.spec.ts | 71 ---------------- .../unit/peripherals/Keep3rParameters.spec.ts | 9 ++- test/unit/peripherals/Keep3rRoles.spec.ts | 45 ++++++----- .../jobs/Keep3rJobDisputable.spec.ts | 20 ++--- .../jobs/Keep3rJobFundableCredits.spec.ts | 8 +- .../jobs/Keep3rJobFundableLiquidity.spec.ts | 52 ++++++------ .../keepers/Keep3rKeeperDisputable.spec.ts | 8 +- test/unit/sidechain/Keep3rEscrow.spec.ts | 34 ++++---- .../sidechain/Keep3rHelperSidechain.spec.ts | 42 +++++----- test/unit/sidechain/Keep3rSidechain.spec.ts | 39 ++++----- test/utils/behaviours.ts | 4 +- yarn.lock | 37 +++++++-- 81 files changed, 466 insertions(+), 793 deletions(-) delete mode 100644 docs/technical/peripherals/IBaseErrors.md delete mode 100644 docs/technical/peripherals/IDustCollector.md delete mode 100644 docs/technical/peripherals/IGovernable.md delete mode 100644 solidity/contracts/peripherals/DustCollector.sol delete mode 100644 solidity/contracts/peripherals/Governable.sol delete mode 100644 solidity/for-test/peripherals/DustCollectorForTest.sol delete mode 100644 solidity/for-test/peripherals/GovernableForTest.sol delete mode 100644 solidity/interfaces/peripherals/IBaseErrors.sol delete mode 100644 solidity/interfaces/peripherals/IDustCollector.sol delete mode 100644 solidity/interfaces/peripherals/IGovernable.sol delete mode 100644 test/unit/peripherals/DustCollector.spec.ts delete mode 100644 test/unit/peripherals/Governable.spec.ts diff --git a/docs/technical/IKeep3rHelperParameters.md b/docs/technical/IKeep3rHelperParameters.md index a56f7e3..5423636 100644 --- a/docs/technical/IKeep3rHelperParameters.md +++ b/docs/technical/IKeep3rHelperParameters.md @@ -221,3 +221,6 @@ address poolAddress bool isTKNToken0 + + + diff --git a/docs/technical/IUniV3PairManager.md b/docs/technical/IUniV3PairManager.md index c0f1589..9a3d1b7 100644 --- a/docs/technical/IUniV3PairManager.md +++ b/docs/technical/IUniV3PairManager.md @@ -75,7 +75,7 @@ Returns the pair manager's position in the corresponding UniswapV3 pool -The collected fees will be sent to governance +The collected fees will be sent to governor ### `burn(uint128 liquidity, uint256 amount0Min, uint256 amount1Min, address to) → uint256 amount0, uint256 amount1` (external) diff --git a/docs/technical/external/IKeep3rV1Proxy.md b/docs/technical/external/IKeep3rV1Proxy.md index 2d585f0..91e626f 100644 --- a/docs/technical/external/IKeep3rV1Proxy.md +++ b/docs/technical/external/IKeep3rV1Proxy.md @@ -11,6 +11,18 @@ +### `governance() → address` (external) + + + + + +### `pendingGovernance() → address` (external) + + + + + ### `minter() → address` (external) @@ -83,6 +95,18 @@ +### `setGovernance(address _governance)` (external) + + + + + +### `acceptGovernance()` (external) + + + + + ### `setKeep3rV1Governance(address _governance)` (external) diff --git a/docs/technical/peripherals/IBaseErrors.md b/docs/technical/peripherals/IBaseErrors.md deleted file mode 100644 index 3378fd4..0000000 --- a/docs/technical/peripherals/IBaseErrors.md +++ /dev/null @@ -1,10 +0,0 @@ -## `IBaseErrors` - - - - - - - - - diff --git a/docs/technical/peripherals/IDustCollector.md b/docs/technical/peripherals/IDustCollector.md deleted file mode 100644 index 33643d9..0000000 --- a/docs/technical/peripherals/IDustCollector.md +++ /dev/null @@ -1,24 +0,0 @@ -## `IDustCollector` - - - - - - -### `sendDust(address _token, uint256 _amount, address _to)` (external) - -Allows an authorized user to transfer the tokens or eth that may have been left in a contract - - - - - -### `DustSent(address _token, uint256 _amount, address _to)` - -Emitted when dust is sent - - - - - - diff --git a/docs/technical/peripherals/IGovernable.md b/docs/technical/peripherals/IGovernable.md deleted file mode 100644 index 6fe6f9d..0000000 --- a/docs/technical/peripherals/IGovernable.md +++ /dev/null @@ -1,51 +0,0 @@ -## `IGovernable` - -Manages the governance role - - - - -### `governance() → address _governance` (external) - -Stores the governance address - - - - -### `pendingGovernance() → address _pendingGovernance` (external) - -Stores the pendingGovernance address - - - - -### `setGovernance(address _governance)` (external) - -Proposes a new address to be governance - - - - -### `acceptGovernance()` (external) - -Changes the governance from the current governance to the previously proposed address - - - - -### `GovernanceSet(address _governance)` - -Emitted when pendingGovernance accepts to be governance - - - - -### `GovernanceProposal(address _pendingGovernance)` - -Emitted when a new governance is proposed - - - - - - diff --git a/docs/technical/peripherals/IKeep3rAccountance.md b/docs/technical/peripherals/IKeep3rAccountance.md index 6a64579..e0ec646 100644 --- a/docs/technical/peripherals/IKeep3rAccountance.md +++ b/docs/technical/peripherals/IKeep3rAccountance.md @@ -6,6 +6,13 @@ Disputes keepers, or if they're already disputed, it can resolve the case Argument `bonding` can be the address of either a token or a liquidity +### `totalBonds() → uint256 _totalBonds` (external) + +Tracks the total amount of bonded KP3Rs in the contract + + + + ### `workCompleted(address _keeper) → uint256 _workCompleted` (external) Tracks the total KP3R earnings of a keeper since it started working diff --git a/docs/technical/peripherals/IKeep3rDisputable.md b/docs/technical/peripherals/IKeep3rDisputable.md index aff4db9..16d1a93 100644 --- a/docs/technical/peripherals/IKeep3rDisputable.md +++ b/docs/technical/peripherals/IKeep3rDisputable.md @@ -9,14 +9,14 @@ Creates/resolves disputes for jobs or keepers ### `dispute(address _jobOrKeeper)` (external) -Allows governance to create a dispute for a given keeper/job +Allows governor to create a dispute for a given keeper/job ### `resolve(address _jobOrKeeper)` (external) -Allows governance to resolve a dispute on a keeper/job +Allows governor to resolve a dispute on a keeper/job diff --git a/docs/technical/peripherals/IKeep3rJobDisputable.md b/docs/technical/peripherals/IKeep3rJobDisputable.md index 8c2ff2d..b4bcab1 100644 --- a/docs/technical/peripherals/IKeep3rJobDisputable.md +++ b/docs/technical/peripherals/IKeep3rJobDisputable.md @@ -7,14 +7,14 @@ Handles the actions that can be taken on a disputed job ### `slashTokenFromJob(address _job, address _token, uint256 _amount)` (external) -Allows governance or slasher to slash a job specific token +Allows governor or slasher to slash a job specific token ### `slashLiquidityFromJob(address _job, address _liquidity, uint256 _amount)` (external) -Allows governance or a slasher to slash liquidity from a job +Allows governor or slasher to slash liquidity from a job diff --git a/docs/technical/peripherals/IKeep3rKeeperDisputable.md b/docs/technical/peripherals/IKeep3rKeeperDisputable.md index 7dee70c..f58c8fe 100644 --- a/docs/technical/peripherals/IKeep3rKeeperDisputable.md +++ b/docs/technical/peripherals/IKeep3rKeeperDisputable.md @@ -7,7 +7,7 @@ Handles the actions that can be taken on a disputed keeper ### `slash(address _keeper, address _bonded, uint256 _bondAmount, uint256 _unbondAmount)` (external) -Allows governance to slash a keeper based on a dispute +Allows governor to slash a keeper based on a dispute diff --git a/docs/technical/peripherals/IKeep3rParameters.md b/docs/technical/peripherals/IKeep3rParameters.md index 08a4770..870aba3 100644 --- a/docs/technical/peripherals/IKeep3rParameters.md +++ b/docs/technical/peripherals/IKeep3rParameters.md @@ -63,7 +63,7 @@ The inflation period is the denominator used to regulate the emission of KP3R ### `fee() → uint256 _amount` (external) -The fee to be sent to governance when a user adds liquidity to a job +The fee to be sent to governor when a user adds liquidity to a job diff --git a/docs/technical/peripherals/IMintable.md b/docs/technical/peripherals/IMintable.md index 00f271b..e7dda76 100644 --- a/docs/technical/peripherals/IMintable.md +++ b/docs/technical/peripherals/IMintable.md @@ -22,7 +22,7 @@ Sets a new address to be the minter ### `MinterSet(address _minter)` -Emitted when governance sets a new minter +Emitted when governor sets a new minter diff --git a/docs/technical/sidechain/IKeep3rSidechainAccountance.md b/docs/technical/sidechain/IKeep3rSidechainAccountance.md index c574fc1..80bbae6 100644 --- a/docs/technical/sidechain/IKeep3rSidechainAccountance.md +++ b/docs/technical/sidechain/IKeep3rSidechainAccountance.md @@ -5,13 +5,6 @@ Implements a view to get the amount of credits that can be withdrawn -### `totalBonds() → uint256 _totalBonds` (external) - -The total amount of bonded wKP3Rs in the contract - - - - ### `virtualReserves() → int256 _virtualReserves` (external) The surplus amount of wKP3Rs in escrow contract diff --git a/hardhat.config.ts b/hardhat.config.ts index 86307d4..97ad22c 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -58,7 +58,7 @@ const config: HardhatUserConfig = { solidity: { compilers: [ { - version: '0.8.7', + version: '0.8.8', settings: { optimizer: { enabled: true, diff --git a/package.json b/package.json index 66616bb..c85708f 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "@solidity-parser/parser": "0.13.2" }, "dependencies": { + "@defi-wonderland/solidity-utils": "0.0.0-6c86c0fc", "@openzeppelin/contracts": "4.3.0" }, "devDependencies": { @@ -125,7 +126,7 @@ "prettier": "2.3.1", "prettier-plugin-organize-imports": "2.3.3", "prettier-plugin-solidity": "1.0.0-beta.13", - "solc-0.8": "npm:solc@0.8.7-fixed", + "solc-0.8": "npm:solc@0.8.8", "solhint": "3.3.6", "solhint-plugin-prettier": "0.0.5", "solidity-coverage": "0.7.16", diff --git a/solidity/contracts/Keep3r.sol b/solidity/contracts/Keep3r.sol index 4103956..c5385f1 100644 --- a/solidity/contracts/Keep3r.sol +++ b/solidity/contracts/Keep3r.sol @@ -20,13 +20,13 @@ pragma solidity >=0.8.4 <0.9.0; import '../interfaces/IKeep3r.sol'; import './peripherals/jobs/Keep3rJobs.sol'; import './peripherals/keepers/Keep3rKeepers.sol'; -import './peripherals/DustCollector.sol'; +import '@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol'; contract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers { constructor( - address _governance, + address _governor, address _keep3rHelper, address _keep3rV1, address _keep3rV1Proxy - ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governance) {} + ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governor) {} } diff --git a/solidity/contracts/Keep3rHelper.sol b/solidity/contracts/Keep3rHelper.sol index 55a93f3..5d6537e 100644 --- a/solidity/contracts/Keep3rHelper.sol +++ b/solidity/contracts/Keep3rHelper.sol @@ -30,9 +30,9 @@ contract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters { constructor( address _kp3r, address _keep3rV2, - address _governance, + address _governor, address _kp3rWethPool - ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {} + ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governor, _kp3rWethPool) {} /// @inheritdoc IKeep3rHelper function quote(uint256 _eth) public view override returns (uint256 _amountOut) { diff --git a/solidity/contracts/Keep3rHelperParameters.sol b/solidity/contracts/Keep3rHelperParameters.sol index 1efa88b..61c8c50 100644 --- a/solidity/contracts/Keep3rHelperParameters.sol +++ b/solidity/contracts/Keep3rHelperParameters.sol @@ -3,15 +3,15 @@ pragma solidity >=0.8.7 <0.9.0; import './libraries/FullMath.sol'; import './libraries/TickMath.sol'; -import '../interfaces/peripherals/IBaseErrors.sol'; import '../interfaces/IKeep3r.sol'; import '../interfaces/external/IKeep3rV1.sol'; import '../interfaces/IKeep3rHelperParameters.sol'; -import './peripherals/Governable.sol'; import './Keep3rHelperParameters.sol'; import '@openzeppelin/contracts/utils/math/Math.sol'; import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; +import '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol'; +import '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol'; contract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable { /// @inheritdoc IKeep3rHelperParameters @@ -50,9 +50,9 @@ contract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governa constructor( address _kp3r, address _keep3rV2, - address _governance, + address _governor, address _kp3rWethPool - ) Governable(_governance) { + ) Governable(_governor) { KP3R = _kp3r; keep3rV2 = _keep3rV2; @@ -62,44 +62,44 @@ contract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governa } /// @inheritdoc IKeep3rHelperParameters - function setKp3rWethPool(address _poolAddress) external override onlyGovernance { + function setKp3rWethPool(address _poolAddress) external override onlyGovernor { if (_poolAddress == address(0)) revert ZeroAddress(); _setKp3rWethPool(_poolAddress); } /// @inheritdoc IKeep3rHelperParameters - function setMinBoost(uint256 _minBoost) external override onlyGovernance { + function setMinBoost(uint256 _minBoost) external override onlyGovernor { minBoost = _minBoost; emit MinBoostChange(minBoost); } /// @inheritdoc IKeep3rHelperParameters - function setMaxBoost(uint256 _maxBoost) external override onlyGovernance { + function setMaxBoost(uint256 _maxBoost) external override onlyGovernor { maxBoost = _maxBoost; emit MaxBoostChange(maxBoost); } /// @inheritdoc IKeep3rHelperParameters - function setTargetBond(uint256 _targetBond) external override onlyGovernance { + function setTargetBond(uint256 _targetBond) external override onlyGovernor { targetBond = _targetBond; emit TargetBondChange(targetBond); } /// @inheritdoc IKeep3rHelperParameters - function setKeep3rV2(address _keep3rV2) external override onlyGovernance { + function setKeep3rV2(address _keep3rV2) external override onlyGovernor { if (_keep3rV2 == address(0)) revert ZeroAddress(); keep3rV2 = _keep3rV2; emit Keep3rV2Change(keep3rV2); } /// @inheritdoc IKeep3rHelperParameters - function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernance { + function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernor { workExtraGas = _workExtraGas; emit WorkExtraGasChange(workExtraGas); } /// @inheritdoc IKeep3rHelperParameters - function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernance { + function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernor { _setQuoteTwapTime(_quoteTwapTime); } @@ -109,13 +109,13 @@ contract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governa } /// @inheritdoc IKeep3rHelperParameters - function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernance { + function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernor { minBaseFee = _minBaseFee; emit MinBaseFeeChange(minBaseFee); } /// @inheritdoc IKeep3rHelperParameters - function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernance { + function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernor { minPriorityFee = _minPriorityFee; emit MinPriorityFeeChange(minPriorityFee); } diff --git a/solidity/contracts/UniV3PairManager.sol b/solidity/contracts/UniV3PairManager.sol index 805bab8..2b1616f 100644 --- a/solidity/contracts/UniV3PairManager.sol +++ b/solidity/contracts/UniV3PairManager.sol @@ -17,6 +17,7 @@ https://defi.sucks pragma solidity >=0.8.4 <0.9.0; +import '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol'; import '@openzeppelin/contracts/token/ERC20/ERC20.sol'; import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; @@ -28,8 +29,6 @@ import './libraries/TickMath.sol'; import '../interfaces/external/IWeth9.sol'; import '../interfaces/IUniV3PairManager.sol'; -import './peripherals/Governable.sol'; - contract UniV3PairManager is IUniV3PairManager, Governable { /// @inheritdoc IERC20Metadata string public override name; @@ -87,7 +86,7 @@ contract UniV3PairManager is IUniV3PairManager, Governable { /// @notice Struct that contains token0, token1, and fee of the Uniswap pool PoolKey private _poolKey; - constructor(address _pool, address _governance) Governable(_governance) { + constructor(address _pool, address _governor) Governable(_governor) { uint24 _fee = IUniswapV3Pool(_pool).fee(); address _token0 = IUniswapV3Pool(_pool).token0(); address _token1 = IUniswapV3Pool(_pool).token1(); @@ -152,11 +151,11 @@ contract UniV3PairManager is IUniV3PairManager, Governable { } /// @inheritdoc IUniV3PairManager - function collect() external override onlyGovernance returns (uint256 amount0, uint256 amount1) { + function collect() external override onlyGovernor returns (uint256 amount0, uint256 amount1) { (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions( keccak256(abi.encodePacked(address(this), tickLower, tickUpper)) ); - (amount0, amount1) = IUniswapV3Pool(pool).collect(governance, tickLower, tickUpper, tokensOwed0, tokensOwed1); + (amount0, amount1) = IUniswapV3Pool(pool).collect(governor, tickLower, tickUpper, tokensOwed0, tokensOwed1); } /// @inheritdoc IUniV3PairManager diff --git a/solidity/contracts/UniV3PairManagerFactory.sol b/solidity/contracts/UniV3PairManagerFactory.sol index da94efb..369d508 100644 --- a/solidity/contracts/UniV3PairManagerFactory.sol +++ b/solidity/contracts/UniV3PairManagerFactory.sol @@ -19,19 +19,19 @@ pragma solidity >=0.8.4 <0.9.0; import '../interfaces/IPairManagerFactory.sol'; import './UniV3PairManager.sol'; -import './peripherals/Governable.sol'; +import '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol'; /// @title Factory of Pair Managers /// @notice This contract creates new pair managers contract UniV3PairManagerFactory is IPairManagerFactory, Governable { mapping(address => address) public override pairManagers; - constructor(address _governance) Governable(_governance) {} + constructor(address _governor) Governable(_governor) {} ///@inheritdoc IPairManagerFactory function createPairManager(address _pool) external override returns (address _pairManager) { if (pairManagers[_pool] != address(0)) revert AlreadyInitialized(); - _pairManager = address(new UniV3PairManager(_pool, governance)); + _pairManager = address(new UniV3PairManager(_pool, governor)); pairManagers[_pool] = _pairManager; emit PairCreated(_pool, _pairManager); } diff --git a/solidity/contracts/peripherals/DustCollector.sol b/solidity/contracts/peripherals/DustCollector.sol deleted file mode 100644 index 3cb8ec2..0000000 --- a/solidity/contracts/peripherals/DustCollector.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity >=0.8.4 <0.9.0; - -import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; -import '../../contracts/peripherals/Governable.sol'; -import '../../interfaces/peripherals/IDustCollector.sol'; - -abstract contract DustCollector is IDustCollector, Governable { - using SafeERC20 for IERC20; - - address internal constant _ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; - - function sendDust( - address _token, - uint256 _amount, - address _to - ) external override onlyGovernance { - if (_to == address(0)) revert ZeroAddress(); - if (_token == _ETH_ADDRESS) { - payable(_to).transfer(_amount); - } else { - IERC20(_token).safeTransfer(_to, _amount); - } - emit DustSent(_token, _amount, _to); - } -} diff --git a/solidity/contracts/peripherals/Governable.sol b/solidity/contracts/peripherals/Governable.sol deleted file mode 100644 index 00ce330..0000000 --- a/solidity/contracts/peripherals/Governable.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.4 <0.9.0; - -import '../../interfaces/peripherals/IGovernable.sol'; - -abstract contract Governable is IGovernable { - /// @inheritdoc IGovernable - address public override governance; - - /// @inheritdoc IGovernable - address public override pendingGovernance; - - constructor(address _governance) { - if (_governance == address(0)) revert NoGovernanceZeroAddress(); - governance = _governance; - } - - /// @inheritdoc IGovernable - function setGovernance(address _governance) external override onlyGovernance { - pendingGovernance = _governance; - emit GovernanceProposal(_governance); - } - - /// @inheritdoc IGovernable - function acceptGovernance() external override onlyPendingGovernance { - governance = pendingGovernance; - delete pendingGovernance; - emit GovernanceSet(governance); - } - - /// @notice Functions with this modifier can only be called by governance - modifier onlyGovernance { - if (msg.sender != governance) revert OnlyGovernance(); - _; - } - - /// @notice Functions with this modifier can only be called by pendingGovernance - modifier onlyPendingGovernance { - if (msg.sender != pendingGovernance) revert OnlyPendingGovernance(); - _; - } -} diff --git a/solidity/contracts/peripherals/Keep3rParameters.sol b/solidity/contracts/peripherals/Keep3rParameters.sol index fd93727..1992b0c 100644 --- a/solidity/contracts/peripherals/Keep3rParameters.sol +++ b/solidity/contracts/peripherals/Keep3rParameters.sol @@ -51,14 +51,14 @@ abstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance { } /// @inheritdoc IKeep3rParameters - function setKeep3rHelper(address _keep3rHelper) external override onlyGovernance { + function setKeep3rHelper(address _keep3rHelper) external override onlyGovernor { if (_keep3rHelper == address(0)) revert ZeroAddress(); keep3rHelper = _keep3rHelper; emit Keep3rHelperChange(_keep3rHelper); } /// @inheritdoc IKeep3rParameters - function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernance { + function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernor { if (_keep3rV1 == address(0)) revert ZeroAddress(); _mint(totalBonds); @@ -67,45 +67,45 @@ abstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance { } /// @inheritdoc IKeep3rParameters - function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernance { + function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernor { if (_keep3rV1Proxy == address(0)) revert ZeroAddress(); keep3rV1Proxy = _keep3rV1Proxy; emit Keep3rV1ProxyChange(_keep3rV1Proxy); } /// @inheritdoc IKeep3rParameters - function setBondTime(uint256 _bondTime) external override onlyGovernance { + function setBondTime(uint256 _bondTime) external override onlyGovernor { bondTime = _bondTime; emit BondTimeChange(_bondTime); } /// @inheritdoc IKeep3rParameters - function setUnbondTime(uint256 _unbondTime) external override onlyGovernance { + function setUnbondTime(uint256 _unbondTime) external override onlyGovernor { unbondTime = _unbondTime; emit UnbondTimeChange(_unbondTime); } /// @inheritdoc IKeep3rParameters - function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernance { + function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernor { liquidityMinimum = _liquidityMinimum; emit LiquidityMinimumChange(_liquidityMinimum); } /// @inheritdoc IKeep3rParameters - function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernance { + function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernor { if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod(); rewardPeriodTime = _rewardPeriodTime; emit RewardPeriodTimeChange(_rewardPeriodTime); } /// @inheritdoc IKeep3rParameters - function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernance { + function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernor { inflationPeriod = _inflationPeriod; emit InflationPeriodChange(_inflationPeriod); } /// @inheritdoc IKeep3rParameters - function setFee(uint256 _fee) external override onlyGovernance { + function setFee(uint256 _fee) external override onlyGovernor { fee = _fee; emit FeeChange(_fee); } diff --git a/solidity/contracts/peripherals/Keep3rRoles.sol b/solidity/contracts/peripherals/Keep3rRoles.sol index e84ccf9..5726c51 100644 --- a/solidity/contracts/peripherals/Keep3rRoles.sol +++ b/solidity/contracts/peripherals/Keep3rRoles.sol @@ -3,8 +3,8 @@ pragma solidity >=0.8.4 <0.9.0; import '../../interfaces/peripherals/IKeep3rRoles.sol'; import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; -import './DustCollector.sol'; -import './Governable.sol'; +import '@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol'; +import '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol'; contract Keep3rRoles is IKeep3rRoles, Governable, DustCollector { /// @inheritdoc IKeep3rRoles @@ -13,10 +13,10 @@ contract Keep3rRoles is IKeep3rRoles, Governable, DustCollector { /// @inheritdoc IKeep3rRoles mapping(address => bool) public override disputers; - constructor(address _governance) Governable(_governance) DustCollector() {} + constructor(address _governor) Governable(_governor) DustCollector() {} /// @inheritdoc IKeep3rRoles - function addSlasher(address _slasher) external override onlyGovernance { + function addSlasher(address _slasher) external override onlyGovernor { if (_slasher == address(0)) revert ZeroAddress(); if (slashers[_slasher]) revert SlasherExistent(); slashers[_slasher] = true; @@ -24,14 +24,14 @@ contract Keep3rRoles is IKeep3rRoles, Governable, DustCollector { } /// @inheritdoc IKeep3rRoles - function removeSlasher(address _slasher) external override onlyGovernance { + function removeSlasher(address _slasher) external override onlyGovernor { if (!slashers[_slasher]) revert SlasherUnexistent(); delete slashers[_slasher]; emit SlasherRemoved(_slasher); } /// @inheritdoc IKeep3rRoles - function addDisputer(address _disputer) external override onlyGovernance { + function addDisputer(address _disputer) external override onlyGovernor { if (_disputer == address(0)) revert ZeroAddress(); if (disputers[_disputer]) revert DisputerExistent(); disputers[_disputer] = true; @@ -39,7 +39,7 @@ contract Keep3rRoles is IKeep3rRoles, Governable, DustCollector { } /// @inheritdoc IKeep3rRoles - function removeDisputer(address _disputer) external override onlyGovernance { + function removeDisputer(address _disputer) external override onlyGovernor { if (!disputers[_disputer]) revert DisputerUnexistent(); delete disputers[_disputer]; emit DisputerRemoved(_disputer); diff --git a/solidity/contracts/peripherals/Mintable.sol b/solidity/contracts/peripherals/Mintable.sol index 0e0b608..369e604 100644 --- a/solidity/contracts/peripherals/Mintable.sol +++ b/solidity/contracts/peripherals/Mintable.sol @@ -2,16 +2,16 @@ pragma solidity >=0.8.4 <0.9.0; import '../../interfaces/peripherals/IMintable.sol'; -import './Governable.sol'; +import '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol'; abstract contract Mintable is Governable, IMintable { /// @inheritdoc IMintable address public override minter; - constructor(address _governance) Governable(_governance) {} + constructor(address _governor) Governable(_governor) {} /// @inheritdoc IMintable - function setMinter(address _minter) external override onlyGovernance { + function setMinter(address _minter) external override onlyGovernor { if (_minter == address(0)) revert ZeroAddress(); minter = _minter; emit MinterSet(_minter); diff --git a/solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol b/solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol index 99e7e1b..04f90a3 100644 --- a/solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol +++ b/solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol @@ -19,7 +19,7 @@ abstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent(); if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient(); - try IERC20(_token).transfer(governance, _amount) {} catch {} + try IERC20(_token).transfer(governor, _amount) {} catch {} jobTokenCredits[_job][_token] -= _amount; if (jobTokenCredits[_job][_token] == 0) { _jobTokens[_job].remove(_token); @@ -37,7 +37,7 @@ abstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, if (!disputes[_job]) revert NotDisputed(); _unbondLiquidityFromJob(_job, _liquidity, _amount); - try IERC20(_liquidity).transfer(governance, _amount) {} catch {} + try IERC20(_liquidity).transfer(governor, _amount) {} catch {} emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount); } } diff --git a/solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol b/solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol index 256dc44..a0f7643 100644 --- a/solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol +++ b/solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol @@ -36,7 +36,7 @@ abstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, Reentra uint256 _tokenFee = (_received * fee) / _BASE; jobTokenCredits[_job][_token] += _received - _tokenFee; jobTokenCreditsAddedAt[_job][_token] = block.timestamp; - IERC20(_token).safeTransfer(governance, _tokenFee); + IERC20(_token).safeTransfer(governor, _tokenFee); _jobTokens[_job].add(_token); emit TokenCreditAddition(_job, _token, msg.sender, _received); diff --git a/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol b/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol index 593582b..5de1248 100644 --- a/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol +++ b/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol @@ -146,7 +146,7 @@ abstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, Ree // Methods /// @inheritdoc IKeep3rJobFundableLiquidity - function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance { + function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernor { if (!_jobs.contains(_job)) revert JobUnavailable(); _settleJobAccountance(_job); _jobLiquidityCredits[_job] += _amount; @@ -154,7 +154,7 @@ abstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, Ree } /// @inheritdoc IKeep3rJobFundableLiquidity - function approveLiquidity(address _liquidity) external virtual override onlyGovernance { + function approveLiquidity(address _liquidity) external virtual override onlyGovernor { if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved(); _liquidityPool[_liquidity] = IPairManager(_liquidity).pool(); _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]); @@ -163,7 +163,7 @@ abstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, Ree } /// @inheritdoc IKeep3rJobFundableLiquidity - function revokeLiquidity(address _liquidity) external override onlyGovernance { + function revokeLiquidity(address _liquidity) external override onlyGovernor { if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent(); delete _liquidityPool[_liquidity]; delete _isKP3RToken0[_liquidity]; diff --git a/solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol b/solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol index d4ffb16..1434695 100644 --- a/solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol +++ b/solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol @@ -37,7 +37,7 @@ abstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDispu uint256 _unbondAmount ) internal { if (_bonded != keep3rV1) { - try IERC20(_bonded).transfer(governance, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {} + try IERC20(_bonded).transfer(governor, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {} } bonds[_keeper][_bonded] -= _bondAmount; pendingUnbonds[_keeper][_bonded] -= _unbondAmount; diff --git a/solidity/contracts/sidechain/Keep3rEscrow.sol b/solidity/contracts/sidechain/Keep3rEscrow.sol index 797d07d..b8de01a 100644 --- a/solidity/contracts/sidechain/Keep3rEscrow.sol +++ b/solidity/contracts/sidechain/Keep3rEscrow.sol @@ -20,8 +20,8 @@ Commit hash: ead559c8dc4361349b7222741c2399447e255d8e pragma solidity >=0.8.4 <0.9.0; import '../peripherals/Mintable.sol'; -import '../peripherals/DustCollector.sol'; import '../../interfaces/sidechain/IKeep3rEscrow.sol'; +import '@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; @@ -31,9 +31,9 @@ contract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow { /// @inheritdoc IKeep3rEscrow address public override wKP3R; - /// @param _governance Address of governance + /// @param _governor Address of governor /// @param _wKP3R Address of wrapped KP3R implementation - constructor(address _governance, address _wKP3R) Mintable(_governance) { + constructor(address _governor, address _wKP3R) Mintable(_governor) { wKP3R = _wKP3R; } @@ -50,7 +50,7 @@ contract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow { } /// @inheritdoc IKeep3rEscrow - function setWKP3R(address _wKP3R) external override onlyGovernance { + function setWKP3R(address _wKP3R) external override onlyGovernor { if (_wKP3R == address(0)) revert ZeroAddress(); wKP3R = _wKP3R; emit wKP3RSet(wKP3R); diff --git a/solidity/contracts/sidechain/Keep3rHelperSidechain.sol b/solidity/contracts/sidechain/Keep3rHelperSidechain.sol index dd9f304..d420313 100644 --- a/solidity/contracts/sidechain/Keep3rHelperSidechain.sol +++ b/solidity/contracts/sidechain/Keep3rHelperSidechain.sol @@ -32,18 +32,18 @@ contract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper { address public immutable override WETH; /// @param _keep3rV2 Address of sidechain Keep3r implementation - /// @param _governance Address of governance + /// @param _governor Address of governor /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote /// @param _wethUsdOracle Address of oracle used for WETH/USD quote /// @dev Oracle pools should use 18 decimals tokens constructor( address _keep3rV2, - address _governance, + address _governor, address _kp3r, address _weth, address _kp3rWethOracle, address _wethUsdOracle - ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethOracle) { + ) Keep3rHelper(_kp3r, _keep3rV2, _governor, _kp3rWethOracle) { WETH = _weth; wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth); _setQuoteTwapTime(1 days); @@ -58,7 +58,7 @@ contract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper { } /// @inheritdoc IKeep3rHelperSidechain - function setOracle(address _liquidity, address _oracle) external override onlyGovernance { + function setOracle(address _liquidity, address _oracle) external override onlyGovernor { if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress(); oracle[_liquidity] = _oracle; emit OracleSet(_liquidity, _oracle); @@ -76,7 +76,7 @@ contract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper { } /// @inheritdoc IKeep3rHelperSidechain - function setWethUsdPool(address _poolAddress) external override onlyGovernance { + function setWethUsdPool(address _poolAddress) external override onlyGovernor { if (_poolAddress == address(0)) revert ZeroAddress(); _setWethUsdPool(_poolAddress); } diff --git a/solidity/contracts/sidechain/Keep3rSidechain.sol b/solidity/contracts/sidechain/Keep3rSidechain.sol index 6b1b00c..2b4930c 100644 --- a/solidity/contracts/sidechain/Keep3rSidechain.sol +++ b/solidity/contracts/sidechain/Keep3rSidechain.sol @@ -28,16 +28,16 @@ import '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol'; contract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance { using EnumerableSet for EnumerableSet.AddressSet; - /// @param _governance Address of governance + /// @param _governor Address of governor /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper /// @param _wrappedKP3R Address of wrapped KP3R implementation /// @param _keep3rEscrow Address of sidechain Keep3rEscrow constructor( - address _governance, // governance + address _governor, // governor address _keep3rHelperSidechain, // helper address _wrappedKP3R, // keep3rV1 address _keep3rEscrow // keep3rV1Proxy - ) Keep3r(_governance, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {} + ) Keep3r(_governor, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {} // Keep3rSidechainAccountance @@ -52,7 +52,7 @@ contract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAcc /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20 /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain /// @param _liquidity Address of the liquidity token being approved - function approveLiquidity(address _liquidity) external virtual override onlyGovernance { + function approveLiquidity(address _liquidity) external virtual override onlyGovernor { if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved(); _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity); if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress(); diff --git a/solidity/for-test/Keep3rForTest.sol b/solidity/for-test/Keep3rForTest.sol index 73114cd..f9ede63 100644 --- a/solidity/for-test/Keep3rForTest.sol +++ b/solidity/for-test/Keep3rForTest.sol @@ -5,9 +5,9 @@ import '../contracts/Keep3r.sol'; contract Keep3rForTest is Keep3r { constructor( - address _governance, + address _governor, address _keep3rHelper, address _keep3rV1, address _keep3rV1Proxy - ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {} + ) Keep3r(_governor, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {} } diff --git a/solidity/for-test/Keep3rHelperForTest.sol b/solidity/for-test/Keep3rHelperForTest.sol index 1f98cca..c77683b 100644 --- a/solidity/for-test/Keep3rHelperForTest.sol +++ b/solidity/for-test/Keep3rHelperForTest.sol @@ -9,9 +9,9 @@ contract Keep3rHelperForTest is Keep3rHelper { constructor( address _kp3r, address _keep3rV2, - address _governance, + address _governor, address _kp3rWethPool - ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {} + ) Keep3rHelper(_kp3r, _keep3rV2, _governor, _kp3rWethPool) {} function _getBasefee() internal view override returns (uint256) { return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee(); diff --git a/solidity/for-test/Keep3rSidechainForTest.sol b/solidity/for-test/Keep3rSidechainForTest.sol index a81ebdf..909bd98 100644 --- a/solidity/for-test/Keep3rSidechainForTest.sol +++ b/solidity/for-test/Keep3rSidechainForTest.sol @@ -7,11 +7,11 @@ contract Keep3rSidechainForTest is Keep3rSidechain { using EnumerableSet for EnumerableSet.AddressSet; constructor( - address _governance, + address _governor, address _keep3rHelper, address _wrappedKP3R, address _keep3rEscrow - ) Keep3rSidechain(_governance, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {} + ) Keep3rSidechain(_governor, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {} function setJobLiquidity(address _job, address _liquidity) external { _jobLiquidities[_job].add(_liquidity); diff --git a/solidity/for-test/UniV3PairManagerForTest.sol b/solidity/for-test/UniV3PairManagerForTest.sol index 3f369b8..3d2c1ed 100644 --- a/solidity/for-test/UniV3PairManagerForTest.sol +++ b/solidity/for-test/UniV3PairManagerForTest.sol @@ -13,7 +13,7 @@ import '../interfaces/external/IWeth9.sol'; import '../interfaces/IUniV3PairManager.sol'; contract UniV3PairManagerForTest is UniV3PairManager { - constructor(address _pool, address _governance) UniV3PairManager(_pool, _governance) {} + constructor(address _pool, address _governor) UniV3PairManager(_pool, _governor) {} function internalAddLiquidity( uint256 amount0Desired, diff --git a/solidity/for-test/peripherals/DustCollectorForTest.sol b/solidity/for-test/peripherals/DustCollectorForTest.sol deleted file mode 100644 index f746bb0..0000000 --- a/solidity/for-test/peripherals/DustCollectorForTest.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.4 <0.9.0; - -import '../../contracts/peripherals/DustCollector.sol'; - -contract DustCollectorForTest is DustCollector { - constructor() DustCollector() Governable(msg.sender) {} -} diff --git a/solidity/for-test/peripherals/GovernableForTest.sol b/solidity/for-test/peripherals/GovernableForTest.sol deleted file mode 100644 index d21f693..0000000 --- a/solidity/for-test/peripherals/GovernableForTest.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.4 <0.9.0; - -import '../../contracts/peripherals/Governable.sol'; - -contract GovernableForTest is Governable { - constructor(address _governor) Governable(_governor) {} -} diff --git a/solidity/for-test/testnet/Keep3rForTestnet.sol b/solidity/for-test/testnet/Keep3rForTestnet.sol index fff86cc..aecc5bf 100644 --- a/solidity/for-test/testnet/Keep3rForTestnet.sol +++ b/solidity/for-test/testnet/Keep3rForTestnet.sol @@ -5,11 +5,11 @@ import '../../contracts/Keep3r.sol'; contract Keep3rForTestnet is Keep3r { constructor( - address _governance, + address _governor, address _keep3rHelper, address _keep3rV1, address _keep3rV1Proxy - ) Keep3r(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) { + ) Keep3r(_governor, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) { bondTime = 0; // allows keepers to instantly register unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds liquidityMinimum = 1; // allows job providers to add low liquidity diff --git a/solidity/for-test/testnet/Keep3rHelperForTestnet.sol b/solidity/for-test/testnet/Keep3rHelperForTestnet.sol index 221196a..3e45a1d 100644 --- a/solidity/for-test/testnet/Keep3rHelperForTestnet.sol +++ b/solidity/for-test/testnet/Keep3rHelperForTestnet.sol @@ -7,9 +7,9 @@ contract Keep3rHelperForTestnet is Keep3rHelper { constructor( address _kp3r, address _keep3rV2, - address _governance, + address _governor, address _kp3rWethPool - ) Keep3rHelper(_kp3r, _keep3rV2, _governance, _kp3rWethPool) {} + ) Keep3rHelper(_kp3r, _keep3rV2, _governor, _kp3rWethPool) {} function _getBasefee() internal pure override returns (uint256) { return 1; diff --git a/solidity/for-test/testnet/Keep3rSidechainForTestnet.sol b/solidity/for-test/testnet/Keep3rSidechainForTestnet.sol index 471a497..6e13307 100644 --- a/solidity/for-test/testnet/Keep3rSidechainForTestnet.sol +++ b/solidity/for-test/testnet/Keep3rSidechainForTestnet.sol @@ -5,11 +5,11 @@ import '../../contracts/sidechain/Keep3rSidechain.sol'; contract Keep3rSidechainForTestnet is Keep3rSidechain { constructor( - address _governance, + address _governor, address _keep3rHelper, address _keep3rV1, address _keep3rV1Proxy - ) Keep3rSidechain(_governance, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) { + ) Keep3rSidechain(_governor, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) { bondTime = 0; // allows keepers to instantly register unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds liquidityMinimum = 1; // allows job providers to add low liquidity diff --git a/solidity/interfaces/IPairManagerFactory.sol b/solidity/interfaces/IPairManagerFactory.sol index d1af962..997f67e 100644 --- a/solidity/interfaces/IPairManagerFactory.sol +++ b/solidity/interfaces/IPairManagerFactory.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.4 <0.9.0; -import './peripherals/IGovernable.sol'; +import '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol'; /// @title Factory of Pair Managers /// @notice This contract creates new pair managers diff --git a/solidity/interfaces/IUniV3PairManager.sol b/solidity/interfaces/IUniV3PairManager.sol index 17de8bf..20f54b8 100644 --- a/solidity/interfaces/IUniV3PairManager.sol +++ b/solidity/interfaces/IUniV3PairManager.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.4 <0.9.0; import './IPairManager.sol'; import '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol'; -import './peripherals/IGovernable.sol'; +import '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol'; /// @title Pair Manager contract /// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner @@ -109,7 +109,7 @@ interface IUniV3PairManager is IGovernable, IPairManager { /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees // owed to a specific position to the recipient, in this case, that recipient is the pair manager - /// @dev The collected fees will be sent to governance + /// @dev The collected fees will be sent to governor /// @return amount0 The amount of fees collected in token0 /// @return amount1 The amount of fees collected in token1 function collect() external returns (uint256 amount0, uint256 amount1); diff --git a/solidity/interfaces/external/IKeep3rV1Proxy.sol b/solidity/interfaces/external/IKeep3rV1Proxy.sol index 68e5e58..662c4c5 100644 --- a/solidity/interfaces/external/IKeep3rV1Proxy.sol +++ b/solidity/interfaces/external/IKeep3rV1Proxy.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.4 <0.9.0; -import '../peripherals/IGovernable.sol'; +import '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol'; -interface IKeep3rV1Proxy is IGovernable { +interface IKeep3rV1Proxy is IBaseErrors { // Structs struct Recipient { address recipient; @@ -13,6 +13,10 @@ interface IKeep3rV1Proxy is IGovernable { // Variables function keep3rV1() external view returns (address); + function governance() external view returns (address); + + function pendingGovernance() external view returns (address); + function minter() external view returns (address); function next(address) external view returns (uint256); @@ -26,8 +30,9 @@ interface IKeep3rV1Proxy is IGovernable { // Errors error Cooldown(); error NoDrawableAmount(); - error ZeroAddress(); error OnlyMinter(); + error OnlyGovernance(); + error OnlyPendingGovernance(); // Methods function addRecipient(address recipient, uint256 amount) external; @@ -44,6 +49,10 @@ interface IKeep3rV1Proxy is IGovernable { function mint(address _account, uint256 _amount) external; + function setGovernance(address _governance) external; + + function acceptGovernance() external; + function setKeep3rV1Governance(address _governance) external; function acceptKeep3rV1Governance() external; diff --git a/solidity/interfaces/peripherals/IBaseErrors.sol b/solidity/interfaces/peripherals/IBaseErrors.sol deleted file mode 100644 index 5191885..0000000 --- a/solidity/interfaces/peripherals/IBaseErrors.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity >=0.8.4 <0.9.0; - -interface IBaseErrors { - /// @notice Throws if a variable is assigned to the zero address - error ZeroAddress(); -} diff --git a/solidity/interfaces/peripherals/IDustCollector.sol b/solidity/interfaces/peripherals/IDustCollector.sol deleted file mode 100644 index 5cb6137..0000000 --- a/solidity/interfaces/peripherals/IDustCollector.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity >=0.8.4 <0.9.0; - -import './IBaseErrors.sol'; - -interface IDustCollector is IBaseErrors { - /// @notice Emitted when dust is sent - /// @param _token The token that will be transferred - /// @param _amount The amount of the token that will be transferred - /// @param _to The address which will receive the funds - event DustSent(address _token, uint256 _amount, address _to); - - /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract - /// @param _token The token that will be transferred - /// @param _amount The amount of the token that will be transferred - /// @param _to The address that will receive the idle funds - function sendDust( - address _token, - uint256 _amount, - address _to - ) external; -} diff --git a/solidity/interfaces/peripherals/IGovernable.sol b/solidity/interfaces/peripherals/IGovernable.sol deleted file mode 100644 index f135604..0000000 --- a/solidity/interfaces/peripherals/IGovernable.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.4 <0.9.0; - -/// @title Governable contract -/// @notice Manages the governance role -interface IGovernable { - // Events - - /// @notice Emitted when pendingGovernance accepts to be governance - /// @param _governance Address of the new governance - event GovernanceSet(address _governance); - - /// @notice Emitted when a new governance is proposed - /// @param _pendingGovernance Address that is proposed to be the new governance - event GovernanceProposal(address _pendingGovernance); - - // Errors - - /// @notice Throws if the caller of the function is not governance - error OnlyGovernance(); - - /// @notice Throws if the caller of the function is not pendingGovernance - error OnlyPendingGovernance(); - - /// @notice Throws if trying to set governance to zero address - error NoGovernanceZeroAddress(); - - // Variables - - /// @notice Stores the governance address - /// @return _governance The governance addresss - function governance() external view returns (address _governance); - - /// @notice Stores the pendingGovernance address - /// @return _pendingGovernance The pendingGovernance addresss - function pendingGovernance() external view returns (address _pendingGovernance); - - // Methods - - /// @notice Proposes a new address to be governance - /// @param _governance The address being proposed as the new governance - function setGovernance(address _governance) external; - - /// @notice Changes the governance from the current governance to the previously proposed address - function acceptGovernance() external; -} diff --git a/solidity/interfaces/peripherals/IKeep3rDisputable.sol b/solidity/interfaces/peripherals/IKeep3rDisputable.sol index fd71ad1..4747e19 100644 --- a/solidity/interfaces/peripherals/IKeep3rDisputable.sol +++ b/solidity/interfaces/peripherals/IKeep3rDisputable.sol @@ -22,11 +22,11 @@ interface IKeep3rDisputable { /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute error NotDisputed(); - /// @notice Allows governance to create a dispute for a given keeper/job + /// @notice Allows governor to create a dispute for a given keeper/job /// @param _jobOrKeeper The address in dispute function dispute(address _jobOrKeeper) external; - /// @notice Allows governance to resolve a dispute on a keeper/job + /// @notice Allows governor to resolve a dispute on a keeper/job /// @param _jobOrKeeper The address cleared function resolve(address _jobOrKeeper) external; } diff --git a/solidity/interfaces/peripherals/IKeep3rJobs.sol b/solidity/interfaces/peripherals/IKeep3rJobs.sol index ec8cf88..42e7c6b 100644 --- a/solidity/interfaces/peripherals/IKeep3rJobs.sol +++ b/solidity/interfaces/peripherals/IKeep3rJobs.sol @@ -455,7 +455,7 @@ interface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, // Methods - /// @notice Allows governance or slasher to slash a job specific token + /// @notice Allows governor or slasher to slash a job specific token /// @param _job The address of the job from which the token will be slashed /// @param _token The address of the token that will be slashed /// @param _amount The amount of the token that will be slashed @@ -465,7 +465,7 @@ interface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, uint256 _amount ) external; - /// @notice Allows governance or a slasher to slash liquidity from a job + /// @notice Allows governor or slasher to slash liquidity from a job /// @param _job The address being slashed /// @param _liquidity The address of the liquidity that will be slashed /// @param _amount The amount of liquidity that will be slashed diff --git a/solidity/interfaces/peripherals/IKeep3rKeepers.sol b/solidity/interfaces/peripherals/IKeep3rKeepers.sol index e142b0f..cc77cb1 100644 --- a/solidity/interfaces/peripherals/IKeep3rKeepers.sol +++ b/solidity/interfaces/peripherals/IKeep3rKeepers.sol @@ -64,7 +64,7 @@ interface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable { // Methods - /// @notice Allows governance to slash a keeper based on a dispute + /// @notice Allows governor to slash a keeper based on a dispute /// @param _keeper The address being slashed /// @param _bonded The asset being slashed /// @param _bondAmount The bonded amount being slashed diff --git a/solidity/interfaces/peripherals/IKeep3rParameters.sol b/solidity/interfaces/peripherals/IKeep3rParameters.sol index 7e789b3..10b0eff 100644 --- a/solidity/interfaces/peripherals/IKeep3rParameters.sol +++ b/solidity/interfaces/peripherals/IKeep3rParameters.sol @@ -78,8 +78,8 @@ interface IKeep3rParameters is IKeep3rAccountance { /// @return _period The denominator used to regulate the emission of KP3R function inflationPeriod() external view returns (uint256 _period); - /// @notice The fee to be sent to governance when a user adds liquidity to a job - /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job + /// @notice The fee to be sent to governor when a user adds liquidity to a job + /// @return _amount The fee amount to be sent to governor when a user adds liquidity to a job function fee() external view returns (uint256 _amount); // Errors diff --git a/solidity/interfaces/peripherals/IKeep3rRoles.sol b/solidity/interfaces/peripherals/IKeep3rRoles.sol index 37b7da4..ae68e81 100644 --- a/solidity/interfaces/peripherals/IKeep3rRoles.sol +++ b/solidity/interfaces/peripherals/IKeep3rRoles.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.4 <0.9.0; -import './IBaseErrors.sol'; -import './IGovernable.sol'; -import './IDustCollector.sol'; +import '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol'; +import '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol'; +import '@defi-wonderland/solidity-utils/solidity/interfaces/IDustCollector.sol'; /// @title Keep3rRoles contract /// @notice Manages the Keep3r specific roles -interface IKeep3rRoles is IBaseErrors, IDustCollector, IGovernable { +interface IKeep3rRoles is IBaseErrors, IGovernable, IDustCollector { // Events /// @notice Emitted when a slasher is added diff --git a/solidity/interfaces/peripherals/IMintable.sol b/solidity/interfaces/peripherals/IMintable.sol index 73781c5..4338a3f 100644 --- a/solidity/interfaces/peripherals/IMintable.sol +++ b/solidity/interfaces/peripherals/IMintable.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.4 <0.9.0; -import './IGovernable.sol'; -import './IBaseErrors.sol'; +import '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol'; +import '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol'; /// @title Mintable contract /// @notice Manages the minter role interface IMintable is IBaseErrors, IGovernable { // Events - /// @notice Emitted when governance sets a new minter + /// @notice Emitted when governor sets a new minter /// @param _minter Address of the new minter event MinterSet(address _minter); diff --git a/test/e2e/basic-job.spec.ts b/test/e2e/basic-job.spec.ts index 33f453f..f828b65 100644 --- a/test/e2e/basic-job.spec.ts +++ b/test/e2e/basic-job.spec.ts @@ -25,7 +25,7 @@ describe('@skip-on-coverage Basic Keeper Job Interaction', () => { let keep3rV1: IKeep3rV1; let helper: Keep3rHelperForTest; let job: BasicJob; - let governance: JsonRpcSigner; + let governor: JsonRpcSigner; let keeper: JsonRpcSigner; let snapshotId: string; let pair: UniV3PairManager; @@ -39,20 +39,20 @@ describe('@skip-on-coverage Basic Keeper Job Interaction', () => { jobOwner = await wallet.impersonate(common.RICH_KP3R_ADDRESS); keeper = await wallet.impersonate(common.RICH_ETH_ADDRESS); - ({ keep3r, governance, keep3rV1, helper } = await common.setupKeep3r()); + ({ keep3r, governor, keep3rV1, helper } = await common.setupKeep3r()); // create job const jobFactory = (await ethers.getContractFactory('BasicJob')) as BasicJob__factory; job = await jobFactory.connect(jobOwner).deploy(keep3r.address); - await keep3r.connect(governance).addJob(job.address); + await keep3r.connect(governor).addJob(job.address); // create keeper await keep3r.connect(keeper).bond(keep3rV1.address, 0); await evm.advanceTimeAndBlock(moment.duration(3, 'days').as('seconds')); await keep3r.connect(keeper).activate(keep3rV1.address); - pair = await common.createLiquidityPair(governance); - await keep3r.connect(governance).approveLiquidity(pair.address); + pair = await common.createLiquidityPair(governor); + await keep3r.connect(governor).approveLiquidity(pair.address); const { liquidity } = await common.mintLiquidity(jobOwner, pair, toUnit(100), jobOwner._address); @@ -160,13 +160,13 @@ describe('@skip-on-coverage Basic Keeper Job Interaction', () => { // this job has several deletions, generating a lot of unaccounted refunds it('should overpay for Kasparov job work', async () => { const chessJob = (await ethers.getContractAt('IKasparov', common.KASPAROV_JOB)) as IKasparov; - const chessGovernance = await wallet.impersonate(await chessJob.governor()); + const chessGovernor = await wallet.impersonate(await chessJob.governor()); await keep3r.connect(jobOwner).addJob(chessJob.address); await keep3r.connect(jobOwner).addLiquidityToJob(chessJob.address, pair.address, toUnit(10)); await evm.advanceTimeAndBlock(DAY * 10 - 1); - await chessJob.connect(chessGovernance).setKeep3r(keep3r.address); + await chessJob.connect(chessGovernor).setKeep3r(keep3r.address); await job.connect(keeper).work(); diff --git a/test/e2e/common.ts b/test/e2e/common.ts index 13d4cff..a503603 100644 --- a/test/e2e/common.ts +++ b/test/e2e/common.ts @@ -46,15 +46,15 @@ export const PAIR_MANAGER_ADDRESS = '0x3f6740b5898c5D3650ec6eAce9a649Ac791e44D7' export async function setupKeep3r(): Promise<{ keep3r: Keep3r; - governance: JsonRpcSigner; + governor: JsonRpcSigner; keep3rV1: IKeep3rV1; keep3rV1Proxy: IKeep3rV1Proxy; keep3rV1ProxyGovernance: JsonRpcSigner; helper: Keep3rHelperForTest; }> { - // create governance with some eth - const governance = await wallet.impersonate(wallet.generateRandomAddress()); - await contracts.setBalance(governance._address, toUnit(1000)); + // create governor with some eth + const governor = await wallet.impersonate(wallet.generateRandomAddress()); + await contracts.setBalance(governor._address, toUnit(1000)); // deploy proxy and set it as Keep3rV1 governance const { keep3rV1, keep3rV1Proxy, keep3rV1ProxyGovernance } = await setupKeep3rV1(); @@ -63,14 +63,12 @@ export async function setupKeep3r(): Promise<{ const keep3rFactory = (await ethers.getContractFactory('Keep3r')) as Keep3r__factory; // calculate keep3rV2 deployment address - const currentNonce = await ethers.provider.getTransactionCount(governance._address); - const keeperV2Address = ethers.utils.getContractAddress({ from: governance._address, nonce: currentNonce + 1 }); + const currentNonce = await ethers.provider.getTransactionCount(governor._address); + const keeperV2Address = ethers.utils.getContractAddress({ from: governor._address, nonce: currentNonce + 1 }); // deploy Keep3rHelperForTest and Keep3r contract - const helper = await helperFactory - .connect(governance) - .deploy(keep3rV1.address, keeperV2Address, governance._address, KP3R_WETH_V3_POOL_ADDRESS); - const keep3r = await keep3rFactory.connect(governance).deploy(governance._address, helper.address, keep3rV1.address, keep3rV1Proxy.address); + const helper = await helperFactory.connect(governor).deploy(keep3rV1.address, keeperV2Address, governor._address, KP3R_WETH_V3_POOL_ADDRESS); + const keep3r = await keep3rFactory.connect(governor).deploy(governor._address, helper.address, keep3rV1.address, keep3rV1Proxy.address); await helper.setBaseFee(HELPER_FOR_TEST_BASE_FEE); @@ -81,7 +79,7 @@ export async function setupKeep3r(): Promise<{ await contracts.setBalance(keep3r.address, toUnit(1000)); await contracts.setBalance(keep3rV1.address, toUnit(1000)); - return { governance, keep3r, keep3rV1, keep3rV1Proxy, keep3rV1ProxyGovernance, helper }; + return { governor, keep3r, keep3rV1, keep3rV1Proxy, keep3rV1ProxyGovernance, helper }; } export async function setupKeep3rV1(): Promise<{ @@ -89,7 +87,7 @@ export async function setupKeep3rV1(): Promise<{ keep3rV1Proxy: IKeep3rV1Proxy; keep3rV1ProxyGovernance: JsonRpcSigner; }> { - // get Keep3rV1 and it's governance + // get Keep3rV1 and its governance const keep3rV1 = (await ethers.getContractAt('IKeep3rV1', KP3R_V1_ADDRESS)) as IKeep3rV1; const keep3rV1Proxy = (await ethers.getContractAt('IKeep3rV1Proxy', KP3R_V1_PROXY_ADDRESS)) as IKeep3rV1Proxy; const keep3rV1ProxyGovernance = await wallet.impersonate(KP3R_V1_PROXY_GOVERNANCE_ADDRESS); @@ -111,10 +109,10 @@ export async function createJobRatedForTest(keep3rAddress: string, jobOwner: Jso return await jobFactory.connect(jobOwner).deploy(keep3rAddress); } -export async function createLiquidityPair(governance: JsonRpcSigner): Promise { +export async function createLiquidityPair(governor: JsonRpcSigner): Promise { return await ((await ethers.getContractFactory('UniV3PairManager')) as UniV3PairManager__factory).deploy( KP3R_WETH_V3_POOL_ADDRESS, - governance._address + governor._address ); } @@ -149,7 +147,7 @@ export async function mintLiquidity( } export async function forceCreditsToJob(keep3rContract: Keep3r, jobAddress: string) { - const governor = await keep3rContract.governance(); + const governor = await keep3rContract.governor(); const governorSigner = await wallet.impersonate(governor); await keep3rContract.connect(governorSigner).forceLiquidityCreditsToJob(jobAddress, toUnit(100)); } diff --git a/test/e2e/deployment-fixtures.spec.ts b/test/e2e/deployment-fixtures.spec.ts index 35f3660..ed5fde1 100644 --- a/test/e2e/deployment-fixtures.spec.ts +++ b/test/e2e/deployment-fixtures.spec.ts @@ -243,7 +243,14 @@ describe('@skip-on-coverage Fixture', () => { }); const setKp3rMinter = async (keep3r: Type.Keep3r) => { - const mintable = (await ethers.getContractAt('IMintable', await keep3r.keep3rV1Proxy())) as Type.Mintable; - const proxyGovernor = await wallet.impersonate(await mintable.governance()); + let mintable; + let proxyGovernor; + try { + mintable = (await ethers.getContractAt('IMintable', await keep3r.keep3rV1Proxy())) as Type.Mintable; + proxyGovernor = await wallet.impersonate(await mintable.governor()); + } catch { + mintable = (await ethers.getContractAt('IKeep3rV1Proxy', await keep3r.keep3rV1Proxy())) as Type.IKeep3rV1Proxy; + proxyGovernor = await wallet.impersonate(await mintable.governance()); + } await mintable.connect(proxyGovernor).setMinter(keep3r.address); }; diff --git a/test/e2e/job.spec.ts b/test/e2e/job.spec.ts index 715743b..234579c 100644 --- a/test/e2e/job.spec.ts +++ b/test/e2e/job.spec.ts @@ -16,7 +16,7 @@ describe('@skip-on-coverage Job', () => { let keep3r: Keep3r; let job: JobForTest; let pair: UniV3PairManager; - let governance: JsonRpcSigner; + let governor: JsonRpcSigner; let snapshotId: string; // Parameter and function equivalent to contract's @@ -31,13 +31,13 @@ describe('@skip-on-coverage Job', () => { jobOwner = await wallet.impersonate(common.RICH_ETH_ADDRESS); keeper = await wallet.generateRandomWithEth(toUnit(10)); - ({ keep3r, governance } = await common.setupKeep3r()); + ({ keep3r, governor } = await common.setupKeep3r()); rewardPeriodTime = (await keep3r.rewardPeriodTime()).toNumber(); job = await common.createJobForTest(keep3r.address, jobOwner); - pair = await common.createLiquidityPair(governance); + pair = await common.createLiquidityPair(governor); richGuy = await wallet.impersonate(common.RICH_KP3R_ADDRESS); @@ -56,7 +56,7 @@ describe('@skip-on-coverage Job', () => { }); it('should not be able to add liquidity to an unexistent job', async () => { - await keep3r.connect(governance).approveLiquidity(pair.address); + await keep3r.connect(governor).approveLiquidity(pair.address); await expect(keep3r.connect(jobOwner).addLiquidityToJob(job.address, pair.address, toUnit(1))).to.be.revertedWith('JobUnavailable()'); }); @@ -71,7 +71,7 @@ describe('@skip-on-coverage Job', () => { // create job and add liquidity to it await keep3r.connect(jobOwner).addJob(job.address); - await keep3r.connect(governance).approveLiquidity(pair.address); + await keep3r.connect(governor).approveLiquidity(pair.address); const response = await common.mintLiquidity(richGuy, pair, liquidityAdded, jobOwner._address); initialLiquidity = response.liquidity; diff --git a/test/e2e/keep3r-escrow.spec.ts b/test/e2e/keep3r-escrow.spec.ts index 0f20837..05355af 100644 --- a/test/e2e/keep3r-escrow.spec.ts +++ b/test/e2e/keep3r-escrow.spec.ts @@ -14,7 +14,7 @@ describe('@skip-on-coverage Keep3rEscrow', () => { let escrow: Keep3rEscrow; let escrowFactory: Keep3rEscrow__factory; let fakeWKP3R: IERC20; - let governance: SignerWithAddress; + let governor: SignerWithAddress; let minter: SignerWithAddress; let snapshotId: string; let whale: JsonRpcSigner; @@ -28,15 +28,15 @@ describe('@skip-on-coverage Keep3rEscrow', () => { blockNumber: common.FORK_BLOCK_NUMBER, }); - [, governance, minter, randomUser] = await ethers.getSigners(); + [, governor, minter, randomUser] = await ethers.getSigners(); fakeWKP3R = (await ethers.getContractAt('@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20', common.DAI_ADDRESS)) as IERC20; escrowFactory = (await ethers.getContractFactory('Keep3rEscrow')) as Keep3rEscrow__factory; - escrow = await escrowFactory.deploy(governance.address, fakeWKP3R.address); + escrow = await escrowFactory.deploy(governor.address, fakeWKP3R.address); whale = await wallet.impersonate(DAI_WETH_WHALE); - await escrow.connect(governance).setMinter(minter.address); + await escrow.connect(governor).setMinter(minter.address); await fakeWKP3R.connect(whale).approve(escrow.address, oneToken); snapshotId = await snapshot.take(); @@ -72,14 +72,14 @@ describe('@skip-on-coverage Keep3rEscrow', () => { }); }); - it('should allow governance to withdraw any dust in the contract', async () => { + it('should allow governor to withdraw any dust in the contract', async () => { await escrow.connect(whale).deposit(oneToken); - await escrow.connect(governance).sendDust(fakeWKP3R.address, oneToken, governance.address); - expect(await fakeWKP3R.balanceOf(governance.address)).to.equal(oneToken); + await escrow.connect(governor).sendDust(fakeWKP3R.address, oneToken, governor.address); + expect(await fakeWKP3R.balanceOf(governor.address)).to.equal(oneToken); }); - it('should only allow governance to withdraw dust in the contract', async () => { + it('should only allow governor to withdraw dust in the contract', async () => { await escrow.connect(whale).deposit(oneToken); - await expect(escrow.connect(randomUser).sendDust(fakeWKP3R.address, oneToken, governance.address)).to.be.revertedWith('OnlyGovernance()'); + await expect(escrow.connect(randomUser).sendDust(fakeWKP3R.address, oneToken, governor.address)).to.be.revertedWith('OnlyGovernor()'); }); }); diff --git a/test/e2e/keep3r-multichain.spec.ts b/test/e2e/keep3r-multichain.spec.ts index 54d8715..f7ea8a6 100644 --- a/test/e2e/keep3r-multichain.spec.ts +++ b/test/e2e/keep3r-multichain.spec.ts @@ -37,7 +37,7 @@ describe('Keep3r Sidechain @skip-on-coverage', () => { let deployer: SignerWithAddress; let stranger: SignerWithAddress; let keeper: SignerWithAddress; - let governance: SignerWithAddress; + let governor: SignerWithAddress; let kp3rWhale: JsonRpcSigner; let keep3r: Keep3rSidechain; let keep3rHelper: Keep3rHelperSidechain; @@ -59,7 +59,7 @@ describe('Keep3r Sidechain @skip-on-coverage', () => { const oneETHinDAI = bn.toUnit(1254); // 1ETH ~ $1250 DAI before(async () => { - [deployer, stranger, keeper, governance] = await ethers.getSigners(); + [deployer, stranger, keeper, governor] = await ethers.getSigners(); await evm.reset({ jsonRpcUrl: process.env.MAINNET_HTTPS_URL, blockNumber: 15100000, @@ -82,7 +82,7 @@ describe('Keep3r Sidechain @skip-on-coverage', () => { wKLP = await wKLPp3rFactory.deploy(pairManager.address); const keep3rEscrowFactory = (await ethers.getContractFactory('Keep3rEscrow')) as Keep3rEscrow__factory; - keep3rEscrow = await keep3rEscrowFactory.deploy(governance.address, wKP3R.address); + keep3rEscrow = await keep3rEscrowFactory.deploy(governor.address, wKP3R.address); const currentNonce: number = await ethers.provider.getTransactionCount(deployer.address); const precalculatedAddress = ethers.utils.getContractAddress({ from: deployer.address, nonce: currentNonce + 1 }); @@ -90,7 +90,7 @@ describe('Keep3r Sidechain @skip-on-coverage', () => { const keep3rHelperFactory = (await ethers.getContractFactory('Keep3rHelperSidechain')) as Keep3rHelperSidechain__factory; keep3rHelper = await keep3rHelperFactory.deploy( precalculatedAddress, - governance.address, + governor.address, KP3R_V1_ADDRESS, WETH_ADDRESS, KP3R_WETH_V3_POOL_ADDRESS, // uses KP3R-WETH pool as oracle @@ -99,15 +99,15 @@ describe('Keep3r Sidechain @skip-on-coverage', () => { const kp3rSidechainFactory = (await ethers.getContractFactory('Keep3rSidechain')) as Keep3rSidechain__factory; keep3r = await kp3rSidechainFactory.deploy( - governance.address, + governor.address, keep3rHelper.address, wKP3R.address, keep3rEscrow.address // replaces keep3rV1Proxy ); // setup - await keep3rHelper.connect(governance).setOracle(wKLP.address, await pairManager.pool()); - await keep3r.connect(governance).approveLiquidity(wKLP.address); + await keep3rHelper.connect(governor).setOracle(wKLP.address, await pairManager.pool()); + await keep3r.connect(governor).approveLiquidity(wKLP.address); // mint kLPs await contracts.setBalance(kp3rWhale._address, bn.toUnit(1000)); @@ -127,7 +127,7 @@ describe('Keep3r Sidechain @skip-on-coverage', () => { // fund escrow await wKP3R.connect(kp3rWhale).approve(keep3rEscrow.address, ESCROW_AMOUNT); await keep3rEscrow.connect(kp3rWhale).deposit(ESCROW_AMOUNT); - await keep3rEscrow.connect(governance).setMinter(keep3r.address); + await keep3rEscrow.connect(governor).setMinter(keep3r.address); // deploy job const jobFactory = (await ethers.getContractFactory('JobRatedForTest')) as JobRatedForTest__factory; diff --git a/test/e2e/keeper-job-interaction.spec.ts b/test/e2e/keeper-job-interaction.spec.ts index 98de3b8..f7da60d 100644 --- a/test/e2e/keeper-job-interaction.spec.ts +++ b/test/e2e/keeper-job-interaction.spec.ts @@ -14,7 +14,7 @@ describe('@skip-on-coverage Keeper Job Interaction', () => { let keep3rV1: IKeep3rV1; let helper: Keep3rHelperForTest; let job: JobForTest; - let governance: JsonRpcSigner; + let governor: JsonRpcSigner; let keep3rV1Proxy: IKeep3rV1Proxy; let keep3rV1ProxyGovernance: JsonRpcSigner; let keeper: JsonRpcSigner; @@ -30,19 +30,19 @@ describe('@skip-on-coverage Keeper Job Interaction', () => { jobOwner = await wallet.impersonate(common.RICH_KP3R_ADDRESS); keeper = await wallet.impersonate(common.RICH_ETH_ADDRESS); - ({ keep3r, governance, keep3rV1, keep3rV1Proxy, keep3rV1ProxyGovernance, helper } = await common.setupKeep3r()); + ({ keep3r, governor, keep3rV1, keep3rV1Proxy, keep3rV1ProxyGovernance, helper } = await common.setupKeep3r()); // create job job = await common.createJobForTest(keep3r.address, jobOwner); - await keep3r.connect(governance).addJob(job.address); + await keep3r.connect(governor).addJob(job.address); // create keeper await keep3r.connect(keeper).bond(keep3rV1.address, 0); await evm.advanceTimeAndBlock(moment.duration(3, 'days').as('seconds')); await keep3r.connect(keeper).activate(keep3rV1.address); - pair = await common.createLiquidityPair(governance); - await keep3r.connect(governance).approveLiquidity(pair.address); + pair = await common.createLiquidityPair(governor); + await keep3r.connect(governor).approveLiquidity(pair.address); pool = (await ethers.getContractAt('IUniswapV3Pool', common.KP3R_WETH_V3_POOL_ADDRESS)) as IUniswapV3Pool; }); diff --git a/test/e2e/keeper.spec.ts b/test/e2e/keeper.spec.ts index 3fadedc..fef6888 100644 --- a/test/e2e/keeper.spec.ts +++ b/test/e2e/keeper.spec.ts @@ -11,7 +11,7 @@ import * as common from './common'; describe('@skip-on-coverage Keep3r', () => { let dai: IERC20; let keeper: JsonRpcSigner; - let governance: JsonRpcSigner; + let governor: JsonRpcSigner; let keep3r: Keep3r; let keep3rV1: IKeep3rV1; let keep3rV1Proxy: IKeep3rV1Proxy; @@ -26,7 +26,7 @@ describe('@skip-on-coverage Keep3r', () => { blockNumber: common.FORK_BLOCK_NUMBER, }); - ({ keep3r, governance, keep3rV1, keep3rV1Proxy, keep3rV1ProxyGovernance } = await common.setupKeep3r()); + ({ keep3r, governor, keep3rV1, keep3rV1Proxy, keep3rV1ProxyGovernance } = await common.setupKeep3r()); keeper = await wallet.impersonate(common.RICH_ETH_DAI_ADDRESS); @@ -102,7 +102,7 @@ describe('@skip-on-coverage Keep3r', () => { newERC20 = (await (await ethers.getContractFactory('ERC20ForTest')).deploy('NewKP3R', 'nKP3R', keeper._address, BONDS)) as IERC20; - await keep3r.connect(governance).setKeep3rV1(newERC20.address); + await keep3r.connect(governor).setKeep3rV1(newERC20.address); await keep3rV1Proxy.connect(keep3rV1ProxyGovernance).setKeep3rV1(newERC20.address); }); diff --git a/test/e2e/univ3-pair-factory.spec.ts b/test/e2e/univ3-pair-factory.spec.ts index c2cfbb8..8a1678a 100644 --- a/test/e2e/univ3-pair-factory.spec.ts +++ b/test/e2e/univ3-pair-factory.spec.ts @@ -15,7 +15,7 @@ describe('UniV3PairManagerFactory', () => { let createdManager: UniV3PairManager; //signers - let governance: SignerWithAddress; + let governor: SignerWithAddress; //misc let snapshotId: string; @@ -26,11 +26,11 @@ describe('UniV3PairManagerFactory', () => { blockNumber: common.FORK_BLOCK_NUMBER, }); - [, governance] = await ethers.getSigners(); + [, governor] = await ethers.getSigners(); uniV3PairManagerFactory = (await ethers.getContractFactory('UniV3PairManagerFactory')) as UniV3PairManagerFactory__factory; - uniPairFactory = await uniV3PairManagerFactory.deploy(governance.address); + uniPairFactory = await uniV3PairManagerFactory.deploy(governor.address); snapshotId = await snapshot.take(); }); @@ -56,8 +56,8 @@ describe('UniV3PairManagerFactory', () => { expect(createdManagerAddress).to.eq(expectedAddress); }); - it('should set the governance of the created pair manager to the owner of the factory', async () => { - expect(await createdManager.governance()).to.equal(governance.address); + it('should set the governor of the created pair manager to the owner of the factory', async () => { + expect(await createdManager.governor()).to.equal(governor.address); }); }); }); diff --git a/test/e2e/univ3-pair-manager.spec.ts b/test/e2e/univ3-pair-manager.spec.ts index 0281325..d8abf67 100644 --- a/test/e2e/univ3-pair-manager.spec.ts +++ b/test/e2e/univ3-pair-manager.spec.ts @@ -54,7 +54,7 @@ describe('UniV3PairManager', () => { let wbtc: IERC20; //signers - let governance: SignerWithAddress; + let governor: SignerWithAddress; let whale: JsonRpcSigner; //misc @@ -86,7 +86,7 @@ describe('UniV3PairManager', () => { blockNumber: common.FORK_BLOCK_NUMBER, }); - [, governance] = await ethers.getSigners(); + [, governor] = await ethers.getSigners(); dai = (await ethers.getContractAt('@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20', common.DAI_ADDRESS)) as IERC20; weth = (await ethers.getContractAt('@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20', common.WETH_ADDRESS)) as IERC20; @@ -104,7 +104,7 @@ describe('UniV3PairManager', () => { uniV3PairManagerFactory = (await ethers.getContractFactory('UniV3PairManagerFactory')) as UniV3PairManagerFactory__factory; liquidityAmountsFactory = (await ethers.getContractFactory('LiquidityAmountsForTest')) as LiquidityAmountsForTest__factory; - uniPairFactory = await uniV3PairManagerFactory.deploy(governance.address); + uniPairFactory = await uniV3PairManagerFactory.deploy(governor.address); // deploying different pairs await uniPairFactory.createPairManager(KP3R_WETH_1); @@ -230,12 +230,12 @@ describe('UniV3PairManager', () => { await provideLiquidityAndSwap(); }); - it('should send the collected fees to governance', async () => { + it('should send the collected fees to governor', async () => { const tokensOwed0 = (await firstPair.position()).tokensOwed0; const tokensOwed1 = (await firstPair.position()).tokensOwed1; - await firstPair.connect(governance).collect(); - expect(await kp3r.balanceOf(governance.address)).to.equal(tokensOwed0); - expect(await weth.balanceOf(governance.address)).to.equal(tokensOwed1); + await firstPair.connect(governor).collect(); + expect(await kp3r.balanceOf(governor.address)).to.equal(tokensOwed0); + expect(await weth.balanceOf(governor.address)).to.equal(tokensOwed1); }); }); }); @@ -254,14 +254,14 @@ describe('UniV3PairManager', () => { it('should send the gathered fees to recipient', async () => { //check the initial balance is 0 - expect(await kp3r.balanceOf(governance.address)).to.equal(0); - expect(await weth.balanceOf(governance.address)).to.equal(0); + expect(await kp3r.balanceOf(governor.address)).to.equal(0); + expect(await weth.balanceOf(governor.address)).to.equal(0); //expect the balance to grow after liquidity is burned and tokens are sent to him - await firstPair.connect(whale).burn(liquidity, amount0MinIsZero, amount1MinIsZero, governance.address); + await firstPair.connect(whale).burn(liquidity, amount0MinIsZero, amount1MinIsZero, governor.address); - expect(await kp3r.balanceOf(governance.address)).to.be.gt(0); - expect(await weth.balanceOf(governance.address)).to.be.gt(0); + expect(await kp3r.balanceOf(governor.address)).to.be.gt(0); + expect(await weth.balanceOf(governor.address)).to.be.gt(0); }); it('should burn credits from the user who burns liquidity', async () => { diff --git a/test/unit/Keep3r.spec.ts b/test/unit/Keep3r.spec.ts index 2ab4f92..84d51a7 100644 --- a/test/unit/Keep3r.spec.ts +++ b/test/unit/Keep3r.spec.ts @@ -8,7 +8,7 @@ import { ethers } from 'hardhat'; chai.use(smock.matchers); describe('Keep3r', () => { - let governance: SignerWithAddress; + let governor: SignerWithAddress; let keep3r: MockContract; let helper: FakeContract; let keep3rV1: FakeContract; @@ -19,7 +19,7 @@ describe('Keep3r', () => { let snapshotId: string; before(async () => { - [governance] = await ethers.getSigners(); + [governor] = await ethers.getSigners(); keep3rFactory = await smock.mock('Keep3rForTest'); helper = await smock.fake('IKeep3rHelper'); @@ -34,7 +34,7 @@ describe('Keep3r', () => { await evm.snapshot.revert(snapshotId); helper.isKP3RToken0.whenCalledWith(kp3rWethPool.address).returns(true); - keep3r = await keep3rFactory.deploy(governance.address, helper.address, keep3rV1.address, keep3rV1Proxy.address); + keep3r = await keep3rFactory.deploy(governor.address, helper.address, keep3rV1.address, keep3rV1Proxy.address); }); it('should be connected to Keep3r Helper', async () => { @@ -49,7 +49,7 @@ describe('Keep3r', () => { expect(await keep3r.keep3rV1Proxy()).to.be.equal(keep3rV1Proxy.address); }); - it('should set deployer as governance', async () => { - expect(await keep3r.governance()).to.be.equal(governance.address); + it('should set deployer as governor', async () => { + expect(await keep3r.governor()).to.be.equal(governor.address); }); }); diff --git a/test/unit/Keep3rHelper.spec.ts b/test/unit/Keep3rHelper.spec.ts index 50717d4..bacf5af 100644 --- a/test/unit/Keep3rHelper.spec.ts +++ b/test/unit/Keep3rHelper.spec.ts @@ -3,7 +3,8 @@ import { KP3R_V1_ADDRESS } from '@e2e/common'; import { BigNumber } from '@ethersproject/bignumber'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { IKeep3r, IKeep3rV1, IUniswapV3Pool, Keep3rHelperForTest, Keep3rHelperForTest__factory, ProxyForTest__factory } from '@types'; -import { behaviours, wallet } from '@utils'; +import { wallet } from '@utils'; +import { onlyGovernor } from '@utils/behaviours'; import { toGwei, toUnit } from '@utils/bn'; import { MathUtils, mathUtilsFactory } from '@utils/math'; import chai, { expect } from 'chai'; @@ -21,7 +22,7 @@ describe('Keep3rHelper', () => { let kp3rV1Address: string; let targetBond: BigNumber; - let governance: SignerWithAddress; + let governor: SignerWithAddress; let randomKeeper: SignerWithAddress; let workExtraGas: BigNumber; @@ -32,13 +33,13 @@ describe('Keep3rHelper', () => { let mathUtils: MathUtils; before(async () => { - [, governance, randomKeeper] = await ethers.getSigners(); + [, governor, randomKeeper] = await ethers.getSigners(); helperFactory = await smock.mock('Keep3rHelperForTest'); keep3r = await smock.fake('IKeep3r'); oraclePool = await smock.fake('IUniswapV3Pool'); oraclePool.token1.returns(KP3R_V1_ADDRESS); - helper = await helperFactory.deploy(KP3R_V1_ADDRESS, keep3r.address, governance.address, oraclePool.address); + helper = await helperFactory.deploy(KP3R_V1_ADDRESS, keep3r.address, governor.address, oraclePool.address); kp3rV1Address = await helper.callStatic.KP3R(); targetBond = await helper.callStatic.targetBond(); @@ -364,16 +365,16 @@ describe('Keep3rHelper', () => { describe('setWorkExtraGas', () => { const newValue = 123; - behaviours.onlyGovernance(() => helper, 'setWorkExtraGas', governance, [newValue]); + onlyGovernor(() => helper, 'setWorkExtraGas', governor, [newValue]); it('should assign specified value to variable', async () => { expect(await helper.callStatic.workExtraGas()).not.to.equal(newValue); - await helper.connect(governance).setWorkExtraGas(newValue); + await helper.connect(governor).setWorkExtraGas(newValue); expect(await helper.callStatic.workExtraGas()).to.equal(newValue); }); it('should emit event', async () => { - await expect(helper.connect(governance).setWorkExtraGas(newValue)).to.emit(helper, 'WorkExtraGasChange').withArgs(newValue); + await expect(helper.connect(governor).setWorkExtraGas(newValue)).to.emit(helper, 'WorkExtraGasChange').withArgs(newValue); }); }); diff --git a/test/unit/Keep3rHelperParameters.spec.ts b/test/unit/Keep3rHelperParameters.spec.ts index 48ecc1f..375150a 100644 --- a/test/unit/Keep3rHelperParameters.spec.ts +++ b/test/unit/Keep3rHelperParameters.spec.ts @@ -2,7 +2,7 @@ import { FakeContract, smock } from '@defi-wonderland/smock'; import { KP3R_V1_ADDRESS } from '@e2e/common'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { IUniswapV3Pool, Keep3rHelperParameters, Keep3rHelperParameters__factory } from '@types'; -import { behaviours } from '@utils'; +import { onlyGovernor } from '@utils/behaviours'; import { toUnit } from '@utils/bn'; import { ZERO_ADDRESS } from '@utils/constants'; import { generateRandomAddress } from '@utils/wallet'; @@ -11,13 +11,13 @@ import { Contract } from 'ethers'; import { ethers } from 'hardhat'; describe('Keep3rHelperParameters', () => { - let governance: SignerWithAddress; + let governor: SignerWithAddress; let parametersFactory: Keep3rHelperParameters__factory; let parameters: Keep3rHelperParameters; let pool: FakeContract; before(async () => { - [, governance] = await ethers.getSigners(); + [, governor] = await ethers.getSigners(); parametersFactory = (await ethers.getContractFactory('Keep3rHelperParameters')) as Keep3rHelperParameters__factory; pool = await smock.fake('IUniswapV3Pool'); @@ -31,18 +31,18 @@ describe('Keep3rHelperParameters', () => { const randomKeep3rV2Address = generateRandomAddress(); it('should assign keep3rV2 to given parameter', async () => { - parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, randomKeep3rV2Address, governance.address, pool.address); + parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, randomKeep3rV2Address, governor.address, pool.address); expect(await parameters.callStatic.keep3rV2()).to.equal(randomKeep3rV2Address); }); it('should assign kp3rWethPool address', async () => { - parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, randomKeep3rV2Address, governance.address, pool.address); + parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, randomKeep3rV2Address, governor.address, pool.address); const assignedAddress = (await parameters.callStatic.kp3rWethPool()).poolAddress; expect(assignedAddress).to.equal(pool.address); }); it('should set kp3rWethPool isTKNToken0 to true if KP3R is token0', async () => { - parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, randomKeep3rV2Address, governance.address, pool.address); + parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, randomKeep3rV2Address, governor.address, pool.address); const isTKNToken0 = (await parameters.callStatic.kp3rWethPool()).isTKNToken0; expect(isTKNToken0).to.be.true; }); @@ -50,7 +50,7 @@ describe('Keep3rHelperParameters', () => { it('should set kp3rWethPool isTKNToken0 to false if KP3R is not token0', async () => { pool.token0.returns(generateRandomAddress()); pool.token1.returns(KP3R_V1_ADDRESS); - parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, randomKeep3rV2Address, governance.address, pool.address); + parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, randomKeep3rV2Address, governor.address, pool.address); const isTKNToken0 = (await parameters.callStatic.kp3rWethPool()).isTKNToken0; expect(isTKNToken0).to.be.false; }); @@ -64,23 +64,23 @@ describe('Keep3rHelperParameters', () => { }); beforeEach(async () => { - parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, generateRandomAddress(), governance.address, pool.address); + parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, generateRandomAddress(), governor.address, pool.address); otherPool.token0.returns(KP3R_V1_ADDRESS); }); - behaviours.onlyGovernance( + onlyGovernor( () => parameters, 'setKp3rWethPool', - governance, + governor, () => [otherPool.address] ); it('should revert if pool address is 0', async () => { - await expect(parameters.connect(governance).setKp3rWethPool(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); + await expect(parameters.connect(governor).setKp3rWethPool(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); }); it('should set kp3rWethPool isTKNToken0 to true if KP3R is token0', async () => { - await parameters.connect(governance).setKp3rWethPool(otherPool.address); + await parameters.connect(governor).setKp3rWethPool(otherPool.address); const isTKNToken0 = (await parameters.callStatic.kp3rWethPool()).isTKNToken0; expect(isTKNToken0).to.be.true; }); @@ -89,7 +89,7 @@ describe('Keep3rHelperParameters', () => { otherPool.token0.returns(generateRandomAddress()); otherPool.token1.returns(KP3R_V1_ADDRESS); - await parameters.connect(governance).setKp3rWethPool(otherPool.address); + await parameters.connect(governor).setKp3rWethPool(otherPool.address); const isTKNToken0 = (await parameters.callStatic.kp3rWethPool()).isTKNToken0; expect(isTKNToken0).to.be.false; }); @@ -98,11 +98,11 @@ describe('Keep3rHelperParameters', () => { otherPool.token0.returns(generateRandomAddress()); otherPool.token1.returns(generateRandomAddress()); - await expect(parameters.connect(governance).setKp3rWethPool(otherPool.address)).to.be.revertedWith('InvalidOraclePool()'); + await expect(parameters.connect(governor).setKp3rWethPool(otherPool.address)).to.be.revertedWith('InvalidOraclePool()'); }); it('should emit event', async () => { - await expect(parameters.connect(governance).setKp3rWethPool(otherPool.address)) + await expect(parameters.connect(governor).setKp3rWethPool(otherPool.address)) .to.emit(parameters, 'Kp3rWethPoolChange') .withArgs(otherPool.address, true); }); @@ -112,7 +112,7 @@ describe('Keep3rHelperParameters', () => { const randomKeep3rV2Address = generateRandomAddress(); beforeEach(async () => { - parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, generateRandomAddress(), governance.address, pool.address); + parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, generateRandomAddress(), governor.address, pool.address); }); [ @@ -125,16 +125,16 @@ describe('Keep3rHelperParameters', () => { { name: 'setMinBaseFee', parameter: 'minBaseFee', args: () => [10e9], event: 'MinBaseFeeChange' }, ].forEach((method) => { describe(method.name, () => { - behaviours.onlyGovernance(() => parameters, method.name, governance, method.args); + onlyGovernor(() => parameters, method.name, governor, method.args); it('should assign specified value to variable', async () => { expect(await (parameters as Contract)[method.parameter]()).not.to.be.equal(method.args()[0]); - await (parameters as Contract).connect(governance)[method.name](...method.args()); + await (parameters as Contract).connect(governor)[method.name](...method.args()); expect(await (parameters as Contract)[method.parameter]()).to.be.equal(method.args()[0]); }); it('should emit event', async () => { - await expect((parameters as Contract).connect(governance)[method.name](...method.args())) + await expect((parameters as Contract).connect(governor)[method.name](...method.args())) .to.emit(parameters, method.event) .withArgs(...method.args()); }); diff --git a/test/unit/UniV3PairFactory.spec.ts b/test/unit/UniV3PairFactory.spec.ts index 75ff30f..c6e5459 100644 --- a/test/unit/UniV3PairFactory.spec.ts +++ b/test/unit/UniV3PairFactory.spec.ts @@ -18,10 +18,10 @@ describe('UniV3PairManagerFactory', () => { let uniPairFactory: MockContract; //signers - let governance: SignerWithAddress; + let governor: SignerWithAddress; before(async () => { - [, governance] = await ethers.getSigners(); + [, governor] = await ethers.getSigners(); uniV3PairManagerFactory = await smock.mock('UniV3PairManagerFactory'); pair = await smock.fake('UniV3PairManager'); @@ -37,12 +37,12 @@ describe('UniV3PairManagerFactory', () => { }); beforeEach(async () => { - uniPairFactory = await uniV3PairManagerFactory.deploy(governance.address); + uniPairFactory = await uniV3PairManagerFactory.deploy(governor.address); }); describe('constructor', () => { - it('should set the governance to the deployer', async () => { - expect(await uniPairFactory.governance()).to.equal(governance.address); + it('should set the governor to the deployer', async () => { + expect(await uniPairFactory.governor()).to.equal(governor.address); }); }); diff --git a/test/unit/UniV3PairManager.spec.ts b/test/unit/UniV3PairManager.spec.ts index 7b1c27f..2507ddf 100644 --- a/test/unit/UniV3PairManager.spec.ts +++ b/test/unit/UniV3PairManager.spec.ts @@ -36,7 +36,7 @@ describe('UniV3PairManager', () => { //signers let deployer: SignerWithAddress; - let newGovernance: SignerWithAddress; + let newGovernor: SignerWithAddress; let randomJobProvider: SignerWithAddress; //misc @@ -56,7 +56,7 @@ describe('UniV3PairManager', () => { const MAX_TICK: number = 887272; before(async () => { - [deployer, newGovernance, randomJobProvider] = await ethers.getSigners(); + [deployer, newGovernor, randomJobProvider] = await ethers.getSigners(); uniV3PairManagerFactory = await smock.mock('UniV3PairManagerForTest'); @@ -122,8 +122,8 @@ describe('UniV3PairManager', () => { expect(actualTickUpper).to.equal(upperTick); }); - it('should assign governance to deployer', async () => { - expect(await uniV3PairManager.governance()).to.equal(deployer.address); + it('should assign governor to deployer', async () => { + expect(await uniV3PairManager.governor()).to.equal(deployer.address); }); }); @@ -154,8 +154,8 @@ describe('UniV3PairManager', () => { }); describe('collect', () => { - it('should revert if the caller is not governance', async () => { - await expect(uniV3PairManager.connect(randomJobProvider).collect()).to.be.revertedWith('OnlyGovernance()'); + it('should revert if the caller is not governor', async () => { + await expect(uniV3PairManager.connect(randomJobProvider).collect()).to.be.revertedWith('OnlyGovernor()'); }); it('should call collect with the correct arguments', async () => { @@ -182,7 +182,7 @@ describe('UniV3PairManager', () => { uniswapPool.burn.returns([10, 20]); uniV3PairManager.burn.returns([10, 20]); - await expect(uniV3PairManager.connect(randomJobProvider).burn(liquidity, amount0Min, amount1Min, newGovernance.address)).to.be.reverted; + await expect(uniV3PairManager.connect(randomJobProvider).burn(liquidity, amount0Min, amount1Min, newGovernor.address)).to.be.reverted; }); context('when the caller has credits', () => { @@ -202,13 +202,13 @@ describe('UniV3PairManager', () => { }); it('should call the pools burn function with the correct arguments', async () => { - await uniV3PairManager.connect(deployer).burn(liquidity, amount0Min, amount1Min, newGovernance.address); + await uniV3PairManager.connect(deployer).burn(liquidity, amount0Min, amount1Min, newGovernor.address); expect(uniswapPool.burn).to.be.calledOnceWith(actualTickLower, actualTickUpper, liquidity); }); it('should call the pools collect function with the correct arguments', async () => { - await uniV3PairManager.connect(deployer).burn(liquidity, amount0Min, amount1Min, newGovernance.address); - expect(uniswapPool.collect).to.be.calledOnceWith(newGovernance.address, actualTickLower, actualTickUpper, tokensOwed0, tokensOwed1); + await uniV3PairManager.connect(deployer).burn(liquidity, amount0Min, amount1Min, newGovernor.address); + expect(uniswapPool.collect).to.be.calledOnceWith(newGovernor.address, actualTickLower, actualTickUpper, tokensOwed0, tokensOwed1); }); it('should revert if burn returns less than amountMin', async () => { @@ -223,21 +223,21 @@ describe('UniV3PairManager', () => { describe('approve', () => { it('should increase the balance of the spender', async () => { - await uniV3PairManager.connect(deployer).approve(newGovernance.address, tenTokens); - expect(await uniV3PairManager.allowance(deployer.address, newGovernance.address)).to.equal(tenTokens); + await uniV3PairManager.connect(deployer).approve(newGovernor.address, tenTokens); + expect(await uniV3PairManager.allowance(deployer.address, newGovernor.address)).to.equal(tenTokens); }); it('should emit an event if approve is successful', async () => { - await expect(await uniV3PairManager.connect(deployer).approve(newGovernance.address, tenTokens)) + await expect(await uniV3PairManager.connect(deployer).approve(newGovernor.address, tenTokens)) .to.emit(uniV3PairManager, 'Approval') - .withArgs(deployer.address, newGovernance.address, tenTokens); + .withArgs(deployer.address, newGovernor.address, tenTokens); }); }); describe('transfer', () => { context('when user does not have credits and tries to transfer', () => { it('should revert', async () => { - await expect(uniV3PairManager.connect(deployer).transfer(newGovernance.address, tenTokens)).to.be.reverted; + await expect(uniV3PairManager.connect(deployer).transfer(newGovernor.address, tenTokens)).to.be.reverted; }); }); @@ -249,22 +249,22 @@ describe('UniV3PairManager', () => { }); it('should transfer tokens from one account to another', async () => { - await uniV3PairManager.connect(deployer).transfer(newGovernance.address, tenTokens); - expect(await uniV3PairManager.balanceOf(newGovernance.address)).to.deep.equal(tenTokens); + await uniV3PairManager.connect(deployer).transfer(newGovernor.address, tenTokens); + expect(await uniV3PairManager.balanceOf(newGovernor.address)).to.deep.equal(tenTokens); }); it('should emit an event when a transfer is successful', async () => { - await expect(uniV3PairManager.connect(deployer).transfer(newGovernance.address, tenTokens)) + await expect(uniV3PairManager.connect(deployer).transfer(newGovernor.address, tenTokens)) .to.emit(uniV3PairManager, 'Transfer') - .withArgs(deployer.address, newGovernance.address, tenTokens); + .withArgs(deployer.address, newGovernor.address, tenTokens); }); }); }); describe('transferFrom', () => { it('it should revert when the user does not have funds and has approved an spender', async () => { - expect(await uniV3PairManager.connect(deployer).approve(newGovernance.address, tenTokens)); - await expect(uniV3PairManager.connect(newGovernance).transferFrom(deployer.address, newGovernance.address, tenTokens)).to.be.reverted; + expect(await uniV3PairManager.connect(deployer).approve(newGovernor.address, tenTokens)); + await expect(uniV3PairManager.connect(newGovernor).transferFrom(deployer.address, newGovernor.address, tenTokens)).to.be.reverted; }); context('when user has funds and has approved an spender', () => { @@ -272,29 +272,29 @@ describe('UniV3PairManager', () => { await uniV3PairManager.setVariable('balanceOf', { [deployer.address]: tenTokens, }); - await uniV3PairManager.connect(deployer).approve(newGovernance.address, tenTokens); + await uniV3PairManager.connect(deployer).approve(newGovernor.address, tenTokens); }); it('should transfer tokens from one account to another', async () => { - await uniV3PairManager.connect(newGovernance).transferFrom(deployer.address, newGovernance.address, tenTokens); - expect(await uniV3PairManager.balanceOf(newGovernance.address)).to.deep.equal(tenTokens); + await uniV3PairManager.connect(newGovernor).transferFrom(deployer.address, newGovernor.address, tenTokens); + expect(await uniV3PairManager.balanceOf(newGovernor.address)).to.deep.equal(tenTokens); }); it('should emit an event when a transfer is successful', async () => { - await expect(await uniV3PairManager.connect(newGovernance).transferFrom(deployer.address, newGovernance.address, tenTokens)) + await expect(await uniV3PairManager.connect(newGovernor).transferFrom(deployer.address, newGovernor.address, tenTokens)) .to.emit(uniV3PairManager, 'Transfer') - .withArgs(deployer.address, newGovernance.address, tenTokens); + .withArgs(deployer.address, newGovernor.address, tenTokens); }); it('should reduce the spenders allowance after a transferFrom', async () => { - await uniV3PairManager.connect(newGovernance).transferFrom(deployer.address, newGovernance.address, tenTokens); - expect(await uniV3PairManager.allowance(deployer.address, newGovernance.address)).to.deep.equal(0); + await uniV3PairManager.connect(newGovernor).transferFrom(deployer.address, newGovernor.address, tenTokens); + expect(await uniV3PairManager.allowance(deployer.address, newGovernor.address)).to.deep.equal(0); }); it('should emit an event when the allowance is changed', async () => { - await expect(await uniV3PairManager.connect(newGovernance).transferFrom(deployer.address, newGovernance.address, tenTokens)) + await expect(await uniV3PairManager.connect(newGovernor).transferFrom(deployer.address, newGovernor.address, tenTokens)) .to.emit(uniV3PairManager, 'Approval') - .withArgs(deployer.address, newGovernance.address, 0); + .withArgs(deployer.address, newGovernor.address, 0); }); }); }); @@ -352,19 +352,19 @@ describe('UniV3PairManager', () => { describe('_mint', () => { it('should mint credits to the recipient', async () => { - await uniV3PairManager.internalMint(newGovernance.address, tenTokens); - expect(await uniV3PairManager.balanceOf(newGovernance.address)).to.equal(tenTokens); + await uniV3PairManager.internalMint(newGovernor.address, tenTokens); + expect(await uniV3PairManager.balanceOf(newGovernor.address)).to.equal(tenTokens); }); it('should increase the contracts totalSupply', async () => { - await uniV3PairManager.internalMint(newGovernance.address, tenTokens); + await uniV3PairManager.internalMint(newGovernor.address, tenTokens); expect(await uniV3PairManager.totalSupply()).to.equal(tenTokens); }); it('should emit an event if the credits have been minted successfuly', async () => { - await expect(await uniV3PairManager.internalMint(newGovernance.address, tenTokens)) + await expect(await uniV3PairManager.internalMint(newGovernor.address, tenTokens)) .to.emit(uniV3PairManager, 'Transfer') - .withArgs(ZERO_ADDRESS, newGovernance.address, tenTokens); + .withArgs(ZERO_ADDRESS, newGovernor.address, tenTokens); }); }); @@ -402,12 +402,12 @@ describe('UniV3PairManager', () => { describe('_pay', () => { it('should transfer tokens to the recipient', async () => { await fakeERC20.connect(deployer).approve(uniV3PairManager.address, tenTokens); - await uniV3PairManager.internalPay(fakeERC20.address, deployer.address, newGovernance.address, tenTokens); - expect(await fakeERC20.balanceOf(newGovernance.address)).to.equal(tenTokens); + await uniV3PairManager.internalPay(fakeERC20.address, deployer.address, newGovernor.address, tenTokens); + expect(await fakeERC20.balanceOf(newGovernor.address)).to.equal(tenTokens); }); it('should fail if payer did not approve the contract to spend his tokens', async () => { - await expect(uniV3PairManager.internalPay(fakeERC20.address, deployer.address, newGovernance.address, tenTokens)).to.be.revertedWith( + await expect(uniV3PairManager.internalPay(fakeERC20.address, deployer.address, newGovernor.address, tenTokens)).to.be.revertedWith( 'UnsuccessfulTransfer()' ); }); diff --git a/test/unit/peripherals/DustCollector.spec.ts b/test/unit/peripherals/DustCollector.spec.ts deleted file mode 100644 index d4f6cdc..0000000 --- a/test/unit/peripherals/DustCollector.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { FakeContract, MockContract, MockContractFactory, smock } from '@defi-wonderland/smock'; -import { BigNumber } from '@ethersproject/bignumber'; -import { Wallet } from '@ethersproject/wallet'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -import { DustCollectorForTest, DustCollectorForTest__factory, IERC20 } from '@types'; -import { contracts, wallet } from '@utils'; -import { onlyGovernance } from '@utils/behaviours'; -import { toUnit } from '@utils/bn'; -import { ETH_ADDRESS, ZERO_ADDRESS } from '@utils/constants'; -import chai, { expect } from 'chai'; -import { ethers } from 'hardhat'; - -chai.use(smock.matchers); - -describe('DustCollectorForTest', () => { - let dust: MockContract; - let dustFactory: MockContractFactory; - let governance: SignerWithAddress; - let fakeERC20: FakeContract; - let randomAddress = wallet.generateRandomAddress(); - let oneEth: BigNumber = toUnit(1); - let tenTokens: BigNumber = toUnit(10); - - before(async () => { - [, governance] = await ethers.getSigners(); - dustFactory = await smock.mock('DustCollectorForTest'); - }); - - beforeEach(async () => { - dust = await dustFactory.connect(governance).deploy(); - fakeERC20 = await smock.fake('IERC20'); - await contracts.setBalance(dust.address, tenTokens); - }); - - describe('sendDust', () => { - onlyGovernance( - () => dust, - 'sendDust', - governance, - () => [fakeERC20.address, tenTokens, randomAddress] - ); - - it('should revert if the receiver is the zero address', async () => { - await expect(dust.sendDust(ETH_ADDRESS, oneEth, ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); - }); - - it('should revert if the address is neither an ERC20 nor ETH', async () => { - await expect(dust.sendDust(dust.address, oneEth, randomAddress)).to.be.revertedWith('SafeERC20: low-level call failed'); - }); - - it('should revert if transfer fails', async () => { - await expect(dust.sendDust(fakeERC20.address, tenTokens, randomAddress)).to.be.revertedWith('SafeERC20: ERC20 operation did not succeed'); - }); - - context('when the function is called with the correct parameters', () => { - let ETH_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; - let randomUser: Wallet; - - before(async () => { - randomUser = await wallet.generateRandom(); - }); - - it('should transfer ETH successfully', async () => { - await dust.sendDust(ETH_ADDRESS, oneEth, randomUser.address); - expect(await randomUser.getBalance()).to.equal(oneEth); - }); - - it('should emit an event if the transfer is successful', async () => { - let ETH_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; - await expect(dust.sendDust(ETH_ADDRESS, oneEth, randomAddress)).to.emit(dust, 'DustSent').withArgs(ETH_ADDRESS, oneEth, randomAddress); - }); - - it('should call the transfer with the correct arguments', async () => { - fakeERC20.transfer.returns(true); - await dust.sendDust(fakeERC20.address, tenTokens, randomAddress); - expect(fakeERC20.transfer).to.have.been.calledWith(randomAddress, tenTokens); - }); - }); - }); -}); diff --git a/test/unit/peripherals/Governable.spec.ts b/test/unit/peripherals/Governable.spec.ts deleted file mode 100644 index 9e99d9e..0000000 --- a/test/unit/peripherals/Governable.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { MockContract, MockContractFactory, smock } from '@defi-wonderland/smock'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -import { GovernableForTest, GovernableForTest__factory } from '@types'; -import { behaviours, wallet } from '@utils'; -import { ZERO_ADDRESS } from '@utils/constants'; -import { expect } from 'chai'; -import { ethers } from 'hardhat'; - -describe('Governable', () => { - let governance: SignerWithAddress; - let pendingGovernance: SignerWithAddress; - let governableFactory: MockContractFactory; - - const randomAddress = wallet.generateRandomAddress(); - - before(async () => { - [, governance, pendingGovernance] = await ethers.getSigners(); - governableFactory = await smock.mock('GovernableForTest'); - }); - - describe('constructor', () => { - it('should revert when given zero address', async () => { - await expect(governableFactory.deploy(ZERO_ADDRESS)).to.be.revertedWith('NoGovernanceZeroAddress()'); - }); - }); - - context('after deployed', () => { - let governable: MockContract; - - beforeEach(async () => { - governable = await governableFactory.deploy(governance.address); - }); - - describe('setGovernance', () => { - behaviours.onlyGovernance(() => governable, 'setGovernance', governance, [randomAddress]); - - it('should set pendingGovernance', async () => { - await governable.connect(governance).setGovernance(randomAddress); - expect(await governable.pendingGovernance()).to.be.eq(randomAddress); - }); - - it('should emit event', async () => { - const tx = await governable.connect(governance).setGovernance(randomAddress); - await expect(tx).to.emit(governable, 'GovernanceProposal').withArgs(randomAddress); - }); - }); - - describe('acceptGovernance', () => { - beforeEach(async () => { - await governable.setVariable('pendingGovernance', pendingGovernance.address); - }); - - behaviours.onlyPendingGovernance(() => governable, 'acceptGovernance', pendingGovernance, []); - - it('should set governance', async () => { - await governable.connect(pendingGovernance).acceptGovernance(); - expect(await governable.governance()).to.be.eq(pendingGovernance.address); - }); - - it('should remove pending governance', async () => { - await governable.connect(pendingGovernance).acceptGovernance(); - expect(await governable.pendingGovernance()).to.be.eq(ZERO_ADDRESS); - }); - - it('should emit event', async () => { - const tx = await governable.connect(pendingGovernance).acceptGovernance(); - await expect(tx).to.emit(governable, 'GovernanceSet').withArgs(pendingGovernance.address); - }); - }); - }); -}); diff --git a/test/unit/peripherals/Keep3rParameters.spec.ts b/test/unit/peripherals/Keep3rParameters.spec.ts index 7e6d9f0..341e8ae 100644 --- a/test/unit/peripherals/Keep3rParameters.spec.ts +++ b/test/unit/peripherals/Keep3rParameters.spec.ts @@ -1,7 +1,8 @@ import { FakeContract, MockContract, MockContractFactory, smock } from '@defi-wonderland/smock'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { IKeep3rV1Proxy, Keep3rHelper, Keep3rParametersForTest, Keep3rParametersForTest__factory } from '@types'; -import { behaviours, wallet } from '@utils'; +import { wallet } from '@utils'; +import { onlyGovernor } from '@utils/behaviours'; import { toUnit } from '@utils/bn'; import { ZERO_ADDRESS } from '@utils/constants'; import { expect } from 'chai'; @@ -10,7 +11,7 @@ import { ethers } from 'hardhat'; describe('Keep3rParameters', () => { let parameters: MockContract; - let governance: SignerWithAddress; + let governor: SignerWithAddress; let parametersFactory: MockContractFactory; let keep3rHelper: FakeContract; let keep3rV1Proxy: FakeContract; @@ -18,7 +19,7 @@ describe('Keep3rParameters', () => { const randomAddress = wallet.generateRandomAddress(); before(async () => { - [governance] = await ethers.getSigners(); + [governor] = await ethers.getSigners(); keep3rV1Proxy = await smock.fake('IKeep3rV1Proxy'); parametersFactory = await smock.mock('Keep3rParametersForTest'); @@ -43,7 +44,7 @@ describe('Keep3rParameters', () => { ].forEach((method) => { describe(method.name, () => { let parametersContract: Contract; - behaviours.onlyGovernance(() => parameters, method.name, governance, method.args); + onlyGovernor(() => parameters, method.name, governor, method.args); beforeEach(async () => { parametersContract = parameters as unknown as Contract; diff --git a/test/unit/peripherals/Keep3rRoles.spec.ts b/test/unit/peripherals/Keep3rRoles.spec.ts index 6094cb3..d1081de 100644 --- a/test/unit/peripherals/Keep3rRoles.spec.ts +++ b/test/unit/peripherals/Keep3rRoles.spec.ts @@ -1,7 +1,8 @@ import { MockContract, MockContractFactory, smock } from '@defi-wonderland/smock'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { Keep3rRoles, Keep3rRoles__factory } from '@types'; -import { behaviours, wallet } from '@utils'; +import { wallet } from '@utils'; +import { onlyGovernor } from '@utils/behaviours'; import { ZERO_ADDRESS } from '@utils/constants'; import chai, { expect } from 'chai'; import { ethers } from 'hardhat'; @@ -10,102 +11,102 @@ chai.use(smock.matchers); describe('Keep3rRoles', () => { let roles: MockContract; - let governance: SignerWithAddress; + let governor: SignerWithAddress; let rolesFactory: MockContractFactory; const randomAddress = wallet.generateRandomAddress(); before(async () => { rolesFactory = await smock.mock('Keep3rRoles'); - [, governance] = await ethers.getSigners(); + [, governor] = await ethers.getSigners(); }); beforeEach(async () => { - roles = await rolesFactory.deploy(governance.address); + roles = await rolesFactory.deploy(governor.address); }); describe('addSlasher', () => { - behaviours.onlyGovernance(() => roles, 'addSlasher', governance, [randomAddress]); + onlyGovernor(() => roles, 'addSlasher', governor, [randomAddress]); it('should revert if slasher is address 0', async () => { - await expect(roles.connect(governance).addSlasher(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); + await expect(roles.connect(governor).addSlasher(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); }); it('should revert if slasher already added', async () => { await roles.setVariable('slashers', { [randomAddress]: true }); - await expect(roles.connect(governance).addSlasher(randomAddress)).to.be.revertedWith('SlasherExistent()'); + await expect(roles.connect(governor).addSlasher(randomAddress)).to.be.revertedWith('SlasherExistent()'); }); it('should add the slasher', async () => { - await roles.connect(governance).addSlasher(randomAddress); + await roles.connect(governor).addSlasher(randomAddress); expect(await roles.slashers(randomAddress)).to.be.true; }); it('should emit event', async () => { - const tx = await roles.connect(governance).addSlasher(randomAddress); + const tx = await roles.connect(governor).addSlasher(randomAddress); await expect(tx).to.emit(roles, 'SlasherAdded').withArgs(randomAddress); }); }); describe('removeSlasher', () => { - behaviours.onlyGovernance(() => roles, 'removeSlasher', governance, [randomAddress]); + onlyGovernor(() => roles, 'removeSlasher', governor, [randomAddress]); it('should revert if slasher not added', async () => { - await expect(roles.connect(governance).removeSlasher(randomAddress)).to.be.revertedWith('SlasherUnexistent()'); + await expect(roles.connect(governor).removeSlasher(randomAddress)).to.be.revertedWith('SlasherUnexistent()'); }); it('should remove the slasher', async () => { await roles.setVariable('slashers', { [randomAddress]: true }); - await roles.connect(governance).removeSlasher(randomAddress); + await roles.connect(governor).removeSlasher(randomAddress); expect(await roles.slashers(randomAddress)).to.be.false; }); it('should emit event', async () => { await roles.setVariable('slashers', { [randomAddress]: true }); - const tx = await roles.connect(governance).removeSlasher(randomAddress); + const tx = await roles.connect(governor).removeSlasher(randomAddress); await expect(tx).to.emit(roles, 'SlasherRemoved').withArgs(randomAddress); }); }); describe('addDisputer', () => { - behaviours.onlyGovernance(() => roles, 'addDisputer', governance, [randomAddress]); + onlyGovernor(() => roles, 'addDisputer', governor, [randomAddress]); it('should revert if disputer is address 0', async () => { - await expect(roles.connect(governance).addDisputer(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); + await expect(roles.connect(governor).addDisputer(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); }); it('should revert if disputer already added', async () => { await roles.setVariable('disputers', { [randomAddress]: true }); - await expect(roles.connect(governance).addDisputer(randomAddress)).to.be.revertedWith('DisputerExistent()'); + await expect(roles.connect(governor).addDisputer(randomAddress)).to.be.revertedWith('DisputerExistent()'); }); it('should add the disputer', async () => { - await roles.connect(governance).addDisputer(randomAddress); + await roles.connect(governor).addDisputer(randomAddress); expect(await roles.disputers(randomAddress)).to.be.true; }); it('should emit event', async () => { - const tx = await roles.connect(governance).addDisputer(randomAddress); + const tx = await roles.connect(governor).addDisputer(randomAddress); await expect(tx).to.emit(roles, 'DisputerAdded').withArgs(randomAddress); }); }); describe('removeDisputer', () => { - behaviours.onlyGovernance(() => roles, 'removeDisputer', governance, [randomAddress]); + onlyGovernor(() => roles, 'removeDisputer', governor, [randomAddress]); it('should revert if disputer not added', async () => { - await expect(roles.connect(governance).removeSlasher(randomAddress)).to.be.revertedWith('SlasherUnexistent()'); + await expect(roles.connect(governor).removeSlasher(randomAddress)).to.be.revertedWith('SlasherUnexistent()'); }); it('should remove the disputer', async () => { await roles.setVariable('disputers', { [randomAddress]: true }); - await roles.connect(governance).removeDisputer(randomAddress); + await roles.connect(governor).removeDisputer(randomAddress); expect(await roles.slashers(randomAddress)).to.be.false; }); it('should emit event', async () => { await roles.setVariable('disputers', { [randomAddress]: true }); - const tx = await roles.connect(governance).removeDisputer(randomAddress); + const tx = await roles.connect(governor).removeDisputer(randomAddress); await expect(tx).to.emit(roles, 'DisputerRemoved').withArgs(randomAddress); }); }); diff --git a/test/unit/peripherals/jobs/Keep3rJobDisputable.spec.ts b/test/unit/peripherals/jobs/Keep3rJobDisputable.spec.ts index f46551a..aa18c5d 100644 --- a/test/unit/peripherals/jobs/Keep3rJobDisputable.spec.ts +++ b/test/unit/peripherals/jobs/Keep3rJobDisputable.spec.ts @@ -21,7 +21,7 @@ chai.use(smock.matchers); describe('Keep3rJobDisputable', () => { const job = wallet.generateRandomAddress(); - let governance: SignerWithAddress; + let governor: SignerWithAddress; let slasher: SignerWithAddress; let disputer: SignerWithAddress; let jobDisputable: MockContract; @@ -40,7 +40,7 @@ describe('Keep3rJobDisputable', () => { let snapshotId: string; before(async () => { - [governance, slasher, disputer] = await ethers.getSigners(); + [governor, slasher, disputer] = await ethers.getSigners(); jobDisputableFactory = await smock.mock('Keep3rJobDisputableForTest'); helper = await smock.fake('IKeep3rHelper'); @@ -122,8 +122,8 @@ describe('Keep3rJobDisputable', () => { tx = await jobDisputable.connect(slasher).slashTokenFromJob(job, tokenA.address, tokenAToRemove); }); - it('should transfer the tokens to governance', async () => { - expect(tokenA.transfer).to.be.calledOnceWith(governance.address, tokenAToRemove); + it('should transfer the tokens to governor', async () => { + expect(tokenA.transfer).to.be.calledOnceWith(governor.address, tokenAToRemove); }); it('should reduce the specified amount from token credits', async () => { @@ -155,7 +155,7 @@ describe('Keep3rJobDisputable', () => { it('should call the transfer function', async () => { await jobDisputable.connect(slasher).slashTokenFromJob(job, tokenA.address, initialTokenA); - expect(tokenA.transfer).to.be.calledOnceWith(governance.address, initialTokenA); + expect(tokenA.transfer).to.be.calledOnceWith(governor.address, initialTokenA); }); it('should slash the token', async () => { @@ -238,9 +238,9 @@ describe('Keep3rJobDisputable', () => { await jobDisputable.setRevokedLiquidity(liquidityA.address); }); - it('should transfer the tokens to governance', async () => { + it('should transfer the tokens to governor', async () => { await jobDisputable.connect(slasher).slashLiquidityFromJob(job, liquidityA.address, liquidityAToRemove); - expect(liquidityA.transfer).to.be.calledOnceWith(governance.address, liquidityAToRemove); + expect(liquidityA.transfer).to.be.calledOnceWith(governor.address, liquidityAToRemove); }); it('should emit an event', async () => { @@ -256,8 +256,8 @@ describe('Keep3rJobDisputable', () => { tx = await jobDisputable.connect(slasher).slashLiquidityFromJob(job, liquidityA.address, liquidityAToRemove); }); - it('should transfer the tokens to governance', async () => { - expect(liquidityA.transfer).to.be.calledOnceWith(governance.address, liquidityAToRemove); + it('should transfer the tokens to governor', async () => { + expect(liquidityA.transfer).to.be.calledOnceWith(governor.address, liquidityAToRemove); }); it('should reduce the specified amount from liquidity accountance', async () => { @@ -302,7 +302,7 @@ describe('Keep3rJobDisputable', () => { it('should call the transfer function', async () => { await jobDisputable.connect(slasher).slashLiquidityFromJob(job, liquidityA.address, liquidityAToRemove); - expect(liquidityA.transfer).to.be.calledOnceWith(governance.address, liquidityAToRemove); + expect(liquidityA.transfer).to.be.calledOnceWith(governor.address, liquidityAToRemove); }); it('should slash the liquidity', async () => { diff --git a/test/unit/peripherals/jobs/Keep3rJobFundableCredits.spec.ts b/test/unit/peripherals/jobs/Keep3rJobFundableCredits.spec.ts index d92ed25..8278e06 100644 --- a/test/unit/peripherals/jobs/Keep3rJobFundableCredits.spec.ts +++ b/test/unit/peripherals/jobs/Keep3rJobFundableCredits.spec.ts @@ -22,7 +22,7 @@ chai.use(smock.matchers); describe('Keep3rJobFundableCredits', () => { const approvedJob = wallet.generateRandomAddress(); const randomJob = wallet.generateRandomAddress(); - let governance: SignerWithAddress; + let governor: SignerWithAddress; let provider: SignerWithAddress; let jobOwner: SignerWithAddress; let jobFundable: MockContract; @@ -35,7 +35,7 @@ describe('Keep3rJobFundableCredits', () => { let snapshotId: string; before(async () => { - [governance, provider, jobOwner] = await ethers.getSigners(); + [governor, provider, jobOwner] = await ethers.getSigners(); jobFundableFactory = await smock.mock('Keep3rJobFundableCreditsForTest'); helper = await smock.fake('IKeep3rHelper'); @@ -101,9 +101,9 @@ describe('Keep3rJobFundableCredits', () => { expect(await jobFundable.jobTokenCreditsAddedAt(approvedJob, token.address)).to.equal(blockTimestamp); }); - it('should transfer fee in tokens to governance', async () => { + it('should transfer fee in tokens to governor', async () => { await jobFundable.connect(provider).addTokenCreditsToJob(approvedJob, token.address, toUnit(1)); - expect(await token.balanceOf(governance.address)).to.equal(toUnit(0.003)); + expect(await token.balanceOf(governor.address)).to.equal(toUnit(0.003)); }); it('should emit event', async () => { diff --git a/test/unit/peripherals/jobs/Keep3rJobFundableLiquidity.spec.ts b/test/unit/peripherals/jobs/Keep3rJobFundableLiquidity.spec.ts index 90ba30f..ddaa3dc 100644 --- a/test/unit/peripherals/jobs/Keep3rJobFundableLiquidity.spec.ts +++ b/test/unit/peripherals/jobs/Keep3rJobFundableLiquidity.spec.ts @@ -9,8 +9,8 @@ import { Keep3rJobFundableLiquidityForTest__factory, UniV3PairManager, } from '@types'; -import { behaviours, evm, wallet } from '@utils'; -import { onlyJobOwner } from '@utils/behaviours'; +import { evm, wallet } from '@utils'; +import { onlyGovernor, onlyJobOwner } from '@utils/behaviours'; import { toUnit } from '@utils/bn'; import { ZERO_ADDRESS } from '@utils/constants'; import { MathUtils, mathUtilsFactory } from '@utils/math'; @@ -23,7 +23,7 @@ chai.use(smock.matchers); describe('Keep3rJobFundableLiquidity', () => { const randomJob = wallet.generateRandomAddress(); - let governance: SignerWithAddress; + let governor: SignerWithAddress; let provider: SignerWithAddress; let jobOwner: SignerWithAddress; let jobFundable: MockContract; @@ -44,7 +44,7 @@ describe('Keep3rJobFundableLiquidity', () => { let snapshotId: string; before(async () => { - [governance, jobOwner, provider] = await ethers.getSigners(); + [governor, jobOwner, provider] = await ethers.getSigners(); jobFundableFactory = await smock.mock('Keep3rJobFundableLiquidityForTest'); helper = await smock.fake('IKeep3rHelper'); @@ -218,7 +218,7 @@ describe('Keep3rJobFundableLiquidity', () => { beforeEach(async () => { randomLiquidity.token0.returns(keep3rV1.address); - await jobFundable.connect(governance).approveLiquidity(randomLiquidity.address); + await jobFundable.connect(governor).approveLiquidity(randomLiquidity.address); await jobFundable.setJobLiquidity(randomJob, randomLiquidity.address); await jobFundable.setVariable('liquidityAmount', { [randomJob]: { [randomLiquidity.address]: liquidityAmount } }); @@ -638,7 +638,7 @@ describe('Keep3rJobFundableLiquidity', () => { }); describe('forceLiquidityCreditsToJob', () => { - behaviours.onlyGovernance(() => jobFundable, 'forceLiquidityCreditsToJob', governance, [randomJob, 1]); + onlyGovernor(() => jobFundable, 'forceLiquidityCreditsToJob', governor, [randomJob, 1]); it('should revert when called with unallowed job', async () => { await expect(jobFundable.forceLiquidityCreditsToJob(randomJob, toUnit(1))).to.be.revertedWith('JobUnavailable()'); @@ -701,7 +701,7 @@ describe('Keep3rJobFundableLiquidity', () => { it('should emit event', async () => { const forcedLiquidityAmount = toUnit(1); - const tx = await jobFundable.connect(governance).forceLiquidityCreditsToJob(randomJob, forcedLiquidityAmount); + const tx = await jobFundable.connect(governor).forceLiquidityCreditsToJob(randomJob, forcedLiquidityAmount); const rewardedAt = (await ethers.provider.getBlock('latest')).timestamp; await expect(tx).to.emit(jobFundable, 'LiquidityCreditsForced').withArgs(randomJob, rewardedAt, forcedLiquidityAmount); @@ -710,64 +710,64 @@ describe('Keep3rJobFundableLiquidity', () => { }); describe('approveLiquidity', () => { - behaviours.onlyGovernance( + onlyGovernor( () => jobFundable, 'approveLiquidity', - governance, + governor, () => [approvedLiquidity.address] ); it('should revert when liquidity already approved', async () => { - await expect(jobFundable.connect(governance).approveLiquidity(approvedLiquidity.address)).to.be.revertedWith('LiquidityPairApproved()'); + await expect(jobFundable.connect(governor).approveLiquidity(approvedLiquidity.address)).to.be.revertedWith('LiquidityPairApproved()'); }); it('should add the liquidity to approved liquidities list', async () => { - await jobFundable.connect(governance).approveLiquidity(randomLiquidity.address); + await jobFundable.connect(governor).approveLiquidity(randomLiquidity.address); expect(await jobFundable.approvedLiquidities()).to.contain(randomLiquidity.address); }); it('should sort the tokens in the liquidity pair', async () => { - await jobFundable.connect(governance).approveLiquidity(randomLiquidity.address); + await jobFundable.connect(governor).approveLiquidity(randomLiquidity.address); expect(await jobFundable.viewTickOrder(randomLiquidity.address)).to.be.true; }); it('should initialize twap for liquidity', async () => { - await jobFundable.connect(governance).approveLiquidity(randomLiquidity.address); + await jobFundable.connect(governor).approveLiquidity(randomLiquidity.address); expect(helper.observe).to.have.been.called; }); it('should emit event', async () => { - await expect(jobFundable.connect(governance).approveLiquidity(randomLiquidity.address)) + await expect(jobFundable.connect(governor).approveLiquidity(randomLiquidity.address)) .to.emit(jobFundable, 'LiquidityApproval') .withArgs(randomLiquidity.address); }); }); describe('revokeLiquidity', () => { - behaviours.onlyGovernance( + onlyGovernor( () => jobFundable, 'revokeLiquidity', - governance, + governor, () => [approvedLiquidity.address] ); it('should not be able to remove unapproved liquidity', async () => { - await expect(jobFundable.connect(governance).revokeLiquidity(randomLiquidity.address)).to.be.revertedWith('LiquidityPairUnexistent()'); + await expect(jobFundable.connect(governor).revokeLiquidity(randomLiquidity.address)).to.be.revertedWith('LiquidityPairUnexistent()'); }); it('should not be able to remove the same liquidity twice', async () => { - await jobFundable.connect(governance).revokeLiquidity(approvedLiquidity.address); - await expect(jobFundable.connect(governance).revokeLiquidity(approvedLiquidity.address)).to.be.revertedWith('LiquidityPairUnexistent()'); + await jobFundable.connect(governor).revokeLiquidity(approvedLiquidity.address); + await expect(jobFundable.connect(governor).revokeLiquidity(approvedLiquidity.address)).to.be.revertedWith('LiquidityPairUnexistent()'); }); it('should remove liquidity', async () => { - await jobFundable.connect(governance).revokeLiquidity(approvedLiquidity.address); + await jobFundable.connect(governor).revokeLiquidity(approvedLiquidity.address); expect(await jobFundable.approvedLiquidities()).not.to.contain(approvedLiquidity.address); }); it('should not remove other liquidities', async () => { - await jobFundable.connect(governance).approveLiquidity(randomLiquidity.address); - await jobFundable.connect(governance).revokeLiquidity(approvedLiquidity.address); + await jobFundable.connect(governor).approveLiquidity(randomLiquidity.address); + await jobFundable.connect(governor).revokeLiquidity(approvedLiquidity.address); expect(await jobFundable.approvedLiquidities()).to.contain(randomLiquidity.address); }); @@ -776,12 +776,12 @@ describe('Keep3rJobFundableLiquidity', () => { await jobFundable.connect(provider).addLiquidityToJob(randomJob, approvedLiquidity.address, toUnit(10)); expect(await jobFundable.jobPeriodCredits(randomJob)).to.be.gt(0); - await jobFundable.connect(governance).revokeLiquidity(approvedLiquidity.address); + await jobFundable.connect(governor).revokeLiquidity(approvedLiquidity.address); expect(await jobFundable.jobPeriodCredits(randomJob)).to.be.eq(toUnit(0)); }); it('should emit event', async () => { - await expect(jobFundable.connect(governance).revokeLiquidity(approvedLiquidity.address)) + await expect(jobFundable.connect(governor).revokeLiquidity(approvedLiquidity.address)) .to.emit(jobFundable, 'LiquidityRevocation') .withArgs(approvedLiquidity.address); }); @@ -1093,8 +1093,8 @@ describe('Keep3rJobFundableLiquidity', () => { }); it('should transfer unbonded liquidity to the receiver', async () => { - await jobFundable.connect(jobOwner).withdrawLiquidityFromJob(randomJob, approvedLiquidity.address, governance.address); - expect(approvedLiquidity.transfer).to.have.been.calledOnceWith(governance.address, unbondedAmount); + await jobFundable.connect(jobOwner).withdrawLiquidityFromJob(randomJob, approvedLiquidity.address, governor.address); + expect(approvedLiquidity.transfer).to.have.been.calledOnceWith(governor.address, unbondedAmount); }); it('should emit event', async () => { diff --git a/test/unit/peripherals/keepers/Keep3rKeeperDisputable.spec.ts b/test/unit/peripherals/keepers/Keep3rKeeperDisputable.spec.ts index d7ece94..8630617 100644 --- a/test/unit/peripherals/keepers/Keep3rKeeperDisputable.spec.ts +++ b/test/unit/peripherals/keepers/Keep3rKeeperDisputable.spec.ts @@ -20,7 +20,7 @@ chai.use(smock.matchers); describe('Keep3rKeeperDisputable', () => { const randomKeeper = wallet.generateRandomAddress(); - let governance: SignerWithAddress; + let governor: SignerWithAddress; let slasher: SignerWithAddress; let disputer: SignerWithAddress; let keeperDisputable: MockContract; @@ -33,7 +33,7 @@ describe('Keep3rKeeperDisputable', () => { let snapshotId: string; before(async () => { - [governance, slasher, disputer] = await ethers.getSigners(); + [governor, slasher, disputer] = await ethers.getSigners(); keeperDisputableFactory = await smock.mock('Keep3rKeeperDisputableForTest'); helper = await smock.fake('IKeep3rHelper'); @@ -176,9 +176,9 @@ describe('Keep3rKeeperDisputable', () => { await expect(keeperDisputable.internalSlash(randomKeeper, erc20.address, toUnit(1), toUnit(1))).not.to.be.reverted; }); - it('should transfer both bond and pending unbond tokens to governance', async () => { + it('should transfer both bond and pending unbond tokens to governor', async () => { await keeperDisputable.internalSlash(randomKeeper, erc20.address, bondAmount, unbondAmount); - expect(erc20.transfer).to.be.calledOnceWith(governance.address, bondAmount.add(unbondAmount)); + expect(erc20.transfer).to.be.calledOnceWith(governor.address, bondAmount.add(unbondAmount)); }); it('should reduce keeper bonds', async () => { diff --git a/test/unit/sidechain/Keep3rEscrow.spec.ts b/test/unit/sidechain/Keep3rEscrow.spec.ts index cdd7828..81928ce 100644 --- a/test/unit/sidechain/Keep3rEscrow.spec.ts +++ b/test/unit/sidechain/Keep3rEscrow.spec.ts @@ -2,14 +2,14 @@ import { FakeContract, MockContract, MockContractFactory, smock } from '@defi-wo import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { IERC20, Keep3rEscrow, Keep3rEscrow__factory } from '@types'; import { wallet } from '@utils'; -import { onlyGovernance, onlyMinter } from '@utils/behaviours'; +import { onlyGovernor, onlyMinter } from '@utils/behaviours'; import { toUnit } from '@utils/bn'; import { ZERO_ADDRESS } from '@utils/constants'; import { expect } from 'chai'; import { ethers } from 'hardhat'; describe('Keep3rEscrow', () => { - let governance: SignerWithAddress; + let governor: SignerWithAddress; let minter: SignerWithAddress; let randomUser: SignerWithAddress; let escrowFactory: MockContractFactory; @@ -20,19 +20,19 @@ describe('Keep3rEscrow', () => { const randomAddress = wallet.generateRandomAddress(); before(async () => { - [, governance, minter, randomUser] = await ethers.getSigners(); + [, governor, minter, randomUser] = await ethers.getSigners(); wKP3R = await smock.fake('IERC20'); escrowFactory = await smock.mock('Keep3rEscrow'); }); beforeEach(async () => { - escrow = await escrowFactory.deploy(governance.address, wKP3R.address); - await escrow.connect(governance).setMinter(minter.address); + escrow = await escrowFactory.deploy(governor.address, wKP3R.address); + await escrow.connect(governor).setMinter(minter.address); }); context('constructor', () => { - it('should set governance to the deployer address', async () => { - expect(await escrow.governance()).to.equal(governance.address); + it('should set governor to the deployer address', async () => { + expect(await escrow.governor()).to.equal(governor.address); }); it('should set wKP3R to the right address', async () => { @@ -41,19 +41,19 @@ describe('Keep3rEscrow', () => { }); describe('setMinter', () => { - onlyGovernance(() => escrow, 'setMinter', governance, [randomAddress]); + onlyGovernor(() => escrow, 'setMinter', governor, [randomAddress]); it('should revert if minter is address 0', async () => { - await expect(escrow.connect(governance).setMinter(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); + await expect(escrow.connect(governor).setMinter(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); }); it('should set the minter address', async () => { - await escrow.connect(governance).setMinter(randomAddress); + await escrow.connect(governor).setMinter(randomAddress); expect(await escrow.minter()).to.eq(randomAddress); }); it('should emit event', async () => { - const tx = await escrow.connect(governance).setMinter(randomAddress); + const tx = await escrow.connect(governor).setMinter(randomAddress); await expect(tx).to.emit(escrow, 'MinterSet').withArgs(randomAddress); }); }); @@ -78,7 +78,7 @@ describe('Keep3rEscrow', () => { context('mint', () => { beforeEach(async () => { - await escrow.connect(governance).setWKP3R(wKP3R.address); + await escrow.connect(governor).setWKP3R(wKP3R.address); wKP3R.balanceOf.whenCalledWith(escrow.address).returns(oneToken); wKP3R.transfer.whenCalledWith(minter.address, oneToken).returns(true); }); @@ -104,24 +104,24 @@ describe('Keep3rEscrow', () => { context('setWKP3R', () => { const randomAddress = wallet.generateRandomAddress(); - onlyGovernance( + onlyGovernor( () => escrow, 'setWKP3R', - governance, + governor, () => [randomAddress] ); it('should revert if wkp3r address is 0', async () => { - await expect(escrow.connect(governance).setWKP3R(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); + await expect(escrow.connect(governor).setWKP3R(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); }); it('should set wKP3R to a new address', async () => { - await escrow.connect(governance).setWKP3R(randomAddress); + await escrow.connect(governor).setWKP3R(randomAddress); expect(await escrow.wKP3R()).to.eq(randomAddress); }); it('should emit an event', async () => { - expect(await escrow.connect(governance).setWKP3R(randomAddress)) + expect(await escrow.connect(governor).setWKP3R(randomAddress)) .to.emit(escrow, 'wKP3RSet') .withArgs(randomAddress); }); diff --git a/test/unit/sidechain/Keep3rHelperSidechain.spec.ts b/test/unit/sidechain/Keep3rHelperSidechain.spec.ts index 387b228..226e414 100644 --- a/test/unit/sidechain/Keep3rHelperSidechain.spec.ts +++ b/test/unit/sidechain/Keep3rHelperSidechain.spec.ts @@ -3,7 +3,7 @@ import { KP3R_V1_ADDRESS, WETH_ADDRESS } from '@e2e/common'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { IKeep3r, IUniswapV3Pool, Keep3rHelperSidechain, Keep3rHelperSidechain__factory } from '@types'; import { bn, evm, wallet } from '@utils'; -import { onlyGovernance } from '@utils/behaviours'; +import { onlyGovernor } from '@utils/behaviours'; import { ZERO_ADDRESS } from '@utils/constants'; import chai, { expect } from 'chai'; import { ethers } from 'hardhat'; @@ -13,7 +13,7 @@ chai.use(smock.matchers); const DAY = 86400; describe('Keep3rHelperSidechain', () => { - let governance: SignerWithAddress; + let governor: SignerWithAddress; let helper: MockContract; let keep3rHelperSidechainFactory: MockContractFactory; let keep3r: FakeContract; @@ -23,7 +23,7 @@ describe('Keep3rHelperSidechain', () => { let snapshotId: string; before(async () => { - [, governance] = await ethers.getSigners(); + [, governor] = await ethers.getSigners(); keep3r = await smock.fake('IKeep3r'); kp3rWethOracle = await smock.fake('IUniswapV3Pool'); wethUsdOracle = await smock.fake('IUniswapV3Pool'); @@ -40,7 +40,7 @@ describe('Keep3rHelperSidechain', () => { keep3rHelperSidechainFactory = await smock.mock('Keep3rHelperSidechain'); helper = await keep3rHelperSidechainFactory.deploy( keep3r.address, - governance.address, + governor.address, KP3R_V1_ADDRESS, WETH_ADDRESS, kp3rWethOracle.address, @@ -59,8 +59,8 @@ describe('Keep3rHelperSidechain', () => { expect(await helper.keep3rV2()).to.eq(keep3r.address); }); - it('should initialize governance to the address passed to the constructor', async () => { - expect(await helper.governance()).to.eq(governance.address); + it('should initialize governor to the address passed to the constructor', async () => { + expect(await helper.governor()).to.eq(governor.address); }); it('should initialize kp3rWethOracle to the address passed to the constructor', async () => { @@ -74,7 +74,7 @@ describe('Keep3rHelperSidechain', () => { const deployed = await keep3rHelperSidechainFactory.deploy( keep3r.address, - governance.address, + governor.address, KP3R_V1_ADDRESS, WETH_ADDRESS, kp3rWethOracle.address, @@ -96,7 +96,7 @@ describe('Keep3rHelperSidechain', () => { const deployed = await keep3rHelperSidechainFactory.deploy( keep3r.address, - governance.address, + governor.address, KP3R_V1_ADDRESS, WETH_ADDRESS, kp3rWethOracle.address, @@ -142,26 +142,26 @@ describe('Keep3rHelperSidechain', () => { }); describe('setOracle', () => { - onlyGovernance( + onlyGovernor( () => helper, 'setOracle', - () => governance, + () => governor, [wallet.generateRandomAddress(), wallet.generateRandomAddress()] ); it('should revert if any address is 0', async () => { const randomAddress = wallet.generateRandomAddress(); - await expect(helper.connect(governance).setOracle(randomAddress, ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); - await expect(helper.connect(governance).setOracle(ZERO_ADDRESS, randomAddress)).to.be.revertedWith('ZeroAddress()'); - await expect(helper.connect(governance).setOracle(ZERO_ADDRESS, ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); + await expect(helper.connect(governor).setOracle(randomAddress, ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); + await expect(helper.connect(governor).setOracle(ZERO_ADDRESS, randomAddress)).to.be.revertedWith('ZeroAddress()'); + await expect(helper.connect(governor).setOracle(ZERO_ADDRESS, ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); }); it('should store oracle address for given liquidity', async () => { const liquidity = wallet.generateRandomAddress(); const oracle = wallet.generateRandomAddress(); - await helper.connect(governance).setOracle(liquidity, oracle); + await helper.connect(governor).setOracle(liquidity, oracle); expect(await helper.oracle(liquidity)).to.eq(oracle); }); @@ -184,20 +184,20 @@ describe('Keep3rHelperSidechain', () => { }); context('setWethUsdPool', () => { - onlyGovernance( + onlyGovernor( () => helper, 'setWethUsdPool', - governance, + governor, () => [otherPool.address] ); it('should revert if pool address is 0', async () => { - await expect(helper.connect(governance).setWethUsdPool(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); + await expect(helper.connect(governor).setWethUsdPool(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); }); it('should set wethUSDPool isTKNToken0 to true if WETH is token0', async () => { otherPool.token0.returns(WETH_ADDRESS); - await helper.connect(governance).setWethUsdPool(otherPool.address); + await helper.connect(governor).setWethUsdPool(otherPool.address); const isTKNToken0 = (await helper.callStatic.wethUSDPool()).isTKNToken0; expect(isTKNToken0).to.be.true; }); @@ -206,7 +206,7 @@ describe('Keep3rHelperSidechain', () => { otherPool.token0.returns(wallet.generateRandomAddress()); otherPool.token1.returns(WETH_ADDRESS); - await helper.connect(governance).setWethUsdPool(otherPool.address); + await helper.connect(governor).setWethUsdPool(otherPool.address); const isTKNToken0 = (await helper.callStatic.wethUSDPool()).isTKNToken0; expect(isTKNToken0).to.be.false; }); @@ -215,12 +215,12 @@ describe('Keep3rHelperSidechain', () => { otherPool.token0.returns(wallet.generateRandomAddress()); otherPool.token1.returns(wallet.generateRandomAddress()); - await expect(helper.connect(governance).setWethUsdPool(otherPool.address)).to.be.revertedWith('InvalidOraclePool()'); + await expect(helper.connect(governor).setWethUsdPool(otherPool.address)).to.be.revertedWith('InvalidOraclePool()'); }); it('should emit event', async () => { otherPool.token0.returns(WETH_ADDRESS); - await expect(helper.connect(governance).setWethUsdPool(otherPool.address)) + await expect(helper.connect(governor).setWethUsdPool(otherPool.address)) .to.emit(helper, 'WethUSDPoolChange') .withArgs(otherPool.address, true); }); diff --git a/test/unit/sidechain/Keep3rSidechain.spec.ts b/test/unit/sidechain/Keep3rSidechain.spec.ts index d9efdb6..3218be9 100644 --- a/test/unit/sidechain/Keep3rSidechain.spec.ts +++ b/test/unit/sidechain/Keep3rSidechain.spec.ts @@ -9,8 +9,9 @@ import { Keep3rSidechainForTest, Keep3rSidechainForTest__factory, } from '@types'; -import { bn, constants, contracts, evm, wallet } from '@utils'; -import { onlyGovernance } from '@utils/behaviours'; +import { bn, contracts, evm, wallet } from '@utils'; +import { onlyGovernor } from '@utils/behaviours'; +import { ZERO_ADDRESS } from '@utils/constants'; import { readArgFromEvent, readArgsFromEvent } from '@utils/event-utils'; import { MathUtils, mathUtilsFactory } from '@utils/math'; import chai, { expect } from 'chai'; @@ -20,7 +21,7 @@ import { ethers } from 'hardhat'; chai.use(smock.matchers); describe('Keep3rSidechain', () => { - let governance: SignerWithAddress; + let governor: SignerWithAddress; let randomKeeper: SignerWithAddress; let keep3r: MockContract; let keep3rFactory: MockContractFactory; @@ -39,7 +40,7 @@ describe('Keep3rSidechain', () => { const DAY = 86400; before(async () => { - [, governance, randomKeeper] = await ethers.getSigners(); + [, governor, randomKeeper] = await ethers.getSigners(); keep3rFactory = await smock.mock('Keep3rSidechainForTest'); helper = await smock.fake('Keep3rHelperSidechain'); @@ -55,7 +56,7 @@ describe('Keep3rSidechain', () => { }); beforeEach(async () => { - keep3r = await keep3rFactory.deploy(governance.address, helper.address, wKP3R.address, escrow.address); + keep3r = await keep3rFactory.deploy(governor.address, helper.address, wKP3R.address, escrow.address); rewardPeriodTime = (await keep3r.rewardPeriodTime()).toNumber(); const inflationPeriodTime = (await keep3r.inflationPeriod()).toNumber(); @@ -72,60 +73,60 @@ describe('Keep3rSidechain', () => { helper.oracle.returns(oraclePool); }); - onlyGovernance( + onlyGovernor( () => keep3r, 'approveLiquidity', - () => governance, + () => governor, [liquidity] ); it('should add the liquidity to approved liquidities list', async () => { - await keep3r.connect(governance).approveLiquidity(liquidity); + await keep3r.connect(governor).approveLiquidity(liquidity); expect(await keep3r.approvedLiquidities()).to.contain(liquidity); }); it('should revert when liquidity already approved', async () => { - await keep3r.connect(governance).approveLiquidity(liquidity); - await expect(keep3r.connect(governance).approveLiquidity(liquidity)).to.be.revertedWith('LiquidityPairApproved()'); + await keep3r.connect(governor).approveLiquidity(liquidity); + await expect(keep3r.connect(governor).approveLiquidity(liquidity)).to.be.revertedWith('LiquidityPairApproved()'); }); it('should query keep3r helper for the correspondant oracle pool', async () => { - await keep3r.connect(governance).approveLiquidity(liquidity); + await keep3r.connect(governor).approveLiquidity(liquidity); expect(helper.oracle).to.have.been.calledOnceWith(liquidity); }); it('should revert if helper has no oracle for liquidity', async () => { - helper.oracle.returns(constants.ZERO_ADDRESS); - await expect(keep3r.connect(governance).approveLiquidity(liquidity)).to.be.revertedWith('ZeroAddress'); + helper.oracle.returns(ZERO_ADDRESS); + await expect(keep3r.connect(governor).approveLiquidity(liquidity)).to.be.revertedWith('ZeroAddress'); }); it('should store the correspondant oracle pool', async () => { - await keep3r.connect(governance).approveLiquidity(liquidity); + await keep3r.connect(governor).approveLiquidity(liquidity); expect(await keep3r.getVariable('_liquidityPool', [liquidity])).to.eq(oraclePool); }); it('should query keep3r helper for the token order', async () => { - await keep3r.connect(governance).approveLiquidity(liquidity); + await keep3r.connect(governor).approveLiquidity(liquidity); expect(helper.isKP3RToken0).to.have.been.calledOnceWith(oraclePool); }); it('should sort the tokens in the liquidity pair', async () => { helper.isKP3RToken0.returns(true); - await keep3r.connect(governance).approveLiquidity(liquidity); + await keep3r.connect(governor).approveLiquidity(liquidity); expect(await keep3r.getVariable('_isKP3RToken0', [liquidity])).to.eq(true); }); it('should initialize twap for liquidity', async () => { - await keep3r.connect(governance).approveLiquidity(liquidity); + await keep3r.connect(governor).approveLiquidity(liquidity); expect(helper.observe).to.have.been.called; }); it('should emit event', async () => { - await expect(keep3r.connect(governance).approveLiquidity(liquidity)).to.emit(keep3r, 'LiquidityApproval').withArgs(liquidity); + await expect(keep3r.connect(governor).approveLiquidity(liquidity)).to.emit(keep3r, 'LiquidityApproval').withArgs(liquidity); }); }); @@ -232,7 +233,7 @@ describe('Keep3rSidechain', () => { blockTimestamp = (await ethers.provider.getBlock('latest')).timestamp; helper.oracle.whenCalledWith(liquidity).returns(oraclePool.address); - await keep3r.connect(governance).approveLiquidity(liquidity); + await keep3r.connect(governor).approveLiquidity(liquidity); await keep3r.setVariables({ _isKP3RToken0: { [oraclePool.address]: true }, diff --git a/test/utils/behaviours.ts b/test/utils/behaviours.ts index fb9dcb8..528f006 100644 --- a/test/utils/behaviours.ts +++ b/test/utils/behaviours.ts @@ -9,8 +9,8 @@ chai.use(smock.matchers); export type Impersonator = Signer | Provider | string; -export const onlyGovernance = createOnlyCallableCheck(['governance'], 'OnlyGovernance()'); -export const onlyPendingGovernance = createOnlyCallableCheck(['pending governance'], 'OnlyPendingGovernance()'); +export const onlyGovernor = createOnlyCallableCheck(['governor'], 'OnlyGovernor()'); +export const onlyPendingGovernor = createOnlyCallableCheck(['pending governor'], 'OnlyPendingGovernor()'); export const onlyJobOwner = createOnlyCallableCheck(['job owner'], 'OnlyJobOwner()'); export const onlyDisputer = createOnlyCallableCheck(['disputer'], 'OnlyDisputer()'); export const onlySlasher = createOnlyCallableCheck(['slasher'], 'OnlySlasher()'); diff --git a/yarn.lock b/yarn.lock index 4099536..2dcfea1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -172,6 +172,15 @@ rxjs "^7.2.0" semver "^7.3.5" +"@defi-wonderland/solidity-utils@0.0.0-6c86c0fc": + version "0.0.0-6c86c0fc" + resolved "https://registry.yarnpkg.com/@defi-wonderland/solidity-utils/-/solidity-utils-0.0.0-6c86c0fc.tgz#36da2deab6e181299c4ec328a0719d044142cab3" + integrity sha512-JVRPMw06UiK0LRMi5wuIH9bkx33+3DSIUdN4QHhlqqGQa9rm9r6H/yVBWDOchACiJIfaShfLZZA0gAnL8tkkvA== + dependencies: + "@openzeppelin/contracts" "4.8.1" + ds-test "https://github.com/dapphub/ds-test" + forge-std "https://github.com/foundry-rs/forge-std" + "@ensdomains/ens@^0.4.4": version "0.4.5" resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" @@ -1240,6 +1249,11 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.3.0.tgz#345236d4ec73ef381ab4907c6ef66fd55e5dedad" integrity sha512-+uBDl/TrmR0Kch6mq3tuxMex/fK7huR6+fQMae+zJk1K5T+dp0pFl12Hbc+1L6oYMXoyDSBJ8zqhRIntrREDFA== +"@openzeppelin/contracts@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.1.tgz#709cfc4bbb3ca9f4460d60101f15dac6b7a2d5e4" + integrity sha512-xQ6eUZl+RDyb/FiZe1h+U7qr/f4p/SrTSQcTPH2bjur3C5DbuW/zFgCU/b1P/xcIaEqJep+9ju4xDRi3rmChdQ== + "@resolver-engine/core@^0.3.3": version "0.3.3" resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" @@ -3518,6 +3532,11 @@ commander@3.0.2: resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== +commander@^8.1.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + compare-func@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" @@ -4266,6 +4285,10 @@ drbg.js@^1.0.1: create-hash "^1.1.2" create-hmac "^1.1.4" +"ds-test@git+https://github.com/dapphub/ds-test.git": + version "1.0.0" + resolved "git+https://github.com/dapphub/ds-test.git#cd98eff28324bfac652e63a239a60632a761790b" + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" @@ -5497,6 +5520,10 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +"forge-std@git+https://github.com/foundry-rs/forge-std.git": + version "1.2.0" + resolved "git+https://github.com/foundry-rs/forge-std.git#4a79aca83f8075f8b1b4fe9153945fef08375630" + form-data@^2.2.0: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -10010,13 +10037,13 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -"solc-0.8@npm:solc@0.8.7-fixed": - version "0.8.7-fixed" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.7-fixed.tgz#76eb37d33637ad278ad858e2633e9da597d877ac" - integrity sha512-nWZRkdPwfBpimAelO30Bz7/hxoj+mylb30gEpBL8hhEWR4xqu2ezQAxWK1Hz5xx1NqesbgGjSgnGul49tRHWgQ== +"solc-0.8@npm:solc@0.8.8": + version "0.8.8" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.8.tgz#3902c496cc200fc83bf96ff42d798f3f41c9c489" + integrity sha512-u5N7fq4kABwyLKDbt9Xq99OiYBP7x56Pl/Oyz4TbNr9xbjgaMW2lhNIAZWtTme7Iuufw+3Tq5Ts3Bia56BOkvQ== dependencies: command-exists "^1.2.8" - commander "3.0.2" + commander "^8.1.0" follow-redirects "^1.12.1" fs-extra "^0.30.0" js-sha3 "0.8.0" From b18e2940310077e04ec08b3026dc92e441fb08ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wei=C3=9Fer=20Hase?= Date: Mon, 20 Feb 2023 11:55:12 -0300 Subject: [PATCH 3/4] feat: implemented decimals in usd oracle * test: implemented decimals in oracle struct * test: individual struct for usd oracle * fix: rm kp3r decimals * feat: added decimals to quote calculation * fix: unit tests * fix: fixture tests * fix: testnet fixture tests * fix: convention naming --------- Co-authored-by: 0xGorilla <84932007+0xGorilla@users.noreply.github.com> --- .../203_keep3r_helper_and_sidechain.ts | 4 +- .../301_keep3r_helper_and_sidechain.ts | 4 +- solidity/contracts/Keep3rHelper.sol | 2 +- solidity/contracts/Keep3rHelperParameters.sol | 19 +++---- .../sidechain/Keep3rHelperSidechain.sol | 29 +++++++--- .../interfaces/IKeep3rHelperParameters.sol | 8 +-- .../sidechain/IKeep3rHelperSidechain.sol | 28 +++++++-- test/e2e/common.ts | 1 + test/e2e/keep3r-multichain.spec.ts | 15 ++++- test/unit/Keep3rHelperParameters.spec.ts | 24 ++++---- .../sidechain/Keep3rHelperSidechain.spec.ts | 57 ++++++++++++------- utils/constants.ts | 5 ++ 12 files changed, 129 insertions(+), 67 deletions(-) diff --git a/deploy/2-sidechain/203_keep3r_helper_and_sidechain.ts b/deploy/2-sidechain/203_keep3r_helper_and_sidechain.ts index ce4686d..5c961c8 100644 --- a/deploy/2-sidechain/203_keep3r_helper_and_sidechain.ts +++ b/deploy/2-sidechain/203_keep3r_helper_and_sidechain.ts @@ -2,7 +2,7 @@ import { DeployFunction } from 'hardhat-deploy/types'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployer, governor, kp3rV1, weth, kp3rWethOracle, wethUsdOracle } = await hre.getNamedAccounts(); + const { deployer, governor, kp3rV1, weth, kp3rWethOracle, wethUsdOracle, usdDecimals } = await hre.getNamedAccounts(); const { kp3rV1: mainnetKp3rV1 } = await hre.companionNetworks['mainnet'].getNamedAccounts(); const keep3rEscrow = await hre.deployments.get('Keep3rEscrow'); @@ -11,7 +11,7 @@ const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnviro const currentNonce: number = await hre.ethers.provider.getTransactionCount(deployer); const keeperV2Address: string = hre.ethers.utils.getContractAddress({ from: deployer, nonce: currentNonce + 1 }); - const keep3rHelperArgs = [keeperV2Address, governor, mainnetKp3rV1, weth, kp3rWethOracle, wethUsdOracle]; + const keep3rHelperArgs = [keeperV2Address, governor, mainnetKp3rV1, weth, kp3rWethOracle, wethUsdOracle, usdDecimals]; const keep3rHelper = await hre.deployments.deploy('Keep3rHelperSidechain', { from: deployer, diff --git a/deploy/3-sidechain-test/301_keep3r_helper_and_sidechain.ts b/deploy/3-sidechain-test/301_keep3r_helper_and_sidechain.ts index ee1f0d9..c7288b0 100644 --- a/deploy/3-sidechain-test/301_keep3r_helper_and_sidechain.ts +++ b/deploy/3-sidechain-test/301_keep3r_helper_and_sidechain.ts @@ -2,7 +2,7 @@ import { DeployFunction } from 'hardhat-deploy/types'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployer, governor, kp3rV1, kp3rWethOracle, wethUsdOracle } = await hre.getNamedAccounts(); + const { deployer, governor, kp3rV1, kp3rWethOracle, wethUsdOracle, usdDecimals } = await hre.getNamedAccounts(); const { kp3rV1: mainnetKp3rV1, weth: mainnetWeth } = await hre.companionNetworks['mainnet'].getNamedAccounts(); const keep3rEscrow = await hre.deployments.get('Keep3rEscrow'); @@ -11,7 +11,7 @@ const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnviro const currentNonce: number = await hre.ethers.provider.getTransactionCount(deployer); const keeperV2Address: string = hre.ethers.utils.getContractAddress({ from: deployer, nonce: currentNonce + 1 }); - const keep3rHelperArgs = [keeperV2Address, governor, mainnetKp3rV1, mainnetWeth, kp3rWethOracle, wethUsdOracle]; + const keep3rHelperArgs = [keeperV2Address, governor, mainnetKp3rV1, mainnetWeth, kp3rWethOracle, wethUsdOracle, usdDecimals]; const keep3rHelper = await hre.deployments.deploy('Keep3rHelperSidechain', { from: deployer, diff --git a/solidity/contracts/Keep3rHelper.sol b/solidity/contracts/Keep3rHelper.sol index 5d6537e..0fb32e8 100644 --- a/solidity/contracts/Keep3rHelper.sol +++ b/solidity/contracts/Keep3rHelper.sol @@ -41,7 +41,7 @@ contract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters { (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos); int56 _difference = _tickCumulatives[0] - _tickCumulatives[1]; - _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime); + _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isKP3RToken0 ? _difference : -_difference, quoteTwapTime); } /// @inheritdoc IKeep3rHelper diff --git a/solidity/contracts/Keep3rHelperParameters.sol b/solidity/contracts/Keep3rHelperParameters.sol index 61c8c50..77d6531 100644 --- a/solidity/contracts/Keep3rHelperParameters.sol +++ b/solidity/contracts/Keep3rHelperParameters.sol @@ -45,7 +45,7 @@ contract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governa address public override keep3rV2; /// @inheritdoc IKeep3rHelperParameters - IKeep3rHelperParameters.TokenOraclePool public override kp3rWethPool; + IKeep3rHelperParameters.Kp3rWethOraclePool public override kp3rWethPool; constructor( address _kp3r, @@ -57,8 +57,9 @@ contract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governa keep3rV2 = _keep3rV2; // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool] - kp3rWethPool = _validateOraclePool(_kp3rWethPool, _kp3r); - emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0); + bool _isKP3RToken0 = _validateOraclePool(_kp3rWethPool, KP3R); + kp3rWethPool = Kp3rWethOraclePool(_kp3rWethPool, _isKP3RToken0); + emit Kp3rWethPoolChange(_kp3rWethPool, _isKP3RToken0); } /// @inheritdoc IKeep3rHelperParameters @@ -123,15 +124,13 @@ contract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governa /// @notice Sets KP3R-WETH pool /// @param _poolAddress The address of the KP3R-WETH pool function _setKp3rWethPool(address _poolAddress) internal { - kp3rWethPool = _validateOraclePool(_poolAddress, KP3R); - emit Kp3rWethPoolChange(kp3rWethPool.poolAddress, kp3rWethPool.isTKNToken0); + bool _isKP3RToken0 = _validateOraclePool(_poolAddress, KP3R); + kp3rWethPool = Kp3rWethOraclePool(_poolAddress, _isKP3RToken0); + emit Kp3rWethPoolChange(_poolAddress, _isKP3RToken0); } - function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (TokenOraclePool memory _oraclePool) { - bool _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token; - + function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (bool _isTKNToken0) { + _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token; if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool(); - - return TokenOraclePool(_poolAddress, _isTKNToken0); } } diff --git a/solidity/contracts/sidechain/Keep3rHelperSidechain.sol b/solidity/contracts/sidechain/Keep3rHelperSidechain.sol index d420313..c60bf03 100644 --- a/solidity/contracts/sidechain/Keep3rHelperSidechain.sol +++ b/solidity/contracts/sidechain/Keep3rHelperSidechain.sol @@ -26,11 +26,14 @@ contract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper { /// @inheritdoc IKeep3rHelperSidechain mapping(address => address) public override oracle; /// @inheritdoc IKeep3rHelperSidechain - IKeep3rHelperParameters.TokenOraclePool public override wethUSDPool; + IKeep3rHelperSidechain.WethUsdOraclePool public override wethUSDPool; /// @notice Ethereum mainnet WETH address used for quoting references address public immutable override WETH; + /// @dev Amount of decimals in which USD is quoted within the contract + uint256 constant _USD_BASE_DECIMALS = 18; + /// @param _keep3rV2 Address of sidechain Keep3r implementation /// @param _governor Address of governor /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote @@ -42,10 +45,16 @@ contract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper { address _kp3r, address _weth, address _kp3rWethOracle, - address _wethUsdOracle + address _wethUsdOracle, + uint8 _usdDecimals ) Keep3rHelper(_kp3r, _keep3rV2, _governor, _kp3rWethOracle) { WETH = _weth; - wethUSDPool = _validateOraclePool(_wethUsdOracle, _weth); + + // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool] + bool _isWETHToken0 = _validateOraclePool(_wethUsdOracle, WETH); + wethUSDPool = WethUsdOraclePool(_wethUsdOracle, _isWETHToken0, _usdDecimals); + emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isWETHToken0, _usdDecimals); + _setQuoteTwapTime(1 days); workExtraGas = 0; } @@ -68,17 +77,18 @@ contract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper { function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) { uint32[] memory _secondsAgos = new uint32[](2); _secondsAgos[1] = quoteTwapTime; + _usd = _usd / 10**(_USD_BASE_DECIMALS - wethUSDPool.usdDecimals); /// @dev Oracle is compatible with IUniswapV3Pool (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos); int56 _difference = _tickCumulatives[0] - _tickCumulatives[1]; - _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isTKNToken0 ? _difference : -_difference, quoteTwapTime); + _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isWETHToken0 ? _difference : -_difference, quoteTwapTime); } /// @inheritdoc IKeep3rHelperSidechain - function setWethUsdPool(address _poolAddress) external override onlyGovernor { + function setWethUsdPool(address _poolAddress, uint8 _usdDecimals) external override onlyGovernor { if (_poolAddress == address(0)) revert ZeroAddress(); - _setWethUsdPool(_poolAddress); + _setWethUsdPool(_poolAddress, _usdDecimals); } /// @inheritdoc IKeep3rHelper @@ -98,9 +108,10 @@ contract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper { _extraGas = workExtraGas; } - function _setWethUsdPool(address _poolAddress) internal { - wethUSDPool = _validateOraclePool(_poolAddress, WETH); - emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isTKNToken0); + function _setWethUsdPool(address _poolAddress, uint8 _usdDecimals) internal { + bool _isWETHToken0 = _validateOraclePool(_poolAddress, WETH); + wethUSDPool = WethUsdOraclePool(_poolAddress, _isWETHToken0, _usdDecimals); + emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isWETHToken0, _usdDecimals); } /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1 diff --git a/solidity/interfaces/IKeep3rHelperParameters.sol b/solidity/interfaces/IKeep3rHelperParameters.sol index 12ce7bc..eb07478 100644 --- a/solidity/interfaces/IKeep3rHelperParameters.sol +++ b/solidity/interfaces/IKeep3rHelperParameters.sol @@ -8,9 +8,9 @@ interface IKeep3rHelperParameters { /// @dev KP3R-WETH Pool address and isKP3RToken0 /// @dev Created in order to save gas by avoiding calls to pool's token0 method - struct TokenOraclePool { + struct Kp3rWethOraclePool { address poolAddress; - bool isTKNToken0; + bool isKP3RToken0; } // Errors @@ -70,8 +70,8 @@ interface IKeep3rHelperParameters { /// @notice KP3R-WETH pool that is being used as oracle /// @return poolAddress Address of the pool - /// @return isTKNToken0 True if calling the token0 method of the pool returns the KP3R token address - function kp3rWethPool() external view returns (address poolAddress, bool isTKNToken0); + /// @return isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address + function kp3rWethPool() external view returns (address poolAddress, bool isKP3RToken0); /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE diff --git a/solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol b/solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol index 152ec64..2f77f04 100644 --- a/solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol +++ b/solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol @@ -6,6 +6,16 @@ import '../IKeep3rHelper.sol'; /// @title Keep3rHelperSidechain contract /// @notice Contains all the helper functions for sidechain keep3r implementations interface IKeep3rHelperSidechain is IKeep3rHelper { + // Structs + + /// @dev WETH-USD Pool address, isWETHToken0 and usdDecimals + /// @dev Created in order to quote any kind of USD tokens + struct WethUsdOraclePool { + address poolAddress; + bool isWETHToken0; + uint8 usdDecimals; + } + // Events /// @notice The oracle for a liquidity has been saved @@ -16,7 +26,8 @@ interface IKeep3rHelperSidechain is IKeep3rHelper { /// @notice Emitted when the WETH USD pool is changed /// @param _address Address of the new WETH USD pool /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address - event WethUSDPoolChange(address _address, bool _isWETHToken0); + /// @param _usdDecimals The amount of decimals of the USD token paired with ETH + event WethUSDPoolChange(address _address, bool _isWETHToken0, uint8 _usdDecimals); /// Variables @@ -30,8 +41,16 @@ interface IKeep3rHelperSidechain is IKeep3rHelper { /// @notice WETH-USD pool that is being used as oracle /// @return poolAddress Address of the pool - /// @return isTKNToken0 True if calling the token0 method of the pool returns the WETH token address - function wethUSDPool() external view returns (address poolAddress, bool isTKNToken0); + /// @return isWETHToken0 True if calling the token0 method of the pool returns the WETH token address + /// @return usdDecimals The amount of decimals of the USD token paired with ETH + function wethUSDPool() + external + view + returns ( + address poolAddress, + bool isWETHToken0, + uint8 usdDecimals + ); /// @notice Quotes USD to ETH /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R @@ -49,6 +68,7 @@ interface IKeep3rHelperSidechain is IKeep3rHelper { /// @notice Sets an oracle for querying WETH/USD quote /// @param _poolAddress The address of the pool used as oracle + /// @param _usdDecimals The amount of decimals of the USD token paired with ETH /// @dev The oracle must contain WETH as either token0 or token1 - function setWethUsdPool(address _poolAddress) external; + function setWethUsdPool(address _poolAddress, uint8 _usdDecimals) external; } diff --git a/test/e2e/common.ts b/test/e2e/common.ts index a503603..7ec2b6e 100644 --- a/test/e2e/common.ts +++ b/test/e2e/common.ts @@ -33,6 +33,7 @@ export const RICH_KP3R_WETH_POOL_ADDRESS = '0x2269522ad48aeb971b25042471a44acc8c export const KP3R_WETH_POOL_ADDRESS = '0xaf988afF99d3d0cb870812C325C588D8D8CB7De8'; export const KP3R_WETH_V3_POOL_ADDRESS = '0x11B7a6bc0259ed6Cf9DB8F499988F9eCc7167bf5'; export const WETH_DAI_V3_POOL_ADDRESS = '0xc2e9f25be6257c210d7adf0d4cd6e3e881ba25f8'; +export const WETH_USDC_V3_POOL_ADDRESS = '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640'; export const UNISWAP_V2_ROUTER_02_ADDRESS = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D'; export const UNISWAP_V2_FACTORY_ADDRESS = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f'; export const KP3R_V1_ADDRESS = '0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44'; diff --git a/test/e2e/keep3r-multichain.spec.ts b/test/e2e/keep3r-multichain.spec.ts index f7ea8a6..3b5297c 100644 --- a/test/e2e/keep3r-multichain.spec.ts +++ b/test/e2e/keep3r-multichain.spec.ts @@ -21,7 +21,14 @@ import chai, { expect } from 'chai'; import { solidity } from 'ethereum-waffle'; import { BigNumber } from 'ethers'; import { ethers } from 'hardhat'; -import { KP3R_V1_ADDRESS, KP3R_WETH_V3_POOL_ADDRESS, PAIR_MANAGER_ADDRESS, WETH_ADDRESS, WETH_DAI_V3_POOL_ADDRESS } from './common'; +import { + KP3R_V1_ADDRESS, + KP3R_WETH_V3_POOL_ADDRESS, + PAIR_MANAGER_ADDRESS, + WETH_ADDRESS, + WETH_DAI_V3_POOL_ADDRESS, + WETH_USDC_V3_POOL_ADDRESS, +} from './common'; const kp3rWhaleAddress = '0xa0f75491720835b36edc92d06ddc468d201e9b73'; @@ -31,7 +38,7 @@ const DAY = 86400; const ONE = bn.toUnit(1); const BONDS = bn.toUnit(10); const ESCROW_AMOUNT = bn.toUnit(100); -const DELTA = bn.toUnit(0.001).toNumber(); +const DELTA = bn.toUnit(0.001).toNumber(); // in KP3Rs (18 decimals) describe('Keep3r Sidechain @skip-on-coverage', () => { let deployer: SignerWithAddress; @@ -94,7 +101,9 @@ describe('Keep3r Sidechain @skip-on-coverage', () => { KP3R_V1_ADDRESS, WETH_ADDRESS, KP3R_WETH_V3_POOL_ADDRESS, // uses KP3R-WETH pool as oracle - WETH_DAI_V3_POOL_ADDRESS // uses WETH-DAI pool as oracle + // helper uses WETH-USDC and test uses WETH-DAI to verify + WETH_USDC_V3_POOL_ADDRESS, // uses WETH-USDC pool as oracle + 6 // USDC has 6 decimals ); const kp3rSidechainFactory = (await ethers.getContractFactory('Keep3rSidechain')) as Keep3rSidechain__factory; diff --git a/test/unit/Keep3rHelperParameters.spec.ts b/test/unit/Keep3rHelperParameters.spec.ts index 375150a..e72517e 100644 --- a/test/unit/Keep3rHelperParameters.spec.ts +++ b/test/unit/Keep3rHelperParameters.spec.ts @@ -41,18 +41,18 @@ describe('Keep3rHelperParameters', () => { expect(assignedAddress).to.equal(pool.address); }); - it('should set kp3rWethPool isTKNToken0 to true if KP3R is token0', async () => { + it('should set kp3rWethPool isKP3RToken0 to true if KP3R is token0', async () => { parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, randomKeep3rV2Address, governor.address, pool.address); - const isTKNToken0 = (await parameters.callStatic.kp3rWethPool()).isTKNToken0; - expect(isTKNToken0).to.be.true; + const isKP3RToken0 = (await parameters.callStatic.kp3rWethPool()).isKP3RToken0; + expect(isKP3RToken0).to.be.true; }); - it('should set kp3rWethPool isTKNToken0 to false if KP3R is not token0', async () => { + it('should set kp3rWethPool isKP3RToken0 to false if KP3R is not token0', async () => { pool.token0.returns(generateRandomAddress()); pool.token1.returns(KP3R_V1_ADDRESS); parameters = await parametersFactory.deploy(KP3R_V1_ADDRESS, randomKeep3rV2Address, governor.address, pool.address); - const isTKNToken0 = (await parameters.callStatic.kp3rWethPool()).isTKNToken0; - expect(isTKNToken0).to.be.false; + const isKP3RToken0 = (await parameters.callStatic.kp3rWethPool()).isKP3RToken0; + expect(isKP3RToken0).to.be.false; }); }); @@ -79,19 +79,19 @@ describe('Keep3rHelperParameters', () => { await expect(parameters.connect(governor).setKp3rWethPool(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); }); - it('should set kp3rWethPool isTKNToken0 to true if KP3R is token0', async () => { + it('should set kp3rWethPool isKP3RToken0 to true if KP3R is token0', async () => { await parameters.connect(governor).setKp3rWethPool(otherPool.address); - const isTKNToken0 = (await parameters.callStatic.kp3rWethPool()).isTKNToken0; - expect(isTKNToken0).to.be.true; + const isKP3RToken0 = (await parameters.callStatic.kp3rWethPool()).isKP3RToken0; + expect(isKP3RToken0).to.be.true; }); - it('should set kp3rWethPool isTKNToken0 to false if KP3R is not token0', async () => { + it('should set kp3rWethPool isKP3RToken0 to false if KP3R is not token0', async () => { otherPool.token0.returns(generateRandomAddress()); otherPool.token1.returns(KP3R_V1_ADDRESS); await parameters.connect(governor).setKp3rWethPool(otherPool.address); - const isTKNToken0 = (await parameters.callStatic.kp3rWethPool()).isTKNToken0; - expect(isTKNToken0).to.be.false; + const isKP3RToken0 = (await parameters.callStatic.kp3rWethPool()).isKP3RToken0; + expect(isKP3RToken0).to.be.false; }); it('should revert if pool does not contain KP3R as token0 nor token1', async () => { diff --git a/test/unit/sidechain/Keep3rHelperSidechain.spec.ts b/test/unit/sidechain/Keep3rHelperSidechain.spec.ts index 226e414..2288acd 100644 --- a/test/unit/sidechain/Keep3rHelperSidechain.spec.ts +++ b/test/unit/sidechain/Keep3rHelperSidechain.spec.ts @@ -22,6 +22,8 @@ describe('Keep3rHelperSidechain', () => { let otherPool: FakeContract; let snapshotId: string; + const USD_POOL_DECIMALS = 18; + before(async () => { [, governor] = await ethers.getSigners(); keep3r = await smock.fake('IKeep3r'); @@ -44,7 +46,8 @@ describe('Keep3rHelperSidechain', () => { KP3R_V1_ADDRESS, WETH_ADDRESS, kp3rWethOracle.address, - wethUsdOracle.address + wethUsdOracle.address, + USD_POOL_DECIMALS ); snapshotId = await evm.snapshot.take(); @@ -66,7 +69,7 @@ describe('Keep3rHelperSidechain', () => { it('should initialize kp3rWethOracle to the address passed to the constructor', async () => { const kp3rWethPool = await helper.kp3rWethPool(); expect(kp3rWethPool.poolAddress).to.eq(kp3rWethOracle.address); - expect(kp3rWethPool.isTKNToken0).to.eq(false); + expect(kp3rWethPool.isKP3RToken0).to.eq(false); }); it('should initialize kp3rWethOracle with the correct token0', async () => { @@ -78,17 +81,19 @@ describe('Keep3rHelperSidechain', () => { KP3R_V1_ADDRESS, WETH_ADDRESS, kp3rWethOracle.address, - wethUsdOracle.address + wethUsdOracle.address, + 18 ); const kp3rWethPool = await deployed.kp3rWethPool(); - expect(kp3rWethPool.isTKNToken0).to.eq(true); + expect(kp3rWethPool.isKP3RToken0).to.eq(true); }); it('should initialize wethUsdOracle to the address passed to the constructor', async () => { const wethUSDPool = await helper.wethUSDPool(); expect(wethUSDPool.poolAddress).to.eq(wethUsdOracle.address); - expect(wethUSDPool.isTKNToken0).to.eq(false); + expect(wethUSDPool.isWETHToken0).to.eq(false); + expect(wethUSDPool.usdDecimals).to.eq(USD_POOL_DECIMALS); }); it('should initialize wethUsdOracle with the correct token0', async () => { @@ -100,11 +105,12 @@ describe('Keep3rHelperSidechain', () => { KP3R_V1_ADDRESS, WETH_ADDRESS, kp3rWethOracle.address, - wethUsdOracle.address + wethUsdOracle.address, + USD_POOL_DECIMALS ); const wethUSDPool = await deployed.wethUSDPool(); - expect(wethUSDPool.isTKNToken0).to.eq(true); + expect(wethUSDPool.isWETHToken0).to.eq(true); }); it('should initialize quote twap time to 1 day', async () => { @@ -184,45 +190,56 @@ describe('Keep3rHelperSidechain', () => { }); context('setWethUsdPool', () => { + const USD_POOL_DECIMALS = 6; onlyGovernor( () => helper, 'setWethUsdPool', governor, - () => [otherPool.address] + () => [otherPool.address, USD_POOL_DECIMALS] ); it('should revert if pool address is 0', async () => { - await expect(helper.connect(governor).setWethUsdPool(ZERO_ADDRESS)).to.be.revertedWith('ZeroAddress()'); + await expect(helper.connect(governor).setWethUsdPool(ZERO_ADDRESS, USD_POOL_DECIMALS)).to.be.revertedWith('ZeroAddress()'); }); - it('should set wethUSDPool isTKNToken0 to true if WETH is token0', async () => { + it('should set wethUSDPool isWETHToken0 to true if WETH is token0', async () => { otherPool.token0.returns(WETH_ADDRESS); - await helper.connect(governor).setWethUsdPool(otherPool.address); - const isTKNToken0 = (await helper.callStatic.wethUSDPool()).isTKNToken0; - expect(isTKNToken0).to.be.true; + await helper.connect(governor).setWethUsdPool(otherPool.address, USD_POOL_DECIMALS); + const isWETHToken0 = (await helper.callStatic.wethUSDPool()).isWETHToken0; + expect(isWETHToken0).to.be.true; }); - it('should set wethUSDPool isTKNToken0 to false if WETH is not token0', async () => { + it('should set wethUSDPool isWETHToken0 to false if WETH is not token0', async () => { otherPool.token0.returns(wallet.generateRandomAddress()); otherPool.token1.returns(WETH_ADDRESS); - await helper.connect(governor).setWethUsdPool(otherPool.address); - const isTKNToken0 = (await helper.callStatic.wethUSDPool()).isTKNToken0; - expect(isTKNToken0).to.be.false; + await helper.connect(governor).setWethUsdPool(otherPool.address, USD_POOL_DECIMALS); + const isWETHToken0 = (await helper.callStatic.wethUSDPool()).isWETHToken0; + expect(isWETHToken0).to.be.false; + }); + + it('should set wethUSDPool parameters', async () => { + otherPool.token0.returns(WETH_ADDRESS); + + await helper.connect(governor).setWethUsdPool(otherPool.address, USD_POOL_DECIMALS); + const wethUSDPool = await helper.callStatic.wethUSDPool(); + expect(wethUSDPool.poolAddress).to.eq(otherPool.address); + expect(wethUSDPool.isWETHToken0).to.be.true; + expect(wethUSDPool.usdDecimals).to.eq(USD_POOL_DECIMALS); }); it('should revert if pool does not contain KP3R as token0 nor token1', async () => { otherPool.token0.returns(wallet.generateRandomAddress()); otherPool.token1.returns(wallet.generateRandomAddress()); - await expect(helper.connect(governor).setWethUsdPool(otherPool.address)).to.be.revertedWith('InvalidOraclePool()'); + await expect(helper.connect(governor).setWethUsdPool(otherPool.address, USD_POOL_DECIMALS)).to.be.revertedWith('InvalidOraclePool()'); }); it('should emit event', async () => { otherPool.token0.returns(WETH_ADDRESS); - await expect(helper.connect(governor).setWethUsdPool(otherPool.address)) + await expect(helper.connect(governor).setWethUsdPool(otherPool.address, USD_POOL_DECIMALS)) .to.emit(helper, 'WethUSDPoolChange') - .withArgs(otherPool.address, true); + .withArgs(otherPool.address, true, USD_POOL_DECIMALS); }); }); }); diff --git a/utils/constants.ts b/utils/constants.ts index c5a2874..4fc178c 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -45,4 +45,9 @@ export const addressRegistry = { 420: '0x4ECFF2c532d47D7be3D957E4a332AB134cad1fd9', // SidechainOracle 31337: '0x60594a405d53811d3bc4766596efd80fd545a270', // UniV3Pool }, + usdDecimals: { + 10: '0x0000000000000000000000000000000000000012', // 18 + 420: '0x0000000000000000000000000000000000000012', // 18 + 31337: '0x0000000000000000000000000000000000000012', // 18 + }, }; From 510fb6d9fd78a43217a6d3da998478e7a1e7990c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wei=C3=9Fer=20Hase?= Date: Mon, 20 Feb 2023 13:54:39 -0300 Subject: [PATCH 4/4] feat: polygon deployment * feat: adding polygon addresses and settings * feat: polygon deployments * fix: env example * fix: added etherscan api key for polygon * fix: sidechain graffiti commit hash --- .env.example | 3 + deployments/polygon/.chainId | 1 + deployments/polygon/KP3Rv1.json | 189 + deployments/polygon/Keep3rEscrow.json | 598 +++ .../polygon/Keep3rHelperSidechain.json | 1668 +++++++ deployments/polygon/Keep3rSidechain.json | 4072 +++++++++++++++++ deployments/polygon/Kp3rWethOracle.json | 987 ++++ deployments/polygon/WethUsdOracle.json | 987 ++++ .../3a869c3b827b38468356d50761a61b47.json | 325 ++ hardhat.config.ts | 8 + solidity/contracts/sidechain/Keep3rEscrow.sol | 2 +- .../sidechain/Keep3rHelperSidechain.sol | 2 +- .../contracts/sidechain/Keep3rSidechain.sol | 2 +- utils/constants.ts | 13 +- 14 files changed, 8851 insertions(+), 6 deletions(-) create mode 100644 deployments/polygon/.chainId create mode 100644 deployments/polygon/KP3Rv1.json create mode 100644 deployments/polygon/Keep3rEscrow.json create mode 100644 deployments/polygon/Keep3rHelperSidechain.json create mode 100644 deployments/polygon/Keep3rSidechain.json create mode 100644 deployments/polygon/Kp3rWethOracle.json create mode 100644 deployments/polygon/WethUsdOracle.json create mode 100644 deployments/polygon/solcInputs/3a869c3b827b38468356d50761a61b47.json diff --git a/.env.example b/.env.example index 60cd5b7..b10d46b 100644 --- a/.env.example +++ b/.env.example @@ -5,12 +5,14 @@ ENCRYPTED_PRIVATE_KEY= # HTTPs providers MAINNET_HTTPS_URL= OPTIMISM_HTTPS_URL= +POLYGON_HTTPS_URL= GOERLI_HTTPS_URL= OP_GOERLI_HTTPS_URL= # Account's private keys MAINNET_PRIVATE_KEY= OPTIMISM_PRIVATE_KEY= +POLYGON_PRIVATE_KEY= GOERLI_PRIVATE_KEY= OP_GOERLI_PRIVATE_KEY= @@ -18,6 +20,7 @@ OP_GOERLI_PRIVATE_KEY= ETHERSCAN_API_KEY= ETHEREUM_ETHERSCAN_API_KEY= OPTIMISTIC_ETHERSCAN_API_KEY= +POLYGON_ETHERSCAN_API_KEY= GOERLI_ETHERSCAN_API_KEY= OP_GOERLI_ETHERSCAN_API_KEY= diff --git a/deployments/polygon/.chainId b/deployments/polygon/.chainId new file mode 100644 index 0000000..0973804 --- /dev/null +++ b/deployments/polygon/.chainId @@ -0,0 +1 @@ +137 \ No newline at end of file diff --git a/deployments/polygon/KP3Rv1.json b/deployments/polygon/KP3Rv1.json new file mode 100644 index 0000000..7e4c3a3 --- /dev/null +++ b/deployments/polygon/KP3Rv1.json @@ -0,0 +1,189 @@ +{ + "address": "0x4a2bE2075588BcE6A7E072574698a7DbbAc39b08", + "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" + } + ], + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/polygon/Keep3rEscrow.json b/deployments/polygon/Keep3rEscrow.json new file mode 100644 index 0000000..43cd380 --- /dev/null +++ b/deployments/polygon/Keep3rEscrow.json @@ -0,0 +1,598 @@ +{ + "address": "0xDBc6501645407CF4D3af383FbD5Bf7586b135d81", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "internalType": "address", + "name": "_wKP3R", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAddress", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "LengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyMinter", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "DustSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "MinterSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newGovernor", + "type": "address" + } + ], + "name": "PendingGovernorAccepted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_pendingGovernor", + "type": "address" + } + ], + "name": "PendingGovernorSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_wKP3R", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "wKP3RDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_wKP3R", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "wKP3RMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newWKP3R", + "type": "address" + } + ], + "name": "wKP3RSet", + "type": "event" + }, + { + "inputs": [], + "name": "ETH_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptPendingGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingGovernor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sendDust", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pendingGovernor", + "type": "address" + } + ], + "name": "setPendingGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_wKP3R", + "type": "address" + } + ], + "name": "setWKP3R", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "wKP3R", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x90beb78c831c2aabff3a4dc96ad0a219804d0343fdcac671156051a1eff2ab69", + "receipt": { + "to": null, + "from": "0xA825fc60eB4B1269F1dF0f6E574b953d2b5f7EFc", + "contractAddress": "0xDBc6501645407CF4D3af383FbD5Bf7586b135d81", + "transactionIndex": 41, + "gasUsed": "690309", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000040000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000020000000001000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000800000000100000", + "blockHash": "0x5f4d36200e4d49a83c1442bcc05b47f52bfa1b5a536d3639ba27604bbd104930", + "transactionHash": "0x90beb78c831c2aabff3a4dc96ad0a219804d0343fdcac671156051a1eff2ab69", + "logs": [ + { + "transactionIndex": 41, + "blockNumber": 39514678, + "transactionHash": "0x90beb78c831c2aabff3a4dc96ad0a219804d0343fdcac671156051a1eff2ab69", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000a825fc60eb4b1269f1df0f6e574b953d2b5f7efc", + "0x0000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0" + ], + "data": "0x000000000000000000000000000000000000000000000000005c14eb412fb8bf0000000000000000000000000000000000000000000000001bc16d674ec80000000000000000000000000000000000000000000000000742ab1d9f8eef2fa4810000000000000000000000000000000000000000000000001b65587c0d984741000000000000000000000000000000000000000000000742ab79b47a305f5d40", + "logIndex": 191, + "blockHash": "0x5f4d36200e4d49a83c1442bcc05b47f52bfa1b5a536d3639ba27604bbd104930" + } + ], + "blockNumber": 39514678, + "cumulativeGasUsed": "8581807", + "status": 1, + "byzantium": true + }, + "args": [ + "0x9A040a31bc38919D50FD740973dBB6F8fdee1426", + "0x4a2bE2075588BcE6A7E072574698a7DbbAc39b08" + ], + "numDeployments": 1, + "solcInputHash": "3a869c3b827b38468356d50761a61b47", + "metadata": "{\"compiler\":{\"version\":\"0.8.8+commit.dddeac2f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"DustSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_minter\",\"type\":\"address\"}],\"name\":\"MinterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"wKP3RDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"wKP3RMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newWKP3R\",\"type\":\"address\"}],\"name\":\"wKP3RSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ETH_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sendDust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_minter\",\"type\":\"address\"}],\"name\":\"setMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"setPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_wKP3R\",\"type\":\"address\"}],\"name\":\"setWKP3R\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wKP3R\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_governor\":\"Address of governor\",\"_wKP3R\":\"Address of wrapped KP3R implementation\"}},\"deposit(uint256)\":{\"params\":{\"_amount\":\"The amount of wKP3R to deposit\"}},\"mint(uint256)\":{\"params\":{\"_amount\":\"The amount of wKP3R to mint\"}},\"sendDust(address,uint256,address)\":{\"params\":{\"_amount\":\"The amont of the token that will be transferred\",\"_to\":\"The address that will receive the idle funds\",\"_token\":\"The token that will be transferred\"}},\"setMinter(address)\":{\"params\":{\"_minter\":\"The address set as the minter\"}},\"setPendingGovernor(address)\":{\"params\":{\"_pendingGovernor\":\"Address of the proposed new governor\"}},\"setWKP3R(address)\":{\"params\":{\"_wKP3R\":\"the wKP3R address\"}}},\"stateVariables\":{\"wKP3R\":{\"return\":\"_wKP3RAddress The address of wKP3R\",\"returns\":{\"_0\":\"_wKP3RAddress The address of wKP3R\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InsufficientBalance()\":[{\"notice\":\"Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\"}],\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"OnlyGovernor()\":[{\"notice\":\"Thrown if a non-governor user tries to call a OnlyGovernor function\"}],\"OnlyMinter()\":[{\"notice\":\"Throws if the caller of the function is not the minter\"}],\"OnlyPendingGovernor()\":[{\"notice\":\"Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"events\":{\"DustSent(address,uint256,address)\":{\"notice\":\"Emitted when dust is sent\"},\"MinterSet(address)\":{\"notice\":\"Emitted when governor sets a new minter\"},\"PendingGovernorAccepted(address)\":{\"notice\":\"Emitted when a new governor is set\"},\"PendingGovernorSet(address,address)\":{\"notice\":\"Emitted when a new pending governor is set\"},\"wKP3RDeposited(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rEscrow#deposit function is called\"},\"wKP3RMinted(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rEscrow#mint function is called\"},\"wKP3RSet(address)\":{\"notice\":\"Emitted when Keep3rEscrow#setWKP3R function is called\"}},\"kind\":\"user\",\"methods\":{\"acceptPendingGovernor()\":{\"notice\":\"Allows a proposed governor to accept the governance\"},\"deposit(uint256)\":{\"notice\":\"Deposits wKP3R into the contract\"},\"mint(uint256)\":{\"notice\":\"mints wKP3R to the recipient\"},\"minter()\":{\"notice\":\"Stores the minter address\"},\"sendDust(address,uint256,address)\":{\"notice\":\"Allows an authorized user to transfer the tokens or eth that may have been left in a contract\"},\"setMinter(address)\":{\"notice\":\"Sets a new address to be the minter\"},\"setPendingGovernor(address)\":{\"notice\":\"Allows a governor to propose a new governor\"},\"setWKP3R(address)\":{\"notice\":\"sets the wKP3R address\"},\"wKP3R()\":{\"notice\":\"Lists the address of the wKP3R contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/sidechain/Keep3rEscrow.sol\":\"Keep3rEscrow\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {Governable} from './Governable.sol';\\nimport {IDustCollector} from '../interfaces/IDustCollector.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\n/// @title DustCollector contract\\nabstract contract DustCollector is IDustCollector, Governable {\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IDustCollector\\n address public constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n /// @inheritdoc IDustCollector\\n function sendDust(address _token, uint256 _amount, address _to) external onlyGovernor {\\n if (_to == address(0)) revert ZeroAddress();\\n if (_token == ETH_ADDRESS) payable(_to).transfer(_amount);\\n else IERC20(_token).safeTransfer(_to, _amount);\\n emit DustSent(_token, _amount, _to);\\n }\\n}\\n\",\"keccak256\":\"0xcdd6d0715406facd602770cca9320eebdc2b7b23b0e0f9e1b7b576fbc0126b47\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '../interfaces/IGovernable.sol';\\n\\n/// @title Governable contract\\n/// @notice Manages the governor role\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public governor;\\n\\n /// @inheritdoc IGovernable\\n address public pendingGovernor;\\n\\n constructor(address _governor) {\\n if (_governor == address(0)) revert ZeroAddress();\\n governor = _governor;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\\n _setPendingGovernor(_pendingGovernor);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptPendingGovernor() external onlyPendingGovernor {\\n _acceptPendingGovernor();\\n }\\n\\n function _setPendingGovernor(address _pendingGovernor) internal {\\n if (_pendingGovernor == address(0)) revert ZeroAddress();\\n pendingGovernor = _pendingGovernor;\\n emit PendingGovernorSet(governor, _pendingGovernor);\\n }\\n\\n function _acceptPendingGovernor() internal {\\n governor = pendingGovernor;\\n delete pendingGovernor;\\n emit PendingGovernorAccepted(governor);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governor\\n modifier onlyGovernor() {\\n if (msg.sender != governor) revert OnlyGovernor();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernor\\n modifier onlyPendingGovernor() {\\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x3f11408cfcb015a99dc417e075c8ebc39b796fc2adc3e81b036487e4486881b3\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from './IGovernable.sol';\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title DustCollector interface\\ninterface IDustCollector is IBaseErrors, IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _ethAddress Address used to trigger a native token transfer\\n // solhint-disable-next-line func-name-mixedcase\\n function ETH_ADDRESS() external view returns (address _ethAddress);\\n\\n // EVENTS\\n\\n /// @notice Emitted when dust is sent\\n /// @param _to The address which wil received the funds\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n // FUNCTIONS\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amont of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(address _token, uint256 _amount, address _to) external;\\n}\\n\",\"keccak256\":\"0xbe22cc660bd6846093504989146038bd369f511325cef40cdc647fe7e04206b1\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Mintable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IMintable.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\\n\\nabstract contract Mintable is Governable, IMintable {\\n /// @inheritdoc IMintable\\n address public override minter;\\n\\n constructor(address _governor) Governable(_governor) {}\\n\\n /// @inheritdoc IMintable\\n function setMinter(address _minter) external override onlyGovernor {\\n if (_minter == address(0)) revert ZeroAddress();\\n minter = _minter;\\n emit MinterSet(_minter);\\n }\\n\\n /// @notice Functions with this modifier can only be called by the minter;\\n modifier onlyMinter() {\\n if (msg.sender != minter) revert OnlyMinter();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x6f70ca1b083865b02f0e44cc72c8c85ecab374724eda4544f3fb78555f070ea4\",\"license\":\"MIT\"},\"solidity/contracts/sidechain/Keep3rEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/Mintable.sol';\\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rEscrow\\n address public override wKP3R;\\n\\n /// @param _governor Address of governor\\n /// @param _wKP3R Address of wrapped KP3R implementation\\n constructor(address _governor, address _wKP3R) Mintable(_governor) {\\n wKP3R = _wKP3R;\\n }\\n\\n /// @inheritdoc IKeep3rEscrow\\n function deposit(uint256 _amount) external override {\\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rEscrow\\n function mint(uint256 _amount) external override onlyMinter {\\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rEscrow\\n function setWKP3R(address _wKP3R) external override onlyGovernor {\\n if (_wKP3R == address(0)) revert ZeroAddress();\\n wKP3R = _wKP3R;\\n emit wKP3RSet(wKP3R);\\n }\\n}\\n\",\"keccak256\":\"0xbcd3de76bc05c78f894d5e257340d9de7f64c61935535b010fb92da42f5887b0\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IMintable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\n\\n/// @title Mintable contract\\n/// @notice Manages the minter role\\ninterface IMintable is IBaseErrors, IGovernable {\\n // Events\\n\\n /// @notice Emitted when governor sets a new minter\\n /// @param _minter Address of the new minter\\n event MinterSet(address _minter);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not the minter\\n error OnlyMinter();\\n\\n // Variables\\n\\n /// @notice Stores the minter address\\n /// @return _minter The minter addresss\\n function minter() external view returns (address _minter);\\n\\n // Methods\\n\\n /// @notice Sets a new address to be the minter\\n /// @param _minter The address set as the minter\\n function setMinter(address _minter) external;\\n}\\n\",\"keccak256\":\"0x0048c141d747eb1b0e9391ac9e13c268f858f2fec939c597992742e7a5e71597\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\nimport '../peripherals/IMintable.sol';\\n\\n/// @title Keep3rEscrow contract\\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\\ninterface IKeep3rEscrow is IMintable {\\n /// @notice Emitted when Keep3rEscrow#deposit function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _sender The address that called the function\\n /// @param _amount The amount of wKP3R the user deposited\\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#mint function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _recipient The address that will received the newly minted wKP3R\\n /// @param _amount The amount of wKP3R minted to the recipient\\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\\n /// @param _newWKP3R The address of the wKP3R contract\\n event wKP3RSet(address _newWKP3R);\\n\\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\\n error InsufficientBalance();\\n\\n /// @notice Lists the address of the wKP3R contract\\n /// @return _wKP3RAddress The address of wKP3R\\n function wKP3R() external view returns (address _wKP3RAddress);\\n\\n /// @notice Deposits wKP3R into the contract\\n /// @param _amount The amount of wKP3R to deposit\\n function deposit(uint256 _amount) external;\\n\\n /// @notice mints wKP3R to the recipient\\n /// @param _amount The amount of wKP3R to mint\\n function mint(uint256 _amount) external;\\n\\n /// @notice sets the wKP3R address\\n /// @param _wKP3R the wKP3R address\\n function setWKP3R(address _wKP3R) external;\\n}\\n\",\"keccak256\":\"0xf4796dde1afba7f50805aeae92ac0a4848525aeca8355d9b1c6b36c15cca4322\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610b92380380610b9283398101604081905261002f916100ac565b81806001600160a01b0381166100585760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b039283166001600160a01b0319918216179091556003805494909216931692909217909155506100df9050565b80516001600160a01b03811681146100a757600080fd5b919050565b600080604083850312156100bf57600080fd5b6100c883610090565b91506100d660208401610090565b90509250929050565b610aa4806100ee6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063a734f06e11610071578063a734f06e1461013e578063b509ec4514610159578063b6b55f251461016c578063e3056a341461017f578063f235757f14610192578063fca3b5aa146101a557600080fd5b806307546172146100b95780630c340a24146100e857806313f6986d146100fb5780632131606414610105578063966abd0014610118578063a0712d681461012b575b600080fd5b6002546100cc906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b6000546100cc906001600160a01b031681565b6101036101b8565b005b610103610113366004610961565b6101ed565b61010361012636600461097c565b610294565b6101036101393660046109b8565b6103aa565b6100cc73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6003546100cc906001600160a01b031681565b61010361017a3660046109b8565b610435565b6001546100cc906001600160a01b031681565b6101036101a0366004610961565b610496565b6101036101b3366004610961565b6104cd565b6001546001600160a01b031633146101e357604051639ba0305d60e01b815260040160405180910390fd5b6101eb61056d565b565b6000546001600160a01b031633146102185760405163070545c960e51b815260040160405180910390fd5b6001600160a01b03811661023f5760405163d92e233d60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f8592ade84fad7cc1c020f9783980e05e1be8bf3c0b6b557f3f5d5b48b5147647906020015b60405180910390a150565b6000546001600160a01b031633146102bf5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0381166102e65760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610347576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610341573d6000803e3d6000fd5b5061035b565b61035b6001600160a01b03841682846105cb565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6002546001600160a01b031633146103d557604051639cdc2ed560e01b815260040160405180910390fd5b6003546103ec906001600160a01b031633836105cb565b600354604080516001600160a01b03909216825233602083015281018290527f5c5d429f40d64606e3af1c2373aa5f5b0846566f2bb3871dcccf094850ed4fc890606001610289565b60035461044d906001600160a01b0316333084610633565b600354604080516001600160a01b03909216825233602083015281018290527fb0c9218af42df0588074c7f30948dd6d1293a5ef42e7762e83d62c5daa7c9b8490606001610289565b6000546001600160a01b031633146104c15760405163070545c960e51b815260040160405180910390fd5b6104ca81610671565b50565b6000546001600160a01b031633146104f85760405163070545c960e51b815260040160405180910390fd5b6001600160a01b03811661051f5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f726b590ef91a8c76ad05bbe91a57ef84605276528f49cd47d787f558a4e755b690602001610289565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6040516001600160a01b03831660248201526044810182905261062e90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526106f4565b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261066b9085906323b872dd60e01b906084016105f7565b50505050565b6001600160a01b0381166106985760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec9101610289565b6000610749826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166107cb9092919063ffffffff16565b80519091501561062e578080602001905181019061076791906109d1565b61062e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60606107da84846000856107e4565b90505b9392505050565b6060824710156108455760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016107c2565b843b6108935760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107c2565b600080866001600160a01b031685876040516108af9190610a1f565b60006040518083038185875af1925050503d80600081146108ec576040519150601f19603f3d011682016040523d82523d6000602084013e6108f1565b606091505b509150915061090182828661090c565b979650505050505050565b6060831561091b5750816107dd565b82511561092b5782518084602001fd5b8160405162461bcd60e51b81526004016107c29190610a3b565b80356001600160a01b038116811461095c57600080fd5b919050565b60006020828403121561097357600080fd5b6107dd82610945565b60008060006060848603121561099157600080fd5b61099a84610945565b9250602084013591506109af60408501610945565b90509250925092565b6000602082840312156109ca57600080fd5b5035919050565b6000602082840312156109e357600080fd5b815180151581146107dd57600080fd5b60005b83811015610a0e5781810151838201526020016109f6565b8381111561066b5750506000910152565b60008251610a318184602087016109f3565b9190910192915050565b6020815260008251806020840152610a5a8160408501602087016109f3565b601f01601f1916919091016040019291505056fea2646970667358221220f434ab00043d895f70b777dbc3d2b90244ba2004f042a55d3494310dc78ef28564736f6c63430008080033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063a734f06e11610071578063a734f06e1461013e578063b509ec4514610159578063b6b55f251461016c578063e3056a341461017f578063f235757f14610192578063fca3b5aa146101a557600080fd5b806307546172146100b95780630c340a24146100e857806313f6986d146100fb5780632131606414610105578063966abd0014610118578063a0712d681461012b575b600080fd5b6002546100cc906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b6000546100cc906001600160a01b031681565b6101036101b8565b005b610103610113366004610961565b6101ed565b61010361012636600461097c565b610294565b6101036101393660046109b8565b6103aa565b6100cc73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6003546100cc906001600160a01b031681565b61010361017a3660046109b8565b610435565b6001546100cc906001600160a01b031681565b6101036101a0366004610961565b610496565b6101036101b3366004610961565b6104cd565b6001546001600160a01b031633146101e357604051639ba0305d60e01b815260040160405180910390fd5b6101eb61056d565b565b6000546001600160a01b031633146102185760405163070545c960e51b815260040160405180910390fd5b6001600160a01b03811661023f5760405163d92e233d60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f8592ade84fad7cc1c020f9783980e05e1be8bf3c0b6b557f3f5d5b48b5147647906020015b60405180910390a150565b6000546001600160a01b031633146102bf5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0381166102e65760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610347576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610341573d6000803e3d6000fd5b5061035b565b61035b6001600160a01b03841682846105cb565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6002546001600160a01b031633146103d557604051639cdc2ed560e01b815260040160405180910390fd5b6003546103ec906001600160a01b031633836105cb565b600354604080516001600160a01b03909216825233602083015281018290527f5c5d429f40d64606e3af1c2373aa5f5b0846566f2bb3871dcccf094850ed4fc890606001610289565b60035461044d906001600160a01b0316333084610633565b600354604080516001600160a01b03909216825233602083015281018290527fb0c9218af42df0588074c7f30948dd6d1293a5ef42e7762e83d62c5daa7c9b8490606001610289565b6000546001600160a01b031633146104c15760405163070545c960e51b815260040160405180910390fd5b6104ca81610671565b50565b6000546001600160a01b031633146104f85760405163070545c960e51b815260040160405180910390fd5b6001600160a01b03811661051f5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f726b590ef91a8c76ad05bbe91a57ef84605276528f49cd47d787f558a4e755b690602001610289565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6040516001600160a01b03831660248201526044810182905261062e90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526106f4565b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261066b9085906323b872dd60e01b906084016105f7565b50505050565b6001600160a01b0381166106985760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec9101610289565b6000610749826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166107cb9092919063ffffffff16565b80519091501561062e578080602001905181019061076791906109d1565b61062e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60606107da84846000856107e4565b90505b9392505050565b6060824710156108455760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016107c2565b843b6108935760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107c2565b600080866001600160a01b031685876040516108af9190610a1f565b60006040518083038185875af1925050503d80600081146108ec576040519150601f19603f3d011682016040523d82523d6000602084013e6108f1565b606091505b509150915061090182828661090c565b979650505050505050565b6060831561091b5750816107dd565b82511561092b5782518084602001fd5b8160405162461bcd60e51b81526004016107c29190610a3b565b80356001600160a01b038116811461095c57600080fd5b919050565b60006020828403121561097357600080fd5b6107dd82610945565b60008060006060848603121561099157600080fd5b61099a84610945565b9250602084013591506109af60408501610945565b90509250925092565b6000602082840312156109ca57600080fd5b5035919050565b6000602082840312156109e357600080fd5b815180151581146107dd57600080fd5b60005b83811015610a0e5781810151838201526020016109f6565b8381111561066b5750506000910152565b60008251610a318184602087016109f3565b9190910192915050565b6020815260008251806020840152610a5a8160408501602087016109f3565b601f01601f1916919091016040019291505056fea2646970667358221220f434ab00043d895f70b777dbc3d2b90244ba2004f042a55d3494310dc78ef28564736f6c63430008080033", + "devdoc": { + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_governor": "Address of governor", + "_wKP3R": "Address of wrapped KP3R implementation" + } + }, + "deposit(uint256)": { + "params": { + "_amount": "The amount of wKP3R to deposit" + } + }, + "mint(uint256)": { + "params": { + "_amount": "The amount of wKP3R to mint" + } + }, + "sendDust(address,uint256,address)": { + "params": { + "_amount": "The amont of the token that will be transferred", + "_to": "The address that will receive the idle funds", + "_token": "The token that will be transferred" + } + }, + "setMinter(address)": { + "params": { + "_minter": "The address set as the minter" + } + }, + "setPendingGovernor(address)": { + "params": { + "_pendingGovernor": "Address of the proposed new governor" + } + }, + "setWKP3R(address)": { + "params": { + "_wKP3R": "the wKP3R address" + } + } + }, + "stateVariables": { + "wKP3R": { + "return": "_wKP3RAddress The address of wKP3R", + "returns": { + "_0": "_wKP3RAddress The address of wKP3R" + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "InsufficientBalance()": [ + { + "notice": "Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance" + } + ], + "InvalidAddress()": [ + { + "notice": "Thrown if an address is invalid" + } + ], + "InvalidAmount()": [ + { + "notice": "Thrown if an amount is invalid" + } + ], + "LengthMismatch()": [ + { + "notice": "Thrown if the lengths of a set of lists mismatch" + } + ], + "OnlyGovernor()": [ + { + "notice": "Thrown if a non-governor user tries to call a OnlyGovernor function" + } + ], + "OnlyMinter()": [ + { + "notice": "Throws if the caller of the function is not the minter" + } + ], + "OnlyPendingGovernor()": [ + { + "notice": "Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function" + } + ], + "ZeroAddress()": [ + { + "notice": "Thrown if an address is the zero address" + } + ], + "ZeroAmount()": [ + { + "notice": "Thrown if an amount is zero" + } + ] + }, + "events": { + "DustSent(address,uint256,address)": { + "notice": "Emitted when dust is sent" + }, + "MinterSet(address)": { + "notice": "Emitted when governor sets a new minter" + }, + "PendingGovernorAccepted(address)": { + "notice": "Emitted when a new governor is set" + }, + "PendingGovernorSet(address,address)": { + "notice": "Emitted when a new pending governor is set" + }, + "wKP3RDeposited(address,address,uint256)": { + "notice": "Emitted when Keep3rEscrow#deposit function is called" + }, + "wKP3RMinted(address,address,uint256)": { + "notice": "Emitted when Keep3rEscrow#mint function is called" + }, + "wKP3RSet(address)": { + "notice": "Emitted when Keep3rEscrow#setWKP3R function is called" + } + }, + "kind": "user", + "methods": { + "acceptPendingGovernor()": { + "notice": "Allows a proposed governor to accept the governance" + }, + "deposit(uint256)": { + "notice": "Deposits wKP3R into the contract" + }, + "mint(uint256)": { + "notice": "mints wKP3R to the recipient" + }, + "minter()": { + "notice": "Stores the minter address" + }, + "sendDust(address,uint256,address)": { + "notice": "Allows an authorized user to transfer the tokens or eth that may have been left in a contract" + }, + "setMinter(address)": { + "notice": "Sets a new address to be the minter" + }, + "setPendingGovernor(address)": { + "notice": "Allows a governor to propose a new governor" + }, + "setWKP3R(address)": { + "notice": "sets the wKP3R address" + }, + "wKP3R()": { + "notice": "Lists the address of the wKP3R contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 82, + "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", + "label": "governor", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 85, + "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", + "label": "pendingGovernor", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 6322, + "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", + "label": "minter", + "offset": 0, + "slot": "2", + "type": "t_address" + }, + { + "astId": 9775, + "contract": "solidity/contracts/sidechain/Keep3rEscrow.sol:Keep3rEscrow", + "label": "wKP3R", + "offset": 0, + "slot": "3", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/Keep3rHelperSidechain.json b/deployments/polygon/Keep3rHelperSidechain.json new file mode 100644 index 0000000..7668c13 --- /dev/null +++ b/deployments/polygon/Keep3rHelperSidechain.json @@ -0,0 +1,1668 @@ +{ + "address": "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rV2", + "type": "address" + }, + { + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "internalType": "address", + "name": "_kp3r", + "type": "address" + }, + { + "internalType": "address", + "name": "_weth", + "type": "address" + }, + { + "internalType": "address", + "name": "_kp3rWethOracle", + "type": "address" + }, + { + "internalType": "address", + "name": "_wethUsdOracle", + "type": "address" + }, + { + "internalType": "uint8", + "name": "_usdDecimals", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidAddress", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidOraclePool", + "type": "error" + }, + { + "inputs": [], + "name": "LengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidityPairInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_keep3rV2", + "type": "address" + } + ], + "name": "Keep3rV2Change", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_isKP3RToken0", + "type": "bool" + } + ], + "name": "Kp3rWethPoolChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_maxBoost", + "type": "uint256" + } + ], + "name": "MaxBoostChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_minBaseFee", + "type": "uint256" + } + ], + "name": "MinBaseFeeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_minBoost", + "type": "uint256" + } + ], + "name": "MinBoostChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_minPriorityFee", + "type": "uint256" + } + ], + "name": "MinPriorityFeeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_oraclePool", + "type": "address" + } + ], + "name": "OracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newGovernor", + "type": "address" + } + ], + "name": "PendingGovernorAccepted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_pendingGovernor", + "type": "address" + } + ], + "name": "PendingGovernorSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "_quoteTwapTime", + "type": "uint32" + } + ], + "name": "QuoteTwapTimeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_targetBond", + "type": "uint256" + } + ], + "name": "TargetBondChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_isWETHToken0", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "_usdDecimals", + "type": "uint8" + } + ], + "name": "WethUSDPoolChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_workExtraGas", + "type": "uint256" + } + ], + "name": "WorkExtraGasChange", + "type": "event" + }, + { + "inputs": [], + "name": "BOOST_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "KP3R", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptPendingGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + } + ], + "name": "bonds", + "outputs": [ + { + "internalType": "uint256", + "name": "_amountBonded", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_liquidityAmount", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "_tickDifference", + "type": "int56" + }, + { + "internalType": "uint256", + "name": "_timeInterval", + "type": "uint256" + } + ], + "name": "getKP3RsAtTick", + "outputs": [ + { + "internalType": "uint256", + "name": "_kp3rAmount", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bonds", + "type": "uint256" + } + ], + "name": "getPaymentParams", + "outputs": [ + { + "internalType": "uint256", + "name": "_boost", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_oneUsdQuote", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_extraGas", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "getPoolTokens", + "outputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "_baseAmount", + "type": "uint128" + }, + { + "internalType": "int56", + "name": "_tickDifference", + "type": "int56" + }, + { + "internalType": "uint256", + "name": "_timeInterval", + "type": "uint256" + } + ], + "name": "getQuoteAtTick", + "outputs": [ + { + "internalType": "uint256", + "name": "_quoteAmount", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_gasUsed", + "type": "uint256" + } + ], + "name": "getRewardAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_gasUsed", + "type": "uint256" + } + ], + "name": "getRewardAmountFor", + "outputs": [ + { + "internalType": "uint256", + "name": "_kp3r", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bonds", + "type": "uint256" + } + ], + "name": "getRewardBoostFor", + "outputs": [ + { + "internalType": "uint256", + "name": "_rewardBoost", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "isKP3RToken0", + "outputs": [ + { + "internalType": "bool", + "name": "_isKP3RToken0", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keep3rV2", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "kp3rWethPool", + "outputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isKP3RToken0", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxBoost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minBaseFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minBoost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minPriorityFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "uint32[]", + "name": "_secondsAgo", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56", + "name": "_tickCumulative1", + "type": "int56" + }, + { + "internalType": "int56", + "name": "_tickCumulative2", + "type": "int56" + }, + { + "internalType": "bool", + "name": "_success", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "oracle", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingGovernor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eth", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "_amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "quoteTwapTime", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_usd", + "type": "uint256" + } + ], + "name": "quoteUsdToEth", + "outputs": [ + { + "internalType": "uint256", + "name": "_amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rV2", + "type": "address" + } + ], + "name": "setKeep3rV2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolAddress", + "type": "address" + } + ], + "name": "setKp3rWethPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxBoost", + "type": "uint256" + } + ], + "name": "setMaxBoost", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minBaseFee", + "type": "uint256" + } + ], + "name": "setMinBaseFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minBoost", + "type": "uint256" + } + ], + "name": "setMinBoost", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minPriorityFee", + "type": "uint256" + } + ], + "name": "setMinPriorityFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "address", + "name": "_oracle", + "type": "address" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pendingGovernor", + "type": "address" + } + ], + "name": "setPendingGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_quoteTwapTime", + "type": "uint32" + } + ], + "name": "setQuoteTwapTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_targetBond", + "type": "uint256" + } + ], + "name": "setTargetBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolAddress", + "type": "address" + }, + { + "internalType": "uint8", + "name": "_usdDecimals", + "type": "uint8" + } + ], + "name": "setWethUsdPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_workExtraGas", + "type": "uint256" + } + ], + "name": "setWorkExtraGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "targetBond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wethUSDPool", + "outputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWETHToken0", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "usdDecimals", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "workExtraGas", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xab6295d6b4ba0b0ef03005f3873b284bbffb70c25f24099f12c23c21824afc05", + "receipt": { + "to": null, + "from": "0xA825fc60eB4B1269F1dF0f6E574b953d2b5f7EFc", + "contractAddress": "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "transactionIndex": 56, + "gasUsed": "2281415", + "logsBloom": "0x00000000000000000000000000000000000000008000000000000000000000000000000080000000010000000000000000008000000040000000000000000000000000000000000000000000004000800000000000000000000100000000000000000000000000000000001000000000000000000000000080802000000000000040000000040000000000000000000000100000000000000000000000000800200000000000000000000000000000000000000000000000000000000000004000000000030000000001000000000000000000000000000000120000000000000000200000000000000000000000000000000000000008000800000000100000", + "blockHash": "0x6638d8001f33ed2f63e44d1927b00f346a2315b86b71b3c6e1b260e2d9f39a1e", + "transactionHash": "0xab6295d6b4ba0b0ef03005f3873b284bbffb70c25f24099f12c23c21824afc05", + "logs": [ + { + "transactionIndex": 56, + "blockNumber": 39514683, + "transactionHash": "0xab6295d6b4ba0b0ef03005f3873b284bbffb70c25f24099f12c23c21824afc05", + "address": "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "topics": [ + "0x554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf4108" + ], + "data": "0x0000000000000000000000006a060bf6579318c15138160ee1f1d225fcc9d4090000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 242, + "blockHash": "0x6638d8001f33ed2f63e44d1927b00f346a2315b86b71b3c6e1b260e2d9f39a1e" + }, + { + "transactionIndex": 56, + "blockNumber": 39514683, + "transactionHash": "0xab6295d6b4ba0b0ef03005f3873b284bbffb70c25f24099f12c23c21824afc05", + "address": "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "topics": [ + "0x10e6a379d12c209d558815459d599ade7bcc91d5270a7dfca948da52aef7df34" + ], + "data": "0x00000000000000000000000045dda9cb7c25131df268515131f647d726f5060800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006", + "logIndex": 243, + "blockHash": "0x6638d8001f33ed2f63e44d1927b00f346a2315b86b71b3c6e1b260e2d9f39a1e" + }, + { + "transactionIndex": 56, + "blockNumber": 39514683, + "transactionHash": "0xab6295d6b4ba0b0ef03005f3873b284bbffb70c25f24099f12c23c21824afc05", + "address": "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "topics": [ + "0xc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000015180", + "logIndex": 244, + "blockHash": "0x6638d8001f33ed2f63e44d1927b00f346a2315b86b71b3c6e1b260e2d9f39a1e" + }, + { + "transactionIndex": 56, + "blockNumber": 39514683, + "transactionHash": "0xab6295d6b4ba0b0ef03005f3873b284bbffb70c25f24099f12c23c21824afc05", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000a825fc60eb4b1269f1df0f6e574b953d2b5f7efc", + "0x0000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0" + ], + "data": "0x000000000000000000000000000000000000000000000000011d9c2de3ab08c10000000000000000000000000000000000000000000000001a3877f82f1fb1e7000000000000000000000000000000000000000000000742eee39105660e29f8000000000000000000000000000000000000000000000000191adbca4b74a926000000000000000000000000000000000000000000000742f0012d3349b932b9", + "logIndex": 245, + "blockHash": "0x6638d8001f33ed2f63e44d1927b00f346a2315b86b71b3c6e1b260e2d9f39a1e" + } + ], + "blockNumber": 39514683, + "cumulativeGasUsed": "14652622", + "status": 1, + "byzantium": true + }, + "args": [ + "0x745a50320B6eB8FF281f1664Fc6713991661B129", + "0x9A040a31bc38919D50FD740973dBB6F8fdee1426", + "0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44", + "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619", + "0x6A060BF6579318c15138160Ee1f1d225fcC9D409", + "0x45dDa9cb7c25131DF268515131f647d726f50608", + "0x0000000000000000000000000000000000000006" + ], + "numDeployments": 1, + "solcInputHash": "3a869c3b827b38468356d50761a61b47", + "metadata": "{\"compiler\":{\"version\":\"0.8.8+commit.dddeac2f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kp3r\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kp3rWethOracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_wethUsdOracle\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_usdDecimals\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidOraclePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"Keep3rV2Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isKP3RToken0\",\"type\":\"bool\"}],\"name\":\"Kp3rWethPoolChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"MaxBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"MinBaseFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"MinBoostChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"MinPriorityFeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_oraclePool\",\"type\":\"address\"}],\"name\":\"OracleSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"QuoteTwapTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"TargetBondChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_isWETHToken0\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"_usdDecimals\",\"type\":\"uint8\"}],\"name\":\"WethUSDPoolChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"WorkExtraGasChange\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BOOST_BASE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"KP3R\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WETH\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountBonded\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityAmount\",\"type\":\"uint256\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getKP3RsAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3rAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getPaymentParams\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_boost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_oneUsdQuote\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_extraGas\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"}],\"name\":\"getPoolTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token1\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_baseAmount\",\"type\":\"uint128\"},{\"internalType\":\"int56\",\"name\":\"_tickDifference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"_timeInterval\",\"type\":\"uint256\"}],\"name\":\"getQuoteAtTick\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_quoteAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_gasUsed\",\"type\":\"uint256\"}],\"name\":\"getRewardAmountFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_kp3r\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bonds\",\"type\":\"uint256\"}],\"name\":\"getRewardBoostFor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardBoost\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"}],\"name\":\"isKP3RToken0\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isKP3RToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV2\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"kp3rWethPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isKP3RToken0\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBaseFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minPriorityFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pool\",\"type\":\"address\"},{\"internalType\":\"uint32[]\",\"name\":\"_secondsAgo\",\"type\":\"uint32[]\"}],\"name\":\"observe\",\"outputs\":[{\"internalType\":\"int56\",\"name\":\"_tickCumulative1\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"_tickCumulative2\",\"type\":\"int56\"},{\"internalType\":\"bool\",\"name\":\"_success\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eth\",\"type\":\"uint256\"}],\"name\":\"quote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"quoteTwapTime\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_usd\",\"type\":\"uint256\"}],\"name\":\"quoteUsdToEth\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV2\",\"type\":\"address\"}],\"name\":\"setKeep3rV2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddress\",\"type\":\"address\"}],\"name\":\"setKp3rWethPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxBoost\",\"type\":\"uint256\"}],\"name\":\"setMaxBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBaseFee\",\"type\":\"uint256\"}],\"name\":\"setMinBaseFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minBoost\",\"type\":\"uint256\"}],\"name\":\"setMinBoost\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minPriorityFee\",\"type\":\"uint256\"}],\"name\":\"setMinPriorityFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"}],\"name\":\"setOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"setPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_quoteTwapTime\",\"type\":\"uint32\"}],\"name\":\"setQuoteTwapTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_targetBond\",\"type\":\"uint256\"}],\"name\":\"setTargetBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_usdDecimals\",\"type\":\"uint8\"}],\"name\":\"setWethUsdPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_workExtraGas\",\"type\":\"uint256\"}],\"name\":\"setWorkExtraGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetBond\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wethUSDPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isWETHToken0\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"usdDecimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"workExtraGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bonds(address)\":{\"params\":{\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_amountBonded\":\"The amount of KP3R the keeper has bonded\"}},\"constructor\":{\"details\":\"Oracle pools should use 18 decimals tokens\",\"params\":{\"_governor\":\"Address of governor\",\"_keep3rV2\":\"Address of sidechain Keep3r implementation\",\"_kp3rWethOracle\":\"Address of oracle used for KP3R/WETH quote\",\"_wethUsdOracle\":\"Address of oracle used for WETH/USD quote\"}},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"params\":{\"_liquidityAmount\":\"Amount of liquidity to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_kp3rAmount\":\"Amount of KP3R tokens underlying on the given liquidity\"}},\"getPaymentParams(uint256)\":{\"params\":{\"_bonds\":\"Amount of bonded KP3R owned by the keeper\"},\"returns\":{\"_boost\":\"Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\",\"_extraGas\":\"Amount of extra gas that should be added to the gas spent\",\"_oneUsdQuote\":\"Amount of KP3R tokens equivalent to 1 ETH\"}},\"getPoolTokens(address)\":{\"params\":{\"_pool\":\"Address of the correspondant pool\"},\"returns\":{\"_token0\":\"Address of the first token of the pair\",\"_token1\":\"Address of the second token of the pair\"}},\"getQuoteAtTick(uint128,int56,uint256)\":{\"params\":{\"_baseAmount\":\"Amount of token to be converted\",\"_tickDifference\":\"Tick value used to calculate the quote\",\"_timeInterval\":\"Time value used to calculate the quote\"},\"returns\":{\"_quoteAmount\":\"Amount of credits deserved for the baseAmount at the tick value\"}},\"getRewardAmount(uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\"},\"returns\":{\"_amount\":\"The amount of KP3R that should be awarded to tx.origin\"}},\"getRewardAmountFor(address,uint256)\":{\"params\":{\"_gasUsed\":\"The amount of gas used that will be rewarded\",\"_keeper\":\"The address of the keeper to check\"},\"returns\":{\"_kp3r\":\"The amount of KP3R that should be awarded to the keeper\"}},\"getRewardBoostFor(uint256)\":{\"details\":\"If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\",\"params\":{\"_bonds\":\"The amount of KP3R tokens bonded by the keeper\"},\"returns\":{\"_rewardBoost\":\"The reward boost that corresponds to the keeper\"}},\"isKP3RToken0(address)\":{\"params\":{\"_pool\":\"Address of the correspondant pool\"},\"returns\":{\"_isKP3RToken0\":\"Boolean indicating the order of the tokens in the pair\"}},\"observe(address,uint32[])\":{\"params\":{\"_pool\":\"Address of the pool to observe\",\"_secondsAgo\":\"Array with time references to observe\"},\"returns\":{\"_success\":\"Boolean indicating if the observe call was succesfull\",\"_tickCumulative1\":\"Cumulative sum of ticks until first time reference\",\"_tickCumulative2\":\"Cumulative sum of ticks until second time reference\"}},\"quote(uint256)\":{\"details\":\"This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\",\"params\":{\"_eth\":\"The amount of ETH\"},\"returns\":{\"_amountOut\":\"The amount of KP3R\"}},\"quoteUsdToEth(uint256)\":{\"details\":\"Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\",\"params\":{\"_usd\":\"The amount of USD to quote to ETH\"},\"returns\":{\"_amountOut\":\"The resulting amount of ETH after quoting the USD\"}},\"setKeep3rV2(address)\":{\"params\":{\"_keep3rV2\":\"The address of Keep3r V2\"}},\"setKp3rWethPool(address)\":{\"params\":{\"_poolAddress\":\"The address of the KP3R-WETH pool\"}},\"setMaxBoost(uint256)\":{\"params\":{\"_maxBoost\":\"The maximum boost multiplier\"}},\"setMinBaseFee(uint256)\":{\"params\":{\"_minBaseFee\":\"The minimum rewarded gas fee\"}},\"setMinBoost(uint256)\":{\"params\":{\"_minBoost\":\"The minimum boost multiplier\"}},\"setMinPriorityFee(uint256)\":{\"params\":{\"_minPriorityFee\":\"The minimum rewarded priority fee\"}},\"setOracle(address,address)\":{\"details\":\"The oracle must contain KP3R as either token0 or token1\",\"params\":{\"_liquidity\":\"The address of the liquidity\",\"_oracle\":\"The address of the pool used to quote the liquidity from\"}},\"setPendingGovernor(address)\":{\"params\":{\"_pendingGovernor\":\"Address of the proposed new governor\"}},\"setQuoteTwapTime(uint32)\":{\"params\":{\"_quoteTwapTime\":\"The twap time for quoting\"}},\"setTargetBond(uint256)\":{\"params\":{\"_targetBond\":\"The target bond amount\"}},\"setWethUsdPool(address,uint8)\":{\"details\":\"The oracle must contain WETH as either token0 or token1\",\"params\":{\"_poolAddress\":\"The address of the pool used as oracle\",\"_usdDecimals\":\"The amount of decimals of the USD token paired with ETH\"}},\"setWorkExtraGas(uint256)\":{\"params\":{\"_workExtraGas\":\"The work extra gas\"}}},\"stateVariables\":{\"_USD_BASE_DECIMALS\":{\"details\":\"Amount of decimals in which USD is quoted within the contract\"},\"oracle\":{\"return\":\"_oracle The address of the observable pool for given liquidity\",\"returns\":{\"_0\":\"_oracle The address of the observable pool for given liquidity\"}},\"wethUSDPool\":{\"returns\":{\"isWETHToken0\":\"True if calling the token0 method of the pool returns the WETH token address\",\"poolAddress\":\"Address of the pool\",\"usdDecimals\":\"The amount of decimals of the USD token paired with ETH\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"InvalidOraclePool()\":[{\"notice\":\"Throws when pool does not have KP3R as token0 nor token1\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"LiquidityPairInvalid()\":[{\"notice\":\"Throws when none of the tokens in the liquidity pair is KP3R\"}],\"OnlyGovernor()\":[{\"notice\":\"Thrown if a non-governor user tries to call a OnlyGovernor function\"}],\"OnlyPendingGovernor()\":[{\"notice\":\"Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"events\":{\"Keep3rV2Change(address)\":{\"notice\":\"Emitted when the Keep3r V2 address is changed\"},\"Kp3rWethPoolChange(address,bool)\":{\"notice\":\"Emitted when the kp3r weth pool is changed\"},\"MaxBoostChange(uint256)\":{\"notice\":\"Emitted when the maximum boost multiplier is changed\"},\"MinBaseFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded gas fee is changed\"},\"MinBoostChange(uint256)\":{\"notice\":\"Emitted when the minimum boost multiplier is changed\"},\"MinPriorityFeeChange(uint256)\":{\"notice\":\"Emitted when minimum rewarded priority fee is changed\"},\"OracleSet(address,address)\":{\"notice\":\"The oracle for a liquidity has been saved\"},\"PendingGovernorAccepted(address)\":{\"notice\":\"Emitted when a new governor is set\"},\"PendingGovernorSet(address,address)\":{\"notice\":\"Emitted when a new pending governor is set\"},\"QuoteTwapTimeChange(uint32)\":{\"notice\":\"Emitted when the quote twap time is changed\"},\"TargetBondChange(uint256)\":{\"notice\":\"Emitted when the target bond amount is changed\"},\"WethUSDPoolChange(address,bool,uint8)\":{\"notice\":\"Emitted when the WETH USD pool is changed\"},\"WorkExtraGasChange(uint256)\":{\"notice\":\"Emitted when the work extra gas amount is changed\"}},\"kind\":\"user\",\"methods\":{\"BOOST_BASE()\":{\"notice\":\"The boost base used to calculate the boost rewards for the keeper\"},\"KP3R()\":{\"notice\":\"Address of KP3R token\"},\"WETH()\":{\"notice\":\"Ethereum mainnet WETH address used for quoting references\"},\"acceptPendingGovernor()\":{\"notice\":\"Allows a proposed governor to accept the governance\"},\"bonds(address)\":{\"notice\":\"Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\"},\"getKP3RsAtTick(uint256,int56,uint256)\":{\"notice\":\"Given a tick and a liquidity amount, calculates the underlying KP3R tokens\"},\"getPaymentParams(uint256)\":{\"notice\":\"Get multiplier, quote, and extra, in order to calculate keeper payment\"},\"getPoolTokens(address)\":{\"notice\":\"Given a pool address, returns the underlying tokens of the pair\"},\"getQuoteAtTick(uint128,int56,uint256)\":{\"notice\":\"Given a tick and a token amount, calculates the output in correspondant token\"},\"getRewardAmount(uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\"},\"getRewardAmountFor(address,uint256)\":{\"notice\":\"Calculates the reward (in KP3R) that corresponds to a keeper for using gas\"},\"getRewardBoostFor(uint256)\":{\"notice\":\"Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\"},\"isKP3RToken0(address)\":{\"notice\":\"Defines the order of the tokens in the pair for twap calculations\"},\"keep3rV2()\":{\"notice\":\"Address of Keep3r V2\"},\"kp3rWethPool()\":{\"notice\":\"KP3R-WETH pool that is being used as oracle\"},\"maxBoost()\":{\"notice\":\"The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\"},\"minBaseFee()\":{\"notice\":\"The minimum base fee that is used to calculate keeper rewards\"},\"minBoost()\":{\"notice\":\"The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\"},\"minPriorityFee()\":{\"notice\":\"The minimum priority fee that is also rewarded for keepers\"},\"observe(address,uint32[])\":{\"notice\":\"Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\"},\"quote(uint256)\":{\"notice\":\"Calculates the amount of KP3R that corresponds to the ETH passed into the function\"},\"quoteTwapTime()\":{\"notice\":\"The twap time for quoting\"},\"quoteUsdToEth(uint256)\":{\"notice\":\"Quotes USD to ETH\"},\"setKeep3rV2(address)\":{\"notice\":\"Sets the Keep3r V2 address\"},\"setKp3rWethPool(address)\":{\"notice\":\"Sets KP3R-WETH pool\"},\"setMaxBoost(uint256)\":{\"notice\":\"Sets the maximum boost multiplier\"},\"setMinBaseFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas fee\"},\"setMinBoost(uint256)\":{\"notice\":\"Sets the minimum boost multiplier\"},\"setMinPriorityFee(uint256)\":{\"notice\":\"Sets the minimum rewarded gas priority fee\"},\"setOracle(address,address)\":{\"notice\":\"Sets an oracle for a given liquidity\"},\"setPendingGovernor(address)\":{\"notice\":\"Allows a governor to propose a new governor\"},\"setQuoteTwapTime(uint32)\":{\"notice\":\"Sets the quote twap time\"},\"setTargetBond(uint256)\":{\"notice\":\"Sets the target bond amount\"},\"setWethUsdPool(address,uint8)\":{\"notice\":\"Sets an oracle for querying WETH/USD quote\"},\"setWorkExtraGas(uint256)\":{\"notice\":\"Sets the work extra gas amount\"},\"targetBond()\":{\"notice\":\"The targeted amount of bonded KP3Rs to max-up reward multiplier For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\"},\"wethUSDPool()\":{\"notice\":\"WETH-USD pool that is being used as oracle\"},\"workExtraGas()\":{\"notice\":\"The amount of unaccounted gas that is going to be added to keeper payments\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/sidechain/Keep3rHelperSidechain.sol\":\"Keep3rHelperSidechain\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '../interfaces/IGovernable.sol';\\n\\n/// @title Governable contract\\n/// @notice Manages the governor role\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public governor;\\n\\n /// @inheritdoc IGovernable\\n address public pendingGovernor;\\n\\n constructor(address _governor) {\\n if (_governor == address(0)) revert ZeroAddress();\\n governor = _governor;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\\n _setPendingGovernor(_pendingGovernor);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptPendingGovernor() external onlyPendingGovernor {\\n _acceptPendingGovernor();\\n }\\n\\n function _setPendingGovernor(address _pendingGovernor) internal {\\n if (_pendingGovernor == address(0)) revert ZeroAddress();\\n pendingGovernor = _pendingGovernor;\\n emit PendingGovernorSet(governor, _pendingGovernor);\\n }\\n\\n function _acceptPendingGovernor() internal {\\n governor = pendingGovernor;\\n delete pendingGovernor;\\n emit PendingGovernorAccepted(governor);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governor\\n modifier onlyGovernor() {\\n if (msg.sender != governor) revert OnlyGovernor();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernor\\n modifier onlyPendingGovernor() {\\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x3f11408cfcb015a99dc417e075c8ebc39b796fc2adc3e81b036487e4486881b3\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from './IGovernable.sol';\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title DustCollector interface\\ninterface IDustCollector is IBaseErrors, IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _ethAddress Address used to trigger a native token transfer\\n // solhint-disable-next-line func-name-mixedcase\\n function ETH_ADDRESS() external view returns (address _ethAddress);\\n\\n // EVENTS\\n\\n /// @notice Emitted when dust is sent\\n /// @param _to The address which wil received the funds\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n // FUNCTIONS\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amont of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(address _token, uint256 _amount, address _to) external;\\n}\\n\",\"keccak256\":\"0xbe22cc660bd6846093504989146038bd369f511325cef40cdc647fe7e04206b1\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\nimport './pool/IUniswapV3PoolImmutables.sol';\\nimport './pool/IUniswapV3PoolState.sol';\\nimport './pool/IUniswapV3PoolDerivedState.sol';\\nimport './pool/IUniswapV3PoolActions.sol';\\nimport './pool/IUniswapV3PoolOwnerActions.sol';\\nimport './pool/IUniswapV3PoolEvents.sol';\\n\\n/// @title The interface for a Uniswap V3 Pool\\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\\n/// to the ERC20 specification\\n/// @dev The pool interface is broken up into many smaller pieces\\ninterface IUniswapV3Pool is\\n IUniswapV3PoolImmutables,\\n IUniswapV3PoolState,\\n IUniswapV3PoolDerivedState,\\n IUniswapV3PoolActions,\\n IUniswapV3PoolOwnerActions,\\n IUniswapV3PoolEvents\\n{\\n\\n}\\n\",\"keccak256\":\"0xfe6113d518466cd6652c85b111e01f33eb62157f49ae5ed7d5a3947a2044adb1\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissionless pool actions\\n/// @notice Contains pool methods that can be called by anyone\\ninterface IUniswapV3PoolActions {\\n /// @notice Sets the initial price for the pool\\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\\n function initialize(uint160 sqrtPriceX96) external;\\n\\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\\n /// @param recipient The address for which the liquidity will be created\\n /// @param tickLower The lower tick of the position in which to add liquidity\\n /// @param tickUpper The upper tick of the position in which to add liquidity\\n /// @param amount The amount of liquidity to mint\\n /// @param data Any data that should be passed through to the callback\\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\\n function mint(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount,\\n bytes calldata data\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Collects tokens owed to a position\\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\\n /// @param recipient The address which should receive the fees collected\\n /// @param tickLower The lower tick of the position for which to collect fees\\n /// @param tickUpper The upper tick of the position for which to collect fees\\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\\n /// @return amount0 The amount of fees collected in token0\\n /// @return amount1 The amount of fees collected in token1\\n function collect(\\n address recipient,\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n\\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\\n /// @dev Fees must be collected separately via a call to #collect\\n /// @param tickLower The lower tick of the position for which to burn liquidity\\n /// @param tickUpper The upper tick of the position for which to burn liquidity\\n /// @param amount How much liquidity to burn\\n /// @return amount0 The amount of token0 sent to the recipient\\n /// @return amount1 The amount of token1 sent to the recipient\\n function burn(\\n int24 tickLower,\\n int24 tickUpper,\\n uint128 amount\\n ) external returns (uint256 amount0, uint256 amount1);\\n\\n /// @notice Swap token0 for token1, or token1 for token0\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\\n /// @param recipient The address to receive the output of the swap\\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\\n /// @param data Any data to be passed through to the callback\\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\\n /// @param recipient The address which will receive the token0 and token1 amounts\\n /// @param amount0 The amount of token0 to send\\n /// @param amount1 The amount of token1 to send\\n /// @param data Any data to be passed through to the callback\\n function flash(\\n address recipient,\\n uint256 amount0,\\n uint256 amount1,\\n bytes calldata data\\n ) external;\\n\\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\\n /// the input observationCardinalityNext.\\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\\n}\\n\",\"keccak256\":\"0x9453dd0e7442188667d01d9b65de3f1e14e9511ff3e303179a15f6fc267f7634\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that is not stored\\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\\n/// blockchain. The functions here may have variable gas costs.\\ninterface IUniswapV3PoolDerivedState {\\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\\n /// you must call it with secondsAgos = [3600, 0].\\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\\n /// timestamp\\n function observe(uint32[] calldata secondsAgos)\\n external\\n view\\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\\n\\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\\n /// snapshot is taken and the second snapshot is taken.\\n /// @param tickLower The lower tick of the range\\n /// @param tickUpper The upper tick of the range\\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\\n /// @return secondsInside The snapshot of seconds per liquidity for the range\\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\\n external\\n view\\n returns (\\n int56 tickCumulativeInside,\\n uint160 secondsPerLiquidityInsideX128,\\n uint32 secondsInside\\n );\\n}\\n\",\"keccak256\":\"0xe603ac5b17ecdee73ba2b27efdf386c257a19c14206e87eee77e2017b742d9e5\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Events emitted by a pool\\n/// @notice Contains all events emitted by the pool\\ninterface IUniswapV3PoolEvents {\\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\\n event Initialize(uint160 sqrtPriceX96, int24 tick);\\n\\n /// @notice Emitted when liquidity is minted for a given position\\n /// @param sender The address that minted the liquidity\\n /// @param owner The owner of the position and recipient of any minted liquidity\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity minted to the position range\\n /// @param amount0 How much token0 was required for the minted liquidity\\n /// @param amount1 How much token1 was required for the minted liquidity\\n event Mint(\\n address sender,\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted when fees are collected by the owner of a position\\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\\n /// @param owner The owner of the position for which fees are collected\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount0 The amount of token0 fees collected\\n /// @param amount1 The amount of token1 fees collected\\n event Collect(\\n address indexed owner,\\n address recipient,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount0,\\n uint128 amount1\\n );\\n\\n /// @notice Emitted when a position's liquidity is removed\\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\\n /// @param owner The owner of the position for which liquidity is removed\\n /// @param tickLower The lower tick of the position\\n /// @param tickUpper The upper tick of the position\\n /// @param amount The amount of liquidity to remove\\n /// @param amount0 The amount of token0 withdrawn\\n /// @param amount1 The amount of token1 withdrawn\\n event Burn(\\n address indexed owner,\\n int24 indexed tickLower,\\n int24 indexed tickUpper,\\n uint128 amount,\\n uint256 amount0,\\n uint256 amount1\\n );\\n\\n /// @notice Emitted by the pool for any swaps between token0 and token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the output of the swap\\n /// @param amount0 The delta of the token0 balance of the pool\\n /// @param amount1 The delta of the token1 balance of the pool\\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\\n /// @param liquidity The liquidity of the pool after the swap\\n /// @param tick The log base 1.0001 of price of the pool after the swap\\n event Swap(\\n address indexed sender,\\n address indexed recipient,\\n int256 amount0,\\n int256 amount1,\\n uint160 sqrtPriceX96,\\n uint128 liquidity,\\n int24 tick\\n );\\n\\n /// @notice Emitted by the pool for any flashes of token0/token1\\n /// @param sender The address that initiated the swap call, and that received the callback\\n /// @param recipient The address that received the tokens from flash\\n /// @param amount0 The amount of token0 that was flashed\\n /// @param amount1 The amount of token1 that was flashed\\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\\n event Flash(\\n address indexed sender,\\n address indexed recipient,\\n uint256 amount0,\\n uint256 amount1,\\n uint256 paid0,\\n uint256 paid1\\n );\\n\\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\\n /// just before a mint/swap/burn.\\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\\n event IncreaseObservationCardinalityNext(\\n uint16 observationCardinalityNextOld,\\n uint16 observationCardinalityNextNew\\n );\\n\\n /// @notice Emitted when the protocol fee is changed by the pool\\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\\n /// @param feeProtocol0New The updated value of the token0 protocol fee\\n /// @param feeProtocol1New The updated value of the token1 protocol fee\\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\\n\\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\\n /// @param sender The address that collects the protocol fees\\n /// @param recipient The address that receives the collected protocol fees\\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x8071514d0fe5d17d6fbd31c191cdfb703031c24e0ece3621d88ab10e871375cd\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that never changes\\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\\ninterface IUniswapV3PoolImmutables {\\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\\n /// @return The contract address\\n function factory() external view returns (address);\\n\\n /// @notice The first of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token0() external view returns (address);\\n\\n /// @notice The second of the two tokens of the pool, sorted by address\\n /// @return The token contract address\\n function token1() external view returns (address);\\n\\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\\n /// @return The fee\\n function fee() external view returns (uint24);\\n\\n /// @notice The pool tick spacing\\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\\n /// This value is an int24 to avoid casting even though it is always positive.\\n /// @return The tick spacing\\n function tickSpacing() external view returns (int24);\\n\\n /// @notice The maximum amount of position liquidity that can use any tick in the range\\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\\n /// @return The max amount of liquidity per tick\\n function maxLiquidityPerTick() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xf6e5d2cd1139c4c276bdbc8e1d2b256e456c866a91f1b868da265c6d2685c3f7\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Permissioned pool actions\\n/// @notice Contains pool methods that may only be called by the factory owner\\ninterface IUniswapV3PoolOwnerActions {\\n /// @notice Set the denominator of the protocol's % share of the fees\\n /// @param feeProtocol0 new protocol fee for token0 of the pool\\n /// @param feeProtocol1 new protocol fee for token1 of the pool\\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\\n\\n /// @notice Collect the protocol fee accrued to the pool\\n /// @param recipient The address to which collected protocol fees should be sent\\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\\n /// @return amount0 The protocol fee collected in token0\\n /// @return amount1 The protocol fee collected in token1\\n function collectProtocol(\\n address recipient,\\n uint128 amount0Requested,\\n uint128 amount1Requested\\n ) external returns (uint128 amount0, uint128 amount1);\\n}\\n\",\"keccak256\":\"0x759b78a2918af9e99e246dc3af084f654e48ef32bb4e4cb8a966aa3dcaece235\",\"license\":\"GPL-2.0-or-later\"},\"@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n/// @title Pool state that can change\\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\\n/// per transaction\\ninterface IUniswapV3PoolState {\\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\\n /// when accessed externally.\\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\\n /// boundary.\\n /// observationIndex The index of the last oracle observation that was written,\\n /// observationCardinality The current maximum number of observations stored in the pool,\\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\\n /// feeProtocol The protocol fee for both tokens of the pool.\\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\\n /// unlocked Whether the pool is currently locked to reentrancy\\n function slot0()\\n external\\n view\\n returns (\\n uint160 sqrtPriceX96,\\n int24 tick,\\n uint16 observationIndex,\\n uint16 observationCardinality,\\n uint16 observationCardinalityNext,\\n uint8 feeProtocol,\\n bool unlocked\\n );\\n\\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal0X128() external view returns (uint256);\\n\\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\\n /// @dev This value can overflow the uint256\\n function feeGrowthGlobal1X128() external view returns (uint256);\\n\\n /// @notice The amounts of token0 and token1 that are owed to the protocol\\n /// @dev Protocol fees will never exceed uint128 max in either token\\n function protocolFees() external view returns (uint128 token0, uint128 token1);\\n\\n /// @notice The currently in range liquidity available to the pool\\n /// @dev This value has no relationship to the total liquidity across all ticks\\n function liquidity() external view returns (uint128);\\n\\n /// @notice Look up information about a specific tick in the pool\\n /// @param tick The tick to look up\\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\\n /// tick upper,\\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\\n /// a specific position.\\n function ticks(int24 tick)\\n external\\n view\\n returns (\\n uint128 liquidityGross,\\n int128 liquidityNet,\\n uint256 feeGrowthOutside0X128,\\n uint256 feeGrowthOutside1X128,\\n int56 tickCumulativeOutside,\\n uint160 secondsPerLiquidityOutsideX128,\\n uint32 secondsOutside,\\n bool initialized\\n );\\n\\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\\n function tickBitmap(int16 wordPosition) external view returns (uint256);\\n\\n /// @notice Returns the information about a position by the position's key\\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\\n /// @return _liquidity The amount of liquidity in the position,\\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\\n function positions(bytes32 key)\\n external\\n view\\n returns (\\n uint128 _liquidity,\\n uint256 feeGrowthInside0LastX128,\\n uint256 feeGrowthInside1LastX128,\\n uint128 tokensOwed0,\\n uint128 tokensOwed1\\n );\\n\\n /// @notice Returns data about a specific observation index\\n /// @param index The element of the observations array to fetch\\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\\n /// ago, rather than at a specific index in the array.\\n /// @return blockTimestamp The timestamp of the observation,\\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\\n /// Returns initialized whether the observation has been initialized and the values are safe to use\\n function observations(uint256 index)\\n external\\n view\\n returns (\\n uint32 blockTimestamp,\\n int56 tickCumulative,\\n uint160 secondsPerLiquidityCumulativeX128,\\n bool initialized\\n );\\n}\\n\",\"keccak256\":\"0x852dc1f5df7dcf7f11e7bb3eed79f0cea72ad4b25f6a9d2c35aafb48925fd49f\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/Keep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2003\\u2003\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2003\\u2003\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2003\\u2003\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/IKeep3rHelper.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\n\\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governor,\\n address _kp3rWethPool\\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governor, _kp3rWethPool) {}\\n\\n /// @inheritdoc IKeep3rHelper\\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\\n uint32[] memory _secondsAgos = new uint32[](2);\\n _secondsAgos[1] = quoteTwapTime;\\n\\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isKP3RToken0 ? _difference : -_difference, quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\\n // solhint-disable-next-line avoid-tx-origin\\n return getRewardAmountFor(tx.origin, _gasUsed);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\\n _bonds = Math.min(_bonds, targetBond);\\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\\n _rewardBoost = _cap * _getBasefee();\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\\n address _token0;\\n address _token1;\\n (_token0, _token1) = getPoolTokens(_pool);\\n if (_token0 == KP3R) {\\n return true;\\n } else if (_token1 != KP3R) {\\n revert LiquidityPairInvalid();\\n }\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n override\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n )\\n {\\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\\n _tickCumulative1 = _uniswapResponse[0];\\n if (_uniswapResponse.length > 1) {\\n _tickCumulative2 = _uniswapResponse[1];\\n }\\n _success = true;\\n } catch (bytes memory) {}\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n virtual\\n override\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n )\\n {\\n _oneEthQuote = quote(1 ether);\\n _boost = getRewardBoostFor(_bonds);\\n _extra = workExtraGas;\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure override returns (uint256 _kp3rAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) public pure override returns (uint256 _quoteAmount) {\\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\\n\\n if (sqrtRatioX96 <= type(uint128).max) {\\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\\n } else {\\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\\n }\\n }\\n\\n /// @notice Gets the gas basefee cost to calculate keeper rewards\\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\\n }\\n}\\n\",\"keccak256\":\"0x442a723bdbd1011e26ef2b12fbca87788ee355221ad809f52e77a69a0b29e8cc\",\"license\":\"MIT\"},\"solidity/contracts/Keep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.7 <0.9.0;\\n\\nimport './libraries/FullMath.sol';\\nimport './libraries/TickMath.sol';\\nimport '../interfaces/IKeep3r.sol';\\nimport '../interfaces/external/IKeep3rV1.sol';\\nimport '../interfaces/IKeep3rHelperParameters.sol';\\nimport './Keep3rHelperParameters.sol';\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\\n\\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\\n /// @inheritdoc IKeep3rHelperParameters\\n address public immutable override KP3R;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public constant override BOOST_BASE = 10_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBoost = 11_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override maxBoost = 12_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override targetBond = 200 ether;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override workExtraGas = 34_000;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint32 public override quoteTwapTime = 10 minutes;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minBaseFee = 15e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n uint256 public override minPriorityFee = 2e9;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n address public override keep3rV2;\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n IKeep3rHelperParameters.Kp3rWethOraclePool public override kp3rWethPool;\\n\\n constructor(\\n address _kp3r,\\n address _keep3rV2,\\n address _governor,\\n address _kp3rWethPool\\n ) Governable(_governor) {\\n KP3R = _kp3r;\\n keep3rV2 = _keep3rV2;\\n\\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\\n bool _isKP3RToken0 = _validateOraclePool(_kp3rWethPool, KP3R);\\n kp3rWethPool = Kp3rWethOraclePool(_kp3rWethPool, _isKP3RToken0);\\n emit Kp3rWethPoolChange(_kp3rWethPool, _isKP3RToken0);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKp3rWethPool(address _poolAddress) external override onlyGovernor {\\n if (_poolAddress == address(0)) revert ZeroAddress();\\n _setKp3rWethPool(_poolAddress);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBoost(uint256 _minBoost) external override onlyGovernor {\\n minBoost = _minBoost;\\n emit MinBoostChange(minBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernor {\\n maxBoost = _maxBoost;\\n emit MaxBoostChange(maxBoost);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setTargetBond(uint256 _targetBond) external override onlyGovernor {\\n targetBond = _targetBond;\\n emit TargetBondChange(targetBond);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setKeep3rV2(address _keep3rV2) external override onlyGovernor {\\n if (_keep3rV2 == address(0)) revert ZeroAddress();\\n keep3rV2 = _keep3rV2;\\n emit Keep3rV2Change(keep3rV2);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernor {\\n workExtraGas = _workExtraGas;\\n emit WorkExtraGasChange(workExtraGas);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernor {\\n _setQuoteTwapTime(_quoteTwapTime);\\n }\\n\\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\\n quoteTwapTime = _quoteTwapTime;\\n emit QuoteTwapTimeChange(quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernor {\\n minBaseFee = _minBaseFee;\\n emit MinBaseFeeChange(minBaseFee);\\n }\\n\\n /// @inheritdoc IKeep3rHelperParameters\\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernor {\\n minPriorityFee = _minPriorityFee;\\n emit MinPriorityFeeChange(minPriorityFee);\\n }\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function _setKp3rWethPool(address _poolAddress) internal {\\n bool _isKP3RToken0 = _validateOraclePool(_poolAddress, KP3R);\\n kp3rWethPool = Kp3rWethOraclePool(_poolAddress, _isKP3RToken0);\\n emit Kp3rWethPoolChange(_poolAddress, _isKP3RToken0);\\n }\\n\\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (bool _isTKNToken0) {\\n _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\\n }\\n}\\n\",\"keccak256\":\"0x327e0b63bca4528c66038e28bf43af552e763a492944e4ce043fe07dc52f6ac8\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/libraries/TickMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\npragma solidity >=0.5.0;\\n\\n// solhint-disable\\n\\n/// @title Math library for computing sqrt prices from ticks and vice versa\\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\\n/// prices between 2**-128 and 2**128\\nlibrary TickMath {\\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\\n int24 internal constant MIN_TICK = -887272;\\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\\n int24 internal constant MAX_TICK = -MIN_TICK;\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\\n\\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\\n /// at the given tick\\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\\n\\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\\n\\n if (tick > 0) ratio = type(uint256).max / ratio;\\n\\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\\n }\\n\\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\\n // Second inequality must be < because the price can never reach the price at the max tick\\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\\n uint256 ratio = uint256(sqrtPriceX96) << 32;\\n\\n uint256 r = ratio;\\n uint256 msb = 0;\\n\\n assembly {\\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(5, gt(r, 0xFFFFFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(4, gt(r, 0xFFFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(3, gt(r, 0xFF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(2, gt(r, 0xF))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := shl(1, gt(r, 0x3))\\n msb := or(msb, f)\\n r := shr(f, r)\\n }\\n assembly {\\n let f := gt(r, 0x1)\\n msb := or(msb, f)\\n }\\n\\n if (msb >= 128) r = ratio >> (msb - 127);\\n else r = ratio << (127 - msb);\\n\\n int256 log_2 = (int256(msb) - 128) << 64;\\n\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(63, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(62, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(61, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(60, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(59, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(58, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(57, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(56, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(55, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(54, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(53, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(52, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(51, f))\\n r := shr(f, r)\\n }\\n assembly {\\n r := shr(127, mul(r, r))\\n let f := shr(128, r)\\n log_2 := or(log_2, shl(50, f))\\n }\\n\\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\\n\\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\\n\\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\\n }\\n}\\n\",\"keccak256\":\"0x11b965ba576ff91b4a6e9533c0f334f2b7b6024ee1c54e36d21799de5580899d\",\"license\":\"GPL-2.0-or-later\"},\"solidity/contracts/sidechain/Keep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3rHelper.sol';\\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\\n\\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\\n /// @inheritdoc IKeep3rHelperSidechain\\n mapping(address => address) public override oracle;\\n /// @inheritdoc IKeep3rHelperSidechain\\n IKeep3rHelperSidechain.WethUsdOraclePool public override wethUSDPool;\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n address public immutable override WETH;\\n\\n /// @dev Amount of decimals in which USD is quoted within the contract\\n uint256 constant _USD_BASE_DECIMALS = 18;\\n\\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\\n /// @param _governor Address of governor\\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\\n /// @dev Oracle pools should use 18 decimals tokens\\n constructor(\\n address _keep3rV2,\\n address _governor,\\n address _kp3r,\\n address _weth,\\n address _kp3rWethOracle,\\n address _wethUsdOracle,\\n uint8 _usdDecimals\\n ) Keep3rHelper(_kp3r, _keep3rV2, _governor, _kp3rWethOracle) {\\n WETH = _weth;\\n\\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\\n bool _isWETHToken0 = _validateOraclePool(_wethUsdOracle, WETH);\\n wethUSDPool = WethUsdOraclePool(_wethUsdOracle, _isWETHToken0, _usdDecimals);\\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isWETHToken0, _usdDecimals);\\n\\n _setQuoteTwapTime(1 days);\\n workExtraGas = 0;\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function setOracle(address _liquidity, address _oracle) external override onlyGovernor {\\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\\n oracle[_liquidity] = _oracle;\\n emit OracleSet(_liquidity, _oracle);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\\n uint32[] memory _secondsAgos = new uint32[](2);\\n _secondsAgos[1] = quoteTwapTime;\\n _usd = _usd / 10**(_USD_BASE_DECIMALS - wethUSDPool.usdDecimals);\\n\\n /// @dev Oracle is compatible with IUniswapV3Pool\\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isWETHToken0 ? _difference : -_difference, quoteTwapTime);\\n }\\n\\n /// @inheritdoc IKeep3rHelperSidechain\\n function setWethUsdPool(address _poolAddress, uint8 _usdDecimals) external override onlyGovernor {\\n if (_poolAddress == address(0)) revert ZeroAddress();\\n _setWethUsdPool(_poolAddress, _usdDecimals);\\n }\\n\\n /// @inheritdoc IKeep3rHelper\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n virtual\\n override(Keep3rHelper, IKeep3rHelper)\\n returns (\\n uint256 _boost,\\n uint256 _oneUsdQuote,\\n uint256 _extraGas\\n )\\n {\\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\\n _boost = getRewardBoostFor(_bonds);\\n _extraGas = workExtraGas;\\n }\\n\\n function _setWethUsdPool(address _poolAddress, uint8 _usdDecimals) internal {\\n bool _isWETHToken0 = _validateOraclePool(_poolAddress, WETH);\\n wethUSDPool = WethUsdOraclePool(_poolAddress, _isWETHToken0, _usdDecimals);\\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isWETHToken0, _usdDecimals);\\n }\\n\\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\\n return 1;\\n }\\n}\\n\",\"keccak256\":\"0x85a9f68843b3a5ac3a37963cd655c52ead22b3a7c8b728128ae5db0bd19f083d\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct Kp3rWethOraclePool {\\n address poolAddress;\\n bool isKP3RToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isKP3RToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0xc571e913c0e3c02f4aa0b27090ca1608c85c68768dc2ab979f8aef7c731f60b2\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0xf4748c236ddf409e45e7169c735e2fc54e627b2b3ccd189ebb438ad768f1deb1\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governor to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governor to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0xdfdabcecbed06fcb2eb1b80e6a61d681afecd1f75c58a888451de7927b10c3b2\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governor or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governor or slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x7fb7153d88e9e65d28b278320884517d6b423b2e8cfc78ee0ee16bc04073278e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governor to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0x8fe10565035bb918b2b1c7d730533bcfe9ec79078f28544852f8178e76302562\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governor when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governor when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x2a847a2ab6dbee960ca84e142ad9c578d8953c4adf1d3221669400ea86c9b82e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IGovernable, IDustCollector {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xc0a19b0dfac535cbffabc0d76cb0569618dedb922b0413bc12358efa47dc32bf\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../IKeep3rHelper.sol';\\n\\n/// @title Keep3rHelperSidechain contract\\n/// @notice Contains all the helper functions for sidechain keep3r implementations\\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\\n // Structs\\n\\n /// @dev WETH-USD Pool address, isWETHToken0 and usdDecimals\\n /// @dev Created in order to quote any kind of USD tokens\\n struct WethUsdOraclePool {\\n address poolAddress;\\n bool isWETHToken0;\\n uint8 usdDecimals;\\n }\\n\\n // Events\\n\\n /// @notice The oracle for a liquidity has been saved\\n /// @param _liquidity The address of the given liquidity\\n /// @param _oraclePool The address of the oracle pool\\n event OracleSet(address _liquidity, address _oraclePool);\\n\\n /// @notice Emitted when the WETH USD pool is changed\\n /// @param _address Address of the new WETH USD pool\\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\\n /// @param _usdDecimals The amount of decimals of the USD token paired with ETH\\n event WethUSDPoolChange(address _address, bool _isWETHToken0, uint8 _usdDecimals);\\n\\n /// Variables\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n /// @return _weth Address of WETH token\\n // solhint-disable func-name-mixedcase\\n function WETH() external view returns (address _weth);\\n\\n /// @return _oracle The address of the observable pool for given liquidity\\n function oracle(address _liquidity) external view returns (address _oracle);\\n\\n /// @notice WETH-USD pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\\n /// @return usdDecimals The amount of decimals of the USD token paired with ETH\\n function wethUSDPool()\\n external\\n view\\n returns (\\n address poolAddress,\\n bool isWETHToken0,\\n uint8 usdDecimals\\n );\\n\\n /// @notice Quotes USD to ETH\\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\\n /// @param _usd The amount of USD to quote to ETH\\n /// @return _eth The resulting amount of ETH after quoting the USD\\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\\n\\n /// Methods\\n\\n /// @notice Sets an oracle for a given liquidity\\n /// @param _liquidity The address of the liquidity\\n /// @param _oracle The address of the pool used to quote the liquidity from\\n /// @dev The oracle must contain KP3R as either token0 or token1\\n function setOracle(address _liquidity, address _oracle) external;\\n\\n /// @notice Sets an oracle for querying WETH/USD quote\\n /// @param _poolAddress The address of the pool used as oracle\\n /// @param _usdDecimals The amount of decimals of the USD token paired with ETH\\n /// @dev The oracle must contain WETH as either token0 or token1\\n function setWethUsdPool(address _poolAddress, uint8 _usdDecimals) external;\\n}\\n\",\"keccak256\":\"0xf354f6c4182f4f91ccb3cabe823bc28cdc1a8cb20c40266e6b6e277279fc7b56\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60c0604052612af8600255612ee0600355680ad78ebc5ac62000006004556184d06005556006805463ffffffff191661025817905564037e11d60060075563773594006008553480156200005257600080fd5b50604051620028c6380380620028c683398101604081905262000075916200041c565b8487878583838383816001600160a01b038116620000a65760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b03199081166001600160a01b03938416178255606087901b6001600160601b0319166080526009805490911686841617905590620000f390839087166200026b565b6040805180820182526001600160a01b0385168082528315156020928301819052600a80546001600160a81b0319168317600160a01b83021790558351918252918101919091529192507f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf4108910160405180910390a15050505050606088901b6001600160601b03191660a05250600092506200019d91508490506001600160a01b0387166200026b565b60408051606080820183526001600160a01b03878116808452851515602080860182905260ff8a8116968801879052600c80546001600160a81b031916909417600160a01b9384021760ff60a81b198116600160a81b890290811795869055895191871696169590951785529190920416151590820152928301919091529192507f10e6a379d12c209d558815459d599ade7bcc91d5270a7dfca948da52aef7df34910160405180910390a16200025762015180620003b1565b5050600060055550620004df945050505050565b6000816001600160a01b0316836001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015620002b157600080fd5b505afa158015620002c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ec9190620004ba565b6001600160a01b03161490508015816200038c5750816001600160a01b0316836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156200034557600080fd5b505afa1580156200035a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003809190620004ba565b6001600160a01b031614155b15620003ab5760405163db60809d60e01b815260040160405180910390fd5b92915050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de9060200160405180910390a150565b80516001600160a01b03811681146200041757600080fd5b919050565b600080600080600080600060e0888a0312156200043857600080fd5b6200044388620003ff565b96506200045360208901620003ff565b95506200046360408901620003ff565b94506200047360608901620003ff565b93506200048360808901620003ff565b92506200049360a08901620003ff565b915060c088015160ff81168114620004aa57600080fd5b8091505092959891949750929550565b600060208284031215620004cd57600080fd5b620004d882620003ff565b9392505050565b60805160601c60a05160601c61239f620005276000396000818161051a01526113ca01526000818161025d01528181610c6201528181610ca60152611505015261239f6000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c8063696a437b11610146578063b2e0df96116100c3578063e244208b11610087578063e244208b146105e0578063e3056a34146105f3578063eb37d34914610606578063ed1bd76c1461062f578063f235757f14610642578063fe10d7741461065557600080fd5b8063b2e0df961461053c578063b93f5af01461054f578063c84993af14610562578063ca4f280314610575578063dc686d91146105a857600080fd5b8063a0d271071161010a578063a0d27107146104d3578063a62611a2146104e6578063ab5dce00146104ef578063ab8cedc514610502578063ad5c46481461051557600080fd5b8063696a437b1461043b5780637b40c9131461045e5780638561579c1461049c5780638a9b1b09146104a55780639aaad679146104ae57600080fd5b80632750c0f9116101d45780633facf242116101985780633facf242146103cb578063435b21c1146103d4578063516c3323146104025780635c38eb3a14610415578063607e48d41461042857600080fd5b80632750c0f914610338578063289adb441461038957806337090c2f1461039c5780633b67c3bd146103a55780633cc7ab30146103b857600080fd5b806313f6986d1161021b57806313f6986d146102ea578063160e1e31146102f25780632248e82d1461030557806325f09e61146103265780632742b9e71461032f57600080fd5b806305e0b9a0146102585780630c340a241461029c5780630c525835146102af578063117cfc1b146102c457806311a6e1c7146102d7575b600080fd5b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b60005461027f906001600160a01b031681565b6102c26102bd366004611c79565b610668565b005b60095461027f906001600160a01b031681565b6102c26102e5366004611ca7565b6106cf565b6102c261072f565b6102c2610300366004611ce6565b610764565b610318610313366004611d03565b6107c2565b604051908152602001610293565b61031861271081565b61031860045481565b600c54610361906001600160a01b0381169060ff600160a01b8204811691600160a81b90041683565b604080516001600160a01b039094168452911515602084015260ff1690820152606001610293565b6102c2610397366004611c79565b6107f5565b61031860035481565b6103186103b3366004611c79565b610855565b6102c26103c6366004611ce6565b6109ec565b61031860055481565b6103e76103e2366004611c79565b610a8c565b60408051938452602084019290925290820152606001610293565b610318610410366004611c79565b610abd565b6102c2610423366004611d2f565b610b18565b6102c2610436366004611c79565b610bea565b61044e610449366004611ce6565b610c4a565b6040519015158152602001610293565b600a5461047d906001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b039093168352901515602083015201610293565b61031860025481565b61031860085481565b6006546104be9063ffffffff1681565b60405163ffffffff9091168152602001610293565b6103186104e1366004611d6c565b610cfd565b61031860075481565b6102c26104fd366004611c79565b610d30565b610318610510366004611da4565b610d90565b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6102c261054a366004611c79565b610e39565b6102c261055d366004611df9565b610e99565b610318610570366004611c79565b610ecd565b610588610583366004611ce6565b610edf565b604080516001600160a01b03938416815292909116602083015201610293565b6105bb6105b6366004611e7f565b610fcd565b60408051600694850b81529290930b6020830152151591810191909152606001610293565b6102c26105ee366004611c79565b6110d8565b60015461027f906001600160a01b031681565b61027f610614366004611ce6565b600b602052600090815260409020546001600160a01b031681565b61031861063d366004611c79565b611138565b6102c2610650366004611ce6565b61127e565b610318610663366004611ce6565b6112b2565b6000546001600160a01b031633146106935760405163070545c960e51b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b031633146106fa5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0382166107215760405163d92e233d60e01b815260040160405180910390fd5b61072b82826113c2565b5050565b6001546001600160a01b0316331461075a57604051639ba0305d60e01b815260040160405180910390fd5b61076261149f565b565b6000546001600160a01b0316331461078f5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0381166107b65760405163d92e233d60e01b815260040160405180910390fd5b6107bf816114fd565b50565b6000806107d1610410856112b2565b90506107ed6127106107e38386611f47565b61063d9190611f7c565b949350505050565b6000546001600160a01b031633146108205760405163070545c960e51b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b906020016106c4565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff1691839150600190811061089957610899611f90565b63ffffffff90921660209283029190910190910152600c546108c79060ff600160a81b909104166012611fa6565b6108d290600a6120a1565b6108dc9084611f7c565b600c5460405163883bdbfd60e01b81529194506000916001600160a01b039091169063883bdbfd906109129085906004016120ad565b60006040518083038186803b15801561092a57600080fd5b505afa15801561093e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109669190810190612166565b50905060008160018151811061097e5761097e611f90565b60200260200101518260008151811061099957610999611f90565b60200260200101516109ab919061222b565b600c549091506109e3908690600160a01b900460ff166109d3576109ce8361227b565b6109d5565b825b60065463ffffffff16610d90565b95945050505050565b6000546001600160a01b03163314610a175760405163070545c960e51b815260040160405180910390fd5b6001600160a01b038116610a3e5760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a906020016106c4565b6000806000610aa561063d670de0b6b3a7640000610855565b9150610ab084610abd565b6005549095929450925050565b6000610acb8260045461159b565b9150600060045483600254600354610ae39190611fa6565b610aed9190611f47565b610af79190611f7c565b600254610b0491906122a2565b9050610b11600182611f47565b9392505050565b6000546001600160a01b03163314610b435760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0382161580610b6057506001600160a01b038116155b15610b7e5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038281166000818152600b602090815260409182902080546001600160a01b031916948616948517905581519283528201929092527fc1d3048301c0d23629a2532c8defa6d68f8e1a0e4157918769e9fb1b2eeb888e91015b60405180910390a15050565b6000546001600160a01b03163314610c155760405163070545c960e51b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b906020016106c4565b6000806000610c5884610edf565b80925081935050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610ca4575060019392505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614610cf657604051637d7c8f2760e11b815260040160405180910390fd5b5050919050565b600080610d16610d1184600687900b6122ba565b6115b1565b90506109e3600160601b86836001600160a01b03166119ca565b6000546001600160a01b03163314610d5b5760405163070545c960e51b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e906020016106c4565b600080610da4610d1184600687900b6122ba565b90506001600160801b036001600160a01b03821611610df4576000610dd26001600160a01b03831680611f47565b9050610dec600160c01b876001600160801b0316836119ca565b925050610e31565b6000610e136001600160a01b03831680680100000000000000006119ca565b9050610e2d600160801b876001600160801b0316836119ca565b9250505b509392505050565b6000546001600160a01b03163314610e645760405163070545c960e51b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa906020016106c4565b6000546001600160a01b03163314610ec45760405163070545c960e51b815260040160405180910390fd5b6107bf81611a78565b6000610ed932836107c2565b92915050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610f1b57600080fd5b505afa158015610f2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5391906122e8565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8c57600080fd5b505afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc491906122e8565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b8152600401610ffe91906120ad565b60006040518083038186803b15801561101657600080fd5b505afa92505050801561104b57506040513d6000823e601f3d908101601f191682016040526110489190810190612166565b60015b611085573d808015611079576040519150601f19603f3d011682016040523d82523d6000602084013e61107e565b606091505b50506110d1565b8160008151811061109857611098611f90565b602002602001015194506001825111156110ca57816001815181106110bf576110bf611f90565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b031633146111035760405163070545c960e51b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d54159221906020016106c4565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff1691839150600190811061117c5761117c611f90565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd906111c29085906004016120ad565b60006040518083038186803b1580156111da57600080fd5b505afa1580156111ee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112169190810190612166565b50905060008160018151811061122e5761122e611f90565b60200260200101518260008151811061124957611249611f90565b602002602001015161125b919061222b565b600a549091506109e3908690600160a01b900460ff166109d3576109ce8361227b565b6000546001600160a01b031633146112a95760405163070545c960e51b815260040160405180910390fd5b6107bf81611ac0565b600080600960009054906101000a90046001600160a01b03166001600160a01b0316631ef94b916040518163ffffffff1660e01b815260040160206040518083038186803b15801561130357600080fd5b505afa158015611317573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133b91906122e8565b60095460405163a39744b560e01b81526001600160a01b038681166004830152808416602483015292935091169063a39744b59060440160206040518083038186803b15801561138a57600080fd5b505afa15801561139e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b119190612305565b60006113ee837f0000000000000000000000000000000000000000000000000000000000000000611b43565b60408051606080820183526001600160a01b03878116808452851515602080860182905260ff8a8116968801879052600c80546001600160a81b031916909417600160a01b9384021760ff60a81b198116600160a81b890290811795869055895191871696169590951785529190920416151590820152928301919091529192507f10e6a379d12c209d558815459d599ade7bcc91d5270a7dfca948da52aef7df34910160405180910390a1505050565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6000611529827f0000000000000000000000000000000000000000000000000000000000000000611b43565b6040805180820182526001600160a01b0385168082528315156020928301819052600a80546001600160a81b0319168317600160a01b83021790558351918252918101919091529192507f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf41089101610bde565b60008183106115aa5781610b11565b5090919050565b60008060008360020b126115c8578260020b6115d5565b8260020b6115d59061231e565b90506115e4620d89e71961233b565b60020b81111561161e5760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b60006001821661163257600160801b611644565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff169050600282161561168357608061167e826ffff97272373d413259a46990580e213a611f47565b901c90505b60048216156116ad5760806116a8826ffff2e50f5f656932ef12357cf3c7fdcc611f47565b901c90505b60088216156116d75760806116d2826fffe5caca7e10e4e61c3624eaa0941cd0611f47565b901c90505b60108216156117015760806116fc826fffcb9843d60f6159c9db58835c926644611f47565b901c90505b602082161561172b576080611726826fff973b41fa98c081472e6896dfb254c0611f47565b901c90505b6040821615611755576080611750826fff2ea16466c96a3843ec78b326b52861611f47565b901c90505b608082161561177f57608061177a826ffe5dee046a99a2a811c461f1969c3053611f47565b901c90505b6101008216156117aa5760806117a5826ffcbe86c7900a88aedcffc83b479aa3a4611f47565b901c90505b6102008216156117d55760806117d0826ff987a7253ac413176f2b074cf7815e54611f47565b901c90505b6104008216156118005760806117fb826ff3392b0822b70005940c7a398e4b70f3611f47565b901c90505b61080082161561182b576080611826826fe7159475a2c29b7443b29c7fa6e889d9611f47565b901c90505b611000821615611856576080611851826fd097f3bdfd2022b8845ad8f792aa5825611f47565b901c90505b61200082161561188157608061187c826fa9f746462d870fdf8a65dc1f90e061e5611f47565b901c90505b6140008216156118ac5760806118a7826f70d869a156d2a1b890bb3df62baf32f7611f47565b901c90505b6180008216156118d75760806118d2826f31be135f97d08fd981231505542fcfa6611f47565b901c90505b620100008216156119035760806118fe826f09aa508b5b7a84e1c677de54f3e99bc9611f47565b901c90505b6202000082161561192e576080611929826e5d6af8dedb81196699c329225ee604611f47565b901c90505b62040000821615611958576080611953826d2216e584f5fa1ea926041bedfe98611f47565b901c90505b6208000082161561198057608061197b826b048a170391f7dc42444e8fa2611f47565b901c90505b60008460020b131561199b5761199881600019611f7c565b90505b6119aa64010000000082612355565b156119b65760016119b9565b60005b6107ed9060ff16602083901c6122a2565b600080806000198587098587029250828110838203039150508060001415611a0457600084116119f957600080fd5b508290049050610b11565b808411611a1057600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de906020016106c4565b6001600160a01b038116611ae75760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec91016106c4565b6000816001600160a01b0316836001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015611b8857600080fd5b505afa158015611b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc091906122e8565b6001600160a01b0316149050801581611c5b5750816001600160a01b0316836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015611c1757600080fd5b505afa158015611c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4f91906122e8565b6001600160a01b031614155b15610ed95760405163db60809d60e01b815260040160405180910390fd5b600060208284031215611c8b57600080fd5b5035919050565b6001600160a01b03811681146107bf57600080fd5b60008060408385031215611cba57600080fd5b8235611cc581611c92565b9150602083013560ff81168114611cdb57600080fd5b809150509250929050565b600060208284031215611cf857600080fd5b8135610b1181611c92565b60008060408385031215611d1657600080fd5b8235611d2181611c92565b946020939093013593505050565b60008060408385031215611d4257600080fd5b8235611d4d81611c92565b91506020830135611cdb81611c92565b8060060b81146107bf57600080fd5b600080600060608486031215611d8157600080fd5b833592506020840135611d9381611d5d565b929592945050506040919091013590565b600080600060608486031215611db957600080fd5b83356001600160801b0381168114611dd057600080fd5b92506020840135611d9381611d5d565b803563ffffffff81168114611df457600080fd5b919050565b600060208284031215611e0b57600080fd5b610b1182611de0565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e5357611e53611e14565b604052919050565b600067ffffffffffffffff821115611e7557611e75611e14565b5060051b60200190565b60008060408385031215611e9257600080fd5b8235611e9d81611c92565b915060208381013567ffffffffffffffff811115611eba57600080fd5b8401601f81018613611ecb57600080fd5b8035611ede611ed982611e5b565b611e2a565b81815260059190911b82018301908381019088831115611efd57600080fd5b928401925b82841015611f2257611f1384611de0565b82529284019290840190611f02565b80955050505050509250929050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615611f6157611f61611f31565b500290565b634e487b7160e01b600052601260045260246000fd5b600082611f8b57611f8b611f66565b500490565b634e487b7160e01b600052603260045260246000fd5b600082821015611fb857611fb8611f31565b500390565b600181815b80851115611ff8578160001904821115611fde57611fde611f31565b80851615611feb57918102915b93841c9390800290611fc2565b509250929050565b60008261200f57506001610ed9565b8161201c57506000610ed9565b8160018114612032576002811461203c57612058565b6001915050610ed9565b60ff84111561204d5761204d611f31565b50506001821b610ed9565b5060208310610133831016604e8410600b841016171561207b575081810a610ed9565b6120858383611fbd565b806000190482111561209957612099611f31565b029392505050565b6000610b118383612000565b6020808252825182820181905260009190848201906040850190845b818110156120eb57835163ffffffff16835292840192918401916001016120c9565b50909695505050505050565b600082601f83011261210857600080fd5b81516020612118611ed983611e5b565b82815260059290921b8401810191818101908684111561213757600080fd5b8286015b8481101561215b57805161214e81611c92565b835291830191830161213b565b509695505050505050565b6000806040838503121561217957600080fd5b825167ffffffffffffffff8082111561219157600080fd5b818501915085601f8301126121a557600080fd5b815160206121b5611ed983611e5b565b82815260059290921b840181019181810190898411156121d457600080fd5b948201945b838610156121fb5785516121ec81611d5d565b825294820194908201906121d9565b9188015191965090935050508082111561221457600080fd5b50612221858286016120f7565b9150509250929050565b60008160060b8360060b6000811281667fffffffffffff190183128115161561225657612256611f31565b81667fffffffffffff01831381161561227157612271611f31565b5090039392505050565b60008160060b667fffffffffffff1981141561229957612299611f31565b60000392915050565b600082198211156122b5576122b5611f31565b500190565b6000826122c9576122c9611f66565b600160ff1b8214600019841416156122e3576122e3611f31565b500590565b6000602082840312156122fa57600080fd5b8151610b1181611c92565b60006020828403121561231757600080fd5b5051919050565b6000600160ff1b82141561233457612334611f31565b5060000390565b60008160020b627fffff1981141561229957612299611f31565b60008261236457612364611f66565b50069056fea26469706673582212206c0ca89630f2f91836f9a3a38aeffab856a05a5e99be6e2c445b810e579b461a64736f6c63430008080033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102535760003560e01c8063696a437b11610146578063b2e0df96116100c3578063e244208b11610087578063e244208b146105e0578063e3056a34146105f3578063eb37d34914610606578063ed1bd76c1461062f578063f235757f14610642578063fe10d7741461065557600080fd5b8063b2e0df961461053c578063b93f5af01461054f578063c84993af14610562578063ca4f280314610575578063dc686d91146105a857600080fd5b8063a0d271071161010a578063a0d27107146104d3578063a62611a2146104e6578063ab5dce00146104ef578063ab8cedc514610502578063ad5c46481461051557600080fd5b8063696a437b1461043b5780637b40c9131461045e5780638561579c1461049c5780638a9b1b09146104a55780639aaad679146104ae57600080fd5b80632750c0f9116101d45780633facf242116101985780633facf242146103cb578063435b21c1146103d4578063516c3323146104025780635c38eb3a14610415578063607e48d41461042857600080fd5b80632750c0f914610338578063289adb441461038957806337090c2f1461039c5780633b67c3bd146103a55780633cc7ab30146103b857600080fd5b806313f6986d1161021b57806313f6986d146102ea578063160e1e31146102f25780632248e82d1461030557806325f09e61146103265780632742b9e71461032f57600080fd5b806305e0b9a0146102585780630c340a241461029c5780630c525835146102af578063117cfc1b146102c457806311a6e1c7146102d7575b600080fd5b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b60005461027f906001600160a01b031681565b6102c26102bd366004611c79565b610668565b005b60095461027f906001600160a01b031681565b6102c26102e5366004611ca7565b6106cf565b6102c261072f565b6102c2610300366004611ce6565b610764565b610318610313366004611d03565b6107c2565b604051908152602001610293565b61031861271081565b61031860045481565b600c54610361906001600160a01b0381169060ff600160a01b8204811691600160a81b90041683565b604080516001600160a01b039094168452911515602084015260ff1690820152606001610293565b6102c2610397366004611c79565b6107f5565b61031860035481565b6103186103b3366004611c79565b610855565b6102c26103c6366004611ce6565b6109ec565b61031860055481565b6103e76103e2366004611c79565b610a8c565b60408051938452602084019290925290820152606001610293565b610318610410366004611c79565b610abd565b6102c2610423366004611d2f565b610b18565b6102c2610436366004611c79565b610bea565b61044e610449366004611ce6565b610c4a565b6040519015158152602001610293565b600a5461047d906001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b039093168352901515602083015201610293565b61031860025481565b61031860085481565b6006546104be9063ffffffff1681565b60405163ffffffff9091168152602001610293565b6103186104e1366004611d6c565b610cfd565b61031860075481565b6102c26104fd366004611c79565b610d30565b610318610510366004611da4565b610d90565b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6102c261054a366004611c79565b610e39565b6102c261055d366004611df9565b610e99565b610318610570366004611c79565b610ecd565b610588610583366004611ce6565b610edf565b604080516001600160a01b03938416815292909116602083015201610293565b6105bb6105b6366004611e7f565b610fcd565b60408051600694850b81529290930b6020830152151591810191909152606001610293565b6102c26105ee366004611c79565b6110d8565b60015461027f906001600160a01b031681565b61027f610614366004611ce6565b600b602052600090815260409020546001600160a01b031681565b61031861063d366004611c79565b611138565b6102c2610650366004611ce6565b61127e565b610318610663366004611ce6565b6112b2565b6000546001600160a01b031633146106935760405163070545c960e51b815260040160405180910390fd5b60028190556040518181527f0919fdaaac0f59c6bc7eeef4f975d6163475220f1e4820d0bce99c84c51cac1d906020015b60405180910390a150565b6000546001600160a01b031633146106fa5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0382166107215760405163d92e233d60e01b815260040160405180910390fd5b61072b82826113c2565b5050565b6001546001600160a01b0316331461075a57604051639ba0305d60e01b815260040160405180910390fd5b61076261149f565b565b6000546001600160a01b0316331461078f5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0381166107b65760405163d92e233d60e01b815260040160405180910390fd5b6107bf816114fd565b50565b6000806107d1610410856112b2565b90506107ed6127106107e38386611f47565b61063d9190611f7c565b949350505050565b6000546001600160a01b031633146108205760405163070545c960e51b815260040160405180910390fd5b60058190556040518181527fed847bdbab1a30becee18585f23c759bd06156561390d2e7fbffd18e74b56c9b906020016106c4565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff1691839150600190811061089957610899611f90565b63ffffffff90921660209283029190910190910152600c546108c79060ff600160a81b909104166012611fa6565b6108d290600a6120a1565b6108dc9084611f7c565b600c5460405163883bdbfd60e01b81529194506000916001600160a01b039091169063883bdbfd906109129085906004016120ad565b60006040518083038186803b15801561092a57600080fd5b505afa15801561093e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109669190810190612166565b50905060008160018151811061097e5761097e611f90565b60200260200101518260008151811061099957610999611f90565b60200260200101516109ab919061222b565b600c549091506109e3908690600160a01b900460ff166109d3576109ce8361227b565b6109d5565b825b60065463ffffffff16610d90565b95945050505050565b6000546001600160a01b03163314610a175760405163070545c960e51b815260040160405180910390fd5b6001600160a01b038116610a3e5760405163d92e233d60e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527fcf744e4fc39d49b6d8103035078629b8a3be95adc007b0d663e96bdff777b10a906020016106c4565b6000806000610aa561063d670de0b6b3a7640000610855565b9150610ab084610abd565b6005549095929450925050565b6000610acb8260045461159b565b9150600060045483600254600354610ae39190611fa6565b610aed9190611f47565b610af79190611f7c565b600254610b0491906122a2565b9050610b11600182611f47565b9392505050565b6000546001600160a01b03163314610b435760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0382161580610b6057506001600160a01b038116155b15610b7e5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038281166000818152600b602090815260409182902080546001600160a01b031916948616948517905581519283528201929092527fc1d3048301c0d23629a2532c8defa6d68f8e1a0e4157918769e9fb1b2eeb888e91015b60405180910390a15050565b6000546001600160a01b03163314610c155760405163070545c960e51b815260040160405180910390fd5b60078190556040518181527ff1443dcc693c421058f429cf588bc37e5c8de2275c3771a810a5e4bf0a908a4b906020016106c4565b6000806000610c5884610edf565b80925081935050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415610ca4575060019392505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614610cf657604051637d7c8f2760e11b815260040160405180910390fd5b5050919050565b600080610d16610d1184600687900b6122ba565b6115b1565b90506109e3600160601b86836001600160a01b03166119ca565b6000546001600160a01b03163314610d5b5760405163070545c960e51b815260040160405180910390fd5b60048190556040518181527feac367d684b6ac6c6ae7e3e852c06f17e6354e0f1e7122832c3e6d17e0a2b71e906020016106c4565b600080610da4610d1184600687900b6122ba565b90506001600160801b036001600160a01b03821611610df4576000610dd26001600160a01b03831680611f47565b9050610dec600160c01b876001600160801b0316836119ca565b925050610e31565b6000610e136001600160a01b03831680680100000000000000006119ca565b9050610e2d600160801b876001600160801b0316836119ca565b9250505b509392505050565b6000546001600160a01b03163314610e645760405163070545c960e51b815260040160405180910390fd5b60038190556040518181527fa1292b4e7a0d916ccfd2bc83858b05f328e344d1f0f507d97ac66723ac7c2aaa906020016106c4565b6000546001600160a01b03163314610ec45760405163070545c960e51b815260040160405180910390fd5b6107bf81611a78565b6000610ed932836107c2565b92915050565b600080826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015610f1b57600080fd5b505afa158015610f2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5391906122e8565b836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8c57600080fd5b505afa158015610fa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc491906122e8565b91509150915091565b6000806000846001600160a01b031663883bdbfd856040518263ffffffff1660e01b8152600401610ffe91906120ad565b60006040518083038186803b15801561101657600080fd5b505afa92505050801561104b57506040513d6000823e601f3d908101601f191682016040526110489190810190612166565b60015b611085573d808015611079576040519150601f19603f3d011682016040523d82523d6000602084013e61107e565b606091505b50506110d1565b8160008151811061109857611098611f90565b602002602001015194506001825111156110ca57816001815181106110bf576110bf611f90565b602002602001015193505b6001925050505b9250925092565b6000546001600160a01b031633146111035760405163070545c960e51b815260040160405180910390fd5b60088190556040518181527f403b461d2c3bcad840d570faac033e4e69e5649645ce89f3c5b4e28d54159221906020016106c4565b604080516002808252606082018352600092839291906020830190803683375050600654825192935063ffffffff1691839150600190811061117c5761117c611f90565b63ffffffff90921660209283029190910190910152600a5460405163883bdbfd60e01b81526000916001600160a01b03169063883bdbfd906111c29085906004016120ad565b60006040518083038186803b1580156111da57600080fd5b505afa1580156111ee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112169190810190612166565b50905060008160018151811061122e5761122e611f90565b60200260200101518260008151811061124957611249611f90565b602002602001015161125b919061222b565b600a549091506109e3908690600160a01b900460ff166109d3576109ce8361227b565b6000546001600160a01b031633146112a95760405163070545c960e51b815260040160405180910390fd5b6107bf81611ac0565b600080600960009054906101000a90046001600160a01b03166001600160a01b0316631ef94b916040518163ffffffff1660e01b815260040160206040518083038186803b15801561130357600080fd5b505afa158015611317573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133b91906122e8565b60095460405163a39744b560e01b81526001600160a01b038681166004830152808416602483015292935091169063a39744b59060440160206040518083038186803b15801561138a57600080fd5b505afa15801561139e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b119190612305565b60006113ee837f0000000000000000000000000000000000000000000000000000000000000000611b43565b60408051606080820183526001600160a01b03878116808452851515602080860182905260ff8a8116968801879052600c80546001600160a81b031916909417600160a01b9384021760ff60a81b198116600160a81b890290811795869055895191871696169590951785529190920416151590820152928301919091529192507f10e6a379d12c209d558815459d599ade7bcc91d5270a7dfca948da52aef7df34910160405180910390a1505050565b60018054600080546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6000611529827f0000000000000000000000000000000000000000000000000000000000000000611b43565b6040805180820182526001600160a01b0385168082528315156020928301819052600a80546001600160a81b0319168317600160a01b83021790558351918252918101919091529192507f554c636366d5fc882a9ab4b7b9d5181781d1a7076abe50ed410365620dcf41089101610bde565b60008183106115aa5781610b11565b5090919050565b60008060008360020b126115c8578260020b6115d5565b8260020b6115d59061231e565b90506115e4620d89e71961233b565b60020b81111561161e5760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640160405180910390fd5b60006001821661163257600160801b611644565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff169050600282161561168357608061167e826ffff97272373d413259a46990580e213a611f47565b901c90505b60048216156116ad5760806116a8826ffff2e50f5f656932ef12357cf3c7fdcc611f47565b901c90505b60088216156116d75760806116d2826fffe5caca7e10e4e61c3624eaa0941cd0611f47565b901c90505b60108216156117015760806116fc826fffcb9843d60f6159c9db58835c926644611f47565b901c90505b602082161561172b576080611726826fff973b41fa98c081472e6896dfb254c0611f47565b901c90505b6040821615611755576080611750826fff2ea16466c96a3843ec78b326b52861611f47565b901c90505b608082161561177f57608061177a826ffe5dee046a99a2a811c461f1969c3053611f47565b901c90505b6101008216156117aa5760806117a5826ffcbe86c7900a88aedcffc83b479aa3a4611f47565b901c90505b6102008216156117d55760806117d0826ff987a7253ac413176f2b074cf7815e54611f47565b901c90505b6104008216156118005760806117fb826ff3392b0822b70005940c7a398e4b70f3611f47565b901c90505b61080082161561182b576080611826826fe7159475a2c29b7443b29c7fa6e889d9611f47565b901c90505b611000821615611856576080611851826fd097f3bdfd2022b8845ad8f792aa5825611f47565b901c90505b61200082161561188157608061187c826fa9f746462d870fdf8a65dc1f90e061e5611f47565b901c90505b6140008216156118ac5760806118a7826f70d869a156d2a1b890bb3df62baf32f7611f47565b901c90505b6180008216156118d75760806118d2826f31be135f97d08fd981231505542fcfa6611f47565b901c90505b620100008216156119035760806118fe826f09aa508b5b7a84e1c677de54f3e99bc9611f47565b901c90505b6202000082161561192e576080611929826e5d6af8dedb81196699c329225ee604611f47565b901c90505b62040000821615611958576080611953826d2216e584f5fa1ea926041bedfe98611f47565b901c90505b6208000082161561198057608061197b826b048a170391f7dc42444e8fa2611f47565b901c90505b60008460020b131561199b5761199881600019611f7c565b90505b6119aa64010000000082612355565b156119b65760016119b9565b60005b6107ed9060ff16602083901c6122a2565b600080806000198587098587029250828110838203039150508060001415611a0457600084116119f957600080fd5b508290049050610b11565b808411611a1057600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6006805463ffffffff191663ffffffff83169081179091556040519081527fc806e26fb64e3a95f4b70abf4d87280555696244d01068b5f45b0e515aceb1de906020016106c4565b6001600160a01b038116611ae75760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556000546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec91016106c4565b6000816001600160a01b0316836001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015611b8857600080fd5b505afa158015611b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc091906122e8565b6001600160a01b0316149050801581611c5b5750816001600160a01b0316836001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015611c1757600080fd5b505afa158015611c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4f91906122e8565b6001600160a01b031614155b15610ed95760405163db60809d60e01b815260040160405180910390fd5b600060208284031215611c8b57600080fd5b5035919050565b6001600160a01b03811681146107bf57600080fd5b60008060408385031215611cba57600080fd5b8235611cc581611c92565b9150602083013560ff81168114611cdb57600080fd5b809150509250929050565b600060208284031215611cf857600080fd5b8135610b1181611c92565b60008060408385031215611d1657600080fd5b8235611d2181611c92565b946020939093013593505050565b60008060408385031215611d4257600080fd5b8235611d4d81611c92565b91506020830135611cdb81611c92565b8060060b81146107bf57600080fd5b600080600060608486031215611d8157600080fd5b833592506020840135611d9381611d5d565b929592945050506040919091013590565b600080600060608486031215611db957600080fd5b83356001600160801b0381168114611dd057600080fd5b92506020840135611d9381611d5d565b803563ffffffff81168114611df457600080fd5b919050565b600060208284031215611e0b57600080fd5b610b1182611de0565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e5357611e53611e14565b604052919050565b600067ffffffffffffffff821115611e7557611e75611e14565b5060051b60200190565b60008060408385031215611e9257600080fd5b8235611e9d81611c92565b915060208381013567ffffffffffffffff811115611eba57600080fd5b8401601f81018613611ecb57600080fd5b8035611ede611ed982611e5b565b611e2a565b81815260059190911b82018301908381019088831115611efd57600080fd5b928401925b82841015611f2257611f1384611de0565b82529284019290840190611f02565b80955050505050509250929050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615611f6157611f61611f31565b500290565b634e487b7160e01b600052601260045260246000fd5b600082611f8b57611f8b611f66565b500490565b634e487b7160e01b600052603260045260246000fd5b600082821015611fb857611fb8611f31565b500390565b600181815b80851115611ff8578160001904821115611fde57611fde611f31565b80851615611feb57918102915b93841c9390800290611fc2565b509250929050565b60008261200f57506001610ed9565b8161201c57506000610ed9565b8160018114612032576002811461203c57612058565b6001915050610ed9565b60ff84111561204d5761204d611f31565b50506001821b610ed9565b5060208310610133831016604e8410600b841016171561207b575081810a610ed9565b6120858383611fbd565b806000190482111561209957612099611f31565b029392505050565b6000610b118383612000565b6020808252825182820181905260009190848201906040850190845b818110156120eb57835163ffffffff16835292840192918401916001016120c9565b50909695505050505050565b600082601f83011261210857600080fd5b81516020612118611ed983611e5b565b82815260059290921b8401810191818101908684111561213757600080fd5b8286015b8481101561215b57805161214e81611c92565b835291830191830161213b565b509695505050505050565b6000806040838503121561217957600080fd5b825167ffffffffffffffff8082111561219157600080fd5b818501915085601f8301126121a557600080fd5b815160206121b5611ed983611e5b565b82815260059290921b840181019181810190898411156121d457600080fd5b948201945b838610156121fb5785516121ec81611d5d565b825294820194908201906121d9565b9188015191965090935050508082111561221457600080fd5b50612221858286016120f7565b9150509250929050565b60008160060b8360060b6000811281667fffffffffffff190183128115161561225657612256611f31565b81667fffffffffffff01831381161561227157612271611f31565b5090039392505050565b60008160060b667fffffffffffff1981141561229957612299611f31565b60000392915050565b600082198211156122b5576122b5611f31565b500190565b6000826122c9576122c9611f66565b600160ff1b8214600019841416156122e3576122e3611f31565b500590565b6000602082840312156122fa57600080fd5b8151610b1181611c92565b60006020828403121561231757600080fd5b5051919050565b6000600160ff1b82141561233457612334611f31565b5060000390565b60008160020b627fffff1981141561229957612299611f31565b60008261236457612364611f66565b50069056fea26469706673582212206c0ca89630f2f91836f9a3a38aeffab856a05a5e99be6e2c445b810e579b461a64736f6c63430008080033", + "devdoc": { + "kind": "dev", + "methods": { + "bonds(address)": { + "params": { + "_keeper": "The address of the keeper to check" + }, + "returns": { + "_amountBonded": "The amount of KP3R the keeper has bonded" + } + }, + "constructor": { + "details": "Oracle pools should use 18 decimals tokens", + "params": { + "_governor": "Address of governor", + "_keep3rV2": "Address of sidechain Keep3r implementation", + "_kp3rWethOracle": "Address of oracle used for KP3R/WETH quote", + "_wethUsdOracle": "Address of oracle used for WETH/USD quote" + } + }, + "getKP3RsAtTick(uint256,int56,uint256)": { + "params": { + "_liquidityAmount": "Amount of liquidity to be converted", + "_tickDifference": "Tick value used to calculate the quote", + "_timeInterval": "Time value used to calculate the quote" + }, + "returns": { + "_kp3rAmount": "Amount of KP3R tokens underlying on the given liquidity" + } + }, + "getPaymentParams(uint256)": { + "params": { + "_bonds": "Amount of bonded KP3R owned by the keeper" + }, + "returns": { + "_boost": "Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R", + "_extraGas": "Amount of extra gas that should be added to the gas spent", + "_oneUsdQuote": "Amount of KP3R tokens equivalent to 1 ETH" + } + }, + "getPoolTokens(address)": { + "params": { + "_pool": "Address of the correspondant pool" + }, + "returns": { + "_token0": "Address of the first token of the pair", + "_token1": "Address of the second token of the pair" + } + }, + "getQuoteAtTick(uint128,int56,uint256)": { + "params": { + "_baseAmount": "Amount of token to be converted", + "_tickDifference": "Tick value used to calculate the quote", + "_timeInterval": "Time value used to calculate the quote" + }, + "returns": { + "_quoteAmount": "Amount of credits deserved for the baseAmount at the tick value" + } + }, + "getRewardAmount(uint256)": { + "params": { + "_gasUsed": "The amount of gas used that will be rewarded" + }, + "returns": { + "_amount": "The amount of KP3R that should be awarded to tx.origin" + } + }, + "getRewardAmountFor(address,uint256)": { + "params": { + "_gasUsed": "The amount of gas used that will be rewarded", + "_keeper": "The address of the keeper to check" + }, + "returns": { + "_kp3r": "The amount of KP3R that should be awarded to the keeper" + } + }, + "getRewardBoostFor(uint256)": { + "details": "If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%", + "params": { + "_bonds": "The amount of KP3R tokens bonded by the keeper" + }, + "returns": { + "_rewardBoost": "The reward boost that corresponds to the keeper" + } + }, + "isKP3RToken0(address)": { + "params": { + "_pool": "Address of the correspondant pool" + }, + "returns": { + "_isKP3RToken0": "Boolean indicating the order of the tokens in the pair" + } + }, + "observe(address,uint32[])": { + "params": { + "_pool": "Address of the pool to observe", + "_secondsAgo": "Array with time references to observe" + }, + "returns": { + "_success": "Boolean indicating if the observe call was succesfull", + "_tickCumulative1": "Cumulative sum of ticks until first time reference", + "_tickCumulative2": "Cumulative sum of ticks until second time reference" + } + }, + "quote(uint256)": { + "details": "This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas", + "params": { + "_eth": "The amount of ETH" + }, + "returns": { + "_amountOut": "The amount of KP3R" + } + }, + "quoteUsdToEth(uint256)": { + "details": "Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R", + "params": { + "_usd": "The amount of USD to quote to ETH" + }, + "returns": { + "_amountOut": "The resulting amount of ETH after quoting the USD" + } + }, + "setKeep3rV2(address)": { + "params": { + "_keep3rV2": "The address of Keep3r V2" + } + }, + "setKp3rWethPool(address)": { + "params": { + "_poolAddress": "The address of the KP3R-WETH pool" + } + }, + "setMaxBoost(uint256)": { + "params": { + "_maxBoost": "The maximum boost multiplier" + } + }, + "setMinBaseFee(uint256)": { + "params": { + "_minBaseFee": "The minimum rewarded gas fee" + } + }, + "setMinBoost(uint256)": { + "params": { + "_minBoost": "The minimum boost multiplier" + } + }, + "setMinPriorityFee(uint256)": { + "params": { + "_minPriorityFee": "The minimum rewarded priority fee" + } + }, + "setOracle(address,address)": { + "details": "The oracle must contain KP3R as either token0 or token1", + "params": { + "_liquidity": "The address of the liquidity", + "_oracle": "The address of the pool used to quote the liquidity from" + } + }, + "setPendingGovernor(address)": { + "params": { + "_pendingGovernor": "Address of the proposed new governor" + } + }, + "setQuoteTwapTime(uint32)": { + "params": { + "_quoteTwapTime": "The twap time for quoting" + } + }, + "setTargetBond(uint256)": { + "params": { + "_targetBond": "The target bond amount" + } + }, + "setWethUsdPool(address,uint8)": { + "details": "The oracle must contain WETH as either token0 or token1", + "params": { + "_poolAddress": "The address of the pool used as oracle", + "_usdDecimals": "The amount of decimals of the USD token paired with ETH" + } + }, + "setWorkExtraGas(uint256)": { + "params": { + "_workExtraGas": "The work extra gas" + } + } + }, + "stateVariables": { + "_USD_BASE_DECIMALS": { + "details": "Amount of decimals in which USD is quoted within the contract" + }, + "oracle": { + "return": "_oracle The address of the observable pool for given liquidity", + "returns": { + "_0": "_oracle The address of the observable pool for given liquidity" + } + }, + "wethUSDPool": { + "returns": { + "isWETHToken0": "True if calling the token0 method of the pool returns the WETH token address", + "poolAddress": "Address of the pool", + "usdDecimals": "The amount of decimals of the USD token paired with ETH" + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidAddress()": [ + { + "notice": "Thrown if an address is invalid" + } + ], + "InvalidAmount()": [ + { + "notice": "Thrown if an amount is invalid" + } + ], + "InvalidOraclePool()": [ + { + "notice": "Throws when pool does not have KP3R as token0 nor token1" + } + ], + "LengthMismatch()": [ + { + "notice": "Thrown if the lengths of a set of lists mismatch" + } + ], + "LiquidityPairInvalid()": [ + { + "notice": "Throws when none of the tokens in the liquidity pair is KP3R" + } + ], + "OnlyGovernor()": [ + { + "notice": "Thrown if a non-governor user tries to call a OnlyGovernor function" + } + ], + "OnlyPendingGovernor()": [ + { + "notice": "Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function" + } + ], + "ZeroAddress()": [ + { + "notice": "Thrown if an address is the zero address" + } + ], + "ZeroAmount()": [ + { + "notice": "Thrown if an amount is zero" + } + ] + }, + "events": { + "Keep3rV2Change(address)": { + "notice": "Emitted when the Keep3r V2 address is changed" + }, + "Kp3rWethPoolChange(address,bool)": { + "notice": "Emitted when the kp3r weth pool is changed" + }, + "MaxBoostChange(uint256)": { + "notice": "Emitted when the maximum boost multiplier is changed" + }, + "MinBaseFeeChange(uint256)": { + "notice": "Emitted when minimum rewarded gas fee is changed" + }, + "MinBoostChange(uint256)": { + "notice": "Emitted when the minimum boost multiplier is changed" + }, + "MinPriorityFeeChange(uint256)": { + "notice": "Emitted when minimum rewarded priority fee is changed" + }, + "OracleSet(address,address)": { + "notice": "The oracle for a liquidity has been saved" + }, + "PendingGovernorAccepted(address)": { + "notice": "Emitted when a new governor is set" + }, + "PendingGovernorSet(address,address)": { + "notice": "Emitted when a new pending governor is set" + }, + "QuoteTwapTimeChange(uint32)": { + "notice": "Emitted when the quote twap time is changed" + }, + "TargetBondChange(uint256)": { + "notice": "Emitted when the target bond amount is changed" + }, + "WethUSDPoolChange(address,bool,uint8)": { + "notice": "Emitted when the WETH USD pool is changed" + }, + "WorkExtraGasChange(uint256)": { + "notice": "Emitted when the work extra gas amount is changed" + } + }, + "kind": "user", + "methods": { + "BOOST_BASE()": { + "notice": "The boost base used to calculate the boost rewards for the keeper" + }, + "KP3R()": { + "notice": "Address of KP3R token" + }, + "WETH()": { + "notice": "Ethereum mainnet WETH address used for quoting references" + }, + "acceptPendingGovernor()": { + "notice": "Allows a proposed governor to accept the governance" + }, + "bonds(address)": { + "notice": "Uses valid wKP3R address from Keep3rSidechain to query keeper bonds" + }, + "getKP3RsAtTick(uint256,int56,uint256)": { + "notice": "Given a tick and a liquidity amount, calculates the underlying KP3R tokens" + }, + "getPaymentParams(uint256)": { + "notice": "Get multiplier, quote, and extra, in order to calculate keeper payment" + }, + "getPoolTokens(address)": { + "notice": "Given a pool address, returns the underlying tokens of the pair" + }, + "getQuoteAtTick(uint128,int56,uint256)": { + "notice": "Given a tick and a token amount, calculates the output in correspondant token" + }, + "getRewardAmount(uint256)": { + "notice": "Calculates the reward (in KP3R) that corresponds to tx.origin for using gas" + }, + "getRewardAmountFor(address,uint256)": { + "notice": "Calculates the reward (in KP3R) that corresponds to a keeper for using gas" + }, + "getRewardBoostFor(uint256)": { + "notice": "Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded" + }, + "isKP3RToken0(address)": { + "notice": "Defines the order of the tokens in the pair for twap calculations" + }, + "keep3rV2()": { + "notice": "Address of Keep3r V2" + }, + "kp3rWethPool()": { + "notice": "KP3R-WETH pool that is being used as oracle" + }, + "maxBoost()": { + "notice": "The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE" + }, + "minBaseFee()": { + "notice": "The minimum base fee that is used to calculate keeper rewards" + }, + "minBoost()": { + "notice": "The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE" + }, + "minPriorityFee()": { + "notice": "The minimum priority fee that is also rewarded for keepers" + }, + "observe(address,uint32[])": { + "notice": "Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment" + }, + "quote(uint256)": { + "notice": "Calculates the amount of KP3R that corresponds to the ETH passed into the function" + }, + "quoteTwapTime()": { + "notice": "The twap time for quoting" + }, + "quoteUsdToEth(uint256)": { + "notice": "Quotes USD to ETH" + }, + "setKeep3rV2(address)": { + "notice": "Sets the Keep3r V2 address" + }, + "setKp3rWethPool(address)": { + "notice": "Sets KP3R-WETH pool" + }, + "setMaxBoost(uint256)": { + "notice": "Sets the maximum boost multiplier" + }, + "setMinBaseFee(uint256)": { + "notice": "Sets the minimum rewarded gas fee" + }, + "setMinBoost(uint256)": { + "notice": "Sets the minimum boost multiplier" + }, + "setMinPriorityFee(uint256)": { + "notice": "Sets the minimum rewarded gas priority fee" + }, + "setOracle(address,address)": { + "notice": "Sets an oracle for a given liquidity" + }, + "setPendingGovernor(address)": { + "notice": "Allows a governor to propose a new governor" + }, + "setQuoteTwapTime(uint32)": { + "notice": "Sets the quote twap time" + }, + "setTargetBond(uint256)": { + "notice": "Sets the target bond amount" + }, + "setWethUsdPool(address,uint8)": { + "notice": "Sets an oracle for querying WETH/USD quote" + }, + "setWorkExtraGas(uint256)": { + "notice": "Sets the work extra gas amount" + }, + "targetBond()": { + "notice": "The targeted amount of bonded KP3Rs to max-up reward multiplier For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get the maximum boost possible in his rewards, if it's less, the reward boost will be proportional" + }, + "wethUSDPool()": { + "notice": "WETH-USD pool that is being used as oracle" + }, + "workExtraGas()": { + "notice": "The amount of unaccounted gas that is going to be added to keeper payments" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 82, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "governor", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 85, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "pendingGovernor", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 3288, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "minBoost", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 3293, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "maxBoost", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 3298, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "targetBond", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 3303, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "workExtraGas", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 3308, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "quoteTwapTime", + "offset": 0, + "slot": "6", + "type": "t_uint32" + }, + { + "astId": 3313, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "minBaseFee", + "offset": 0, + "slot": "7", + "type": "t_uint256" + }, + { + "astId": 3318, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "minPriorityFee", + "offset": 0, + "slot": "8", + "type": "t_uint256" + }, + { + "astId": 3322, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "keep3rV2", + "offset": 0, + "slot": "9", + "type": "t_address" + }, + { + "astId": 3327, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "kp3rWethPool", + "offset": 0, + "slot": "10", + "type": "t_struct(Kp3rWethOraclePool)12965_storage" + }, + { + "astId": 9888, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "oracle", + "offset": 0, + "slot": "11", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 9893, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "wethUSDPool", + "offset": 0, + "slot": "12", + "type": "t_struct(WethUsdOraclePool)15476_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_struct(Kp3rWethOraclePool)12965_storage": { + "encoding": "inplace", + "label": "struct IKeep3rHelperParameters.Kp3rWethOraclePool", + "members": [ + { + "astId": 12962, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "poolAddress", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 12964, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "isKP3RToken0", + "offset": 20, + "slot": "0", + "type": "t_bool" + } + ], + "numberOfBytes": "32" + }, + "t_struct(WethUsdOraclePool)15476_storage": { + "encoding": "inplace", + "label": "struct IKeep3rHelperSidechain.WethUsdOraclePool", + "members": [ + { + "astId": 15471, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "poolAddress", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 15473, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "isWETHToken0", + "offset": 20, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 15475, + "contract": "solidity/contracts/sidechain/Keep3rHelperSidechain.sol:Keep3rHelperSidechain", + "label": "usdDecimals", + "offset": 21, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/Keep3rSidechain.json b/deployments/polygon/Keep3rSidechain.json new file mode 100644 index 0000000..eb374c1 --- /dev/null +++ b/deployments/polygon/Keep3rSidechain.json @@ -0,0 +1,4072 @@ +{ + "address": "0x745a50320B6eB8FF281f1664Fc6713991661B129", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "internalType": "address", + "name": "_keep3rHelperSidechain", + "type": "address" + }, + { + "internalType": "address", + "name": "_wrappedKP3R", + "type": "address" + }, + { + "internalType": "address", + "name": "_keep3rEscrow", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AlreadyAJob", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyAKeeper", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyDisputed", + "type": "error" + }, + { + "inputs": [], + "name": "BondsLocked", + "type": "error" + }, + { + "inputs": [], + "name": "BondsUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "Deprecated", + "type": "error" + }, + { + "inputs": [], + "name": "Disputed", + "type": "error" + }, + { + "inputs": [], + "name": "DisputerExistent", + "type": "error" + }, + { + "inputs": [], + "name": "DisputerUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "GasNotInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientFunds", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientJobTokenCredits", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAddress", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "JobAlreadyAdded", + "type": "error" + }, + { + "inputs": [], + "name": "JobDisputed", + "type": "error" + }, + { + "inputs": [], + "name": "JobLiquidityInsufficient", + "type": "error" + }, + { + "inputs": [], + "name": "JobLiquidityLessThanMin", + "type": "error" + }, + { + "inputs": [], + "name": "JobLiquidityUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "JobMigrationImpossible", + "type": "error" + }, + { + "inputs": [], + "name": "JobMigrationLocked", + "type": "error" + }, + { + "inputs": [], + "name": "JobMigrationUnavailable", + "type": "error" + }, + { + "inputs": [], + "name": "JobTokenCreditsLocked", + "type": "error" + }, + { + "inputs": [], + "name": "JobTokenInsufficient", + "type": "error" + }, + { + "inputs": [], + "name": "JobTokenUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "JobUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "JobUnavailable", + "type": "error" + }, + { + "inputs": [], + "name": "LengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidityPairApproved", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidityPairUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidityPairUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "MinRewardPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "NotDisputed", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyDisputer", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyJobOwner", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingJobOwner", + "type": "error" + }, + { + "inputs": [], + "name": "OnlySlasher", + "type": "error" + }, + { + "inputs": [], + "name": "SlasherExistent", + "type": "error" + }, + { + "inputs": [], + "name": "SlasherUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "TokenUnallowed", + "type": "error" + }, + { + "inputs": [], + "name": "UnbondsLocked", + "type": "error" + }, + { + "inputs": [], + "name": "UnbondsUnexistent", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_bond", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Activation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_bondTime", + "type": "uint256" + } + ], + "name": "BondTimeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_bonding", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Bonding", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_jobOrKeeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_disputer", + "type": "address" + } + ], + "name": "Dispute", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_disputer", + "type": "address" + } + ], + "name": "DisputerAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_disputer", + "type": "address" + } + ], + "name": "DisputerRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "DustSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "FeeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_inflationPeriod", + "type": "uint256" + } + ], + "name": "InflationPeriodChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_jobOwner", + "type": "address" + } + ], + "name": "JobAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_fromJob", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_toJob", + "type": "address" + } + ], + "name": "JobMigrationRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_fromJob", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_toJob", + "type": "address" + } + ], + "name": "JobMigrationSuccessful", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "JobOwnershipAssent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_pendingOwner", + "type": "address" + } + ], + "name": "JobOwnershipChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_slasher", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "JobSlashLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_slasher", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "JobSlashToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_keep3rHelper", + "type": "address" + } + ], + "name": "Keep3rHelperChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_keep3rV1", + "type": "address" + } + ], + "name": "Keep3rV1Change", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_keep3rV1Proxy", + "type": "address" + } + ], + "name": "Keep3rV1ProxyChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_slasher", + "type": "address" + } + ], + "name": "KeeperRevoke", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_slasher", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "KeeperSlash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_gasLeft", + "type": "uint256" + } + ], + "name": "KeeperValidation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_credit", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_payment", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_gasLeft", + "type": "uint256" + } + ], + "name": "KeeperWork", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "LiquidityAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_liquidity", + "type": "address" + } + ], + "name": "LiquidityApproval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rewardedAt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_currentCredits", + "type": "uint256" + } + ], + "name": "LiquidityCreditsForced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rewardedAt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_currentCredits", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_periodCredits", + "type": "uint256" + } + ], + "name": "LiquidityCreditsReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_liquidityMinimum", + "type": "uint256" + } + ], + "name": "LiquidityMinimumChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_liquidity", + "type": "address" + } + ], + "name": "LiquidityRevocation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "LiquidityWithdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newGovernor", + "type": "address" + } + ], + "name": "PendingGovernorAccepted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_pendingGovernor", + "type": "address" + } + ], + "name": "PendingGovernorSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_jobOrKeeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_resolver", + "type": "address" + } + ], + "name": "Resolve", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_rewardPeriodTime", + "type": "uint256" + } + ], + "name": "RewardPeriodTimeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_slasher", + "type": "address" + } + ], + "name": "SlasherAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_slasher", + "type": "address" + } + ], + "name": "SlasherRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "TokenCreditAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "TokenCreditWithdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_unbondTime", + "type": "uint256" + } + ], + "name": "UnbondTimeChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeperOrJob", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_unbonding", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Unbonding", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_bond", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "ETH_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_fromJob", + "type": "address" + }, + { + "internalType": "address", + "name": "_toJob", + "type": "address" + } + ], + "name": "acceptJobMigration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + } + ], + "name": "acceptJobOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "acceptPendingGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bonding", + "type": "address" + } + ], + "name": "activate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_disputer", + "type": "address" + } + ], + "name": "addDisputer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + } + ], + "name": "addJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "addLiquidityToJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_slasher", + "type": "address" + } + ], + "name": "addSlasher", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "addTokenCreditsToJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + } + ], + "name": "approveLiquidity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "approvedLiquidities", + "outputs": [ + { + "internalType": "address[]", + "name": "_list", + "type": "address[]" + } + ], + "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": [], + "name": "bondTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_payment", + "type": "uint256" + } + ], + "name": "bondedPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "bonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "canActivateAfter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "canWithdrawAfter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "changeJobOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "directTokenPayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_jobOrKeeper", + "type": "address" + } + ], + "name": "dispute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "disputers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "disputes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "firstSeen", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "forceLiquidityCreditsToJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "hasBonded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inflationPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "address", + "name": "_bond", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minBond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_earned", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_age", + "type": "uint256" + } + ], + "name": "isBondedKeeper", + "outputs": [ + { + "internalType": "bool", + "name": "_isBondedKeeper", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + } + ], + "name": "isKeeper", + "outputs": [ + { + "internalType": "bool", + "name": "_isKeeper", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + } + ], + "name": "jobLiquidityCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "_liquidityCredits", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "jobOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "jobPendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + } + ], + "name": "jobPeriodCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "_periodCredits", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "jobTokenCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "jobTokenCreditsAddedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "jobs", + "outputs": [ + { + "internalType": "address[]", + "name": "_list", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keep3rHelper", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keep3rV1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keep3rV1Proxy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keepers", + "outputs": [ + { + "internalType": "address[]", + "name": "_list", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "liquidityAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidityMinimum", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_fromJob", + "type": "address" + }, + { + "internalType": "address", + "name": "_toJob", + "type": "address" + } + ], + "name": "migrateJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + } + ], + "name": "observeLiquidity", + "outputs": [ + { + "components": [ + { + "internalType": "int56", + "name": "current", + "type": "int56" + }, + { + "internalType": "int56", + "name": "difference", + "type": "int56" + }, + { + "internalType": "uint256", + "name": "period", + "type": "uint256" + } + ], + "internalType": "struct IKeep3rJobFundableLiquidity.TickCache", + "name": "_tickCache", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pendingBonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingGovernor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pendingJobMigrations", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pendingUnbonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "quoteLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "_periodCredits", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_disputer", + "type": "address" + } + ], + "name": "removeDisputer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_slasher", + "type": "address" + } + ], + "name": "removeSlasher", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_jobOrKeeper", + "type": "address" + } + ], + "name": "resolve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + } + ], + "name": "revoke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + } + ], + "name": "revokeLiquidity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPeriodTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "sendDust", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bondTime", + "type": "uint256" + } + ], + "name": "setBondTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_inflationPeriod", + "type": "uint256" + } + ], + "name": "setInflationPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rHelper", + "type": "address" + } + ], + "name": "setKeep3rHelper", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rV1", + "type": "address" + } + ], + "name": "setKeep3rV1", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keep3rV1Proxy", + "type": "address" + } + ], + "name": "setKeep3rV1Proxy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_liquidityMinimum", + "type": "uint256" + } + ], + "name": "setLiquidityMinimum", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pendingGovernor", + "type": "address" + } + ], + "name": "setPendingGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rewardPeriodTime", + "type": "uint256" + } + ], + "name": "setRewardPeriodTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_unbondTime", + "type": "uint256" + } + ], + "name": "setUnbondTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "address", + "name": "_bonded", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_bondAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_unbondAmount", + "type": "uint256" + } + ], + "name": "slash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "slashLiquidityFromJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "slashTokenFromJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "slashers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + } + ], + "name": "totalJobCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "_credits", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bonding", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "unbond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "unbondLiquidityFromJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unbondTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "virtualReserves", + "outputs": [ + { + "internalType": "int256", + "name": "_virtualReserves", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bonding", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_liquidity", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "withdrawLiquidityFromJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_job", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "withdrawTokenCreditsFromJob", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "workCompleted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "worked", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_usdPerGasUnit", + "type": "uint256" + } + ], + "name": "worked", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "workedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xb3c66ef8d19268f92ca3f512a6b943d6bea80e80a0ff9b67f880c9024e6fa6bf", + "receipt": { + "to": null, + "from": "0xA825fc60eB4B1269F1dF0f6E574b953d2b5f7EFc", + "contractAddress": "0x745a50320B6eB8FF281f1664Fc6713991661B129", + "transactionIndex": 43, + "gasUsed": "5586440", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000040000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000020000000001000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000800000000100000", + "blockHash": "0xa4cfccd859c40c221a70df14a66665eb6046d38784222cfa163cd7fddc7ec31c", + "transactionHash": "0xb3c66ef8d19268f92ca3f512a6b943d6bea80e80a0ff9b67f880c9024e6fa6bf", + "logs": [ + { + "transactionIndex": 43, + "blockNumber": 39514687, + "transactionHash": "0xb3c66ef8d19268f92ca3f512a6b943d6bea80e80a0ff9b67f880c9024e6fa6bf", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000a825fc60eb4b1269f1df0f6e574b953d2b5f7efc", + "0x0000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0" + ], + "data": "0x00000000000000000000000000000000000000000000000002b3b1372a7273d800000000000000000000000000000000000000000000000015651525379948d70000000000000000000000000000000000000000000007431d5fa39ee2289fd500000000000000000000000000000000000000000000000012b163ee0d26d4ff000000000000000000000000000000000000000000000743201354d60c9b13ad", + "logIndex": 159, + "blockHash": "0xa4cfccd859c40c221a70df14a66665eb6046d38784222cfa163cd7fddc7ec31c" + } + ], + "blockNumber": 39514687, + "cumulativeGasUsed": "11608099", + "status": 1, + "byzantium": true + }, + "args": [ + "0x9A040a31bc38919D50FD740973dBB6F8fdee1426", + "0x832accE332B81262C028B2F800D1D53C8aEE12f4", + "0x4a2bE2075588BcE6A7E072574698a7DbbAc39b08", + "0xDBc6501645407CF4D3af383FbD5Bf7586b135d81" + ], + "numDeployments": 1, + "solcInputHash": "3a869c3b827b38468356d50761a61b47", + "metadata": "{\"compiler\":{\"version\":\"0.8.8+commit.dddeac2f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rHelperSidechain\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_wrappedKP3R\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keep3rEscrow\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyAJob\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyAKeeper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Deprecated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Disputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DisputerUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasNotInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientJobTokenCredits\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityLessThanMin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobLiquidityUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationImpossible\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobMigrationUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenCreditsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenInsufficient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobTokenUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JobUnavailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityPairUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MinRewardPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotDisputed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDisputer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingJobOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySlasher\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherExistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SlasherUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenUnallowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnbondsUnexistent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Activation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"BondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Bonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"Dispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"DisputerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"DustSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"FeeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"InflationPeriodChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOwner\",\"type\":\"address\"}],\"name\":\"JobAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"JobMigrationSuccessful\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipAssent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_pendingOwner\",\"type\":\"address\"}],\"name\":\"JobOwnershipChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashLiquidity\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"JobSlashToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"Keep3rHelperChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"Keep3rV1Change\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"Keep3rV1ProxyChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"KeeperRevoke\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"KeeperSlash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperValidation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_credit\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gasLeft\",\"type\":\"uint256\"}],\"name\":\"KeeperWork\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityApproval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsForced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardedAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_currentCredits\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"name\":\"LiquidityCreditsReward\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"LiquidityMinimumChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"LiquidityRevocation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_resolver\",\"type\":\"address\"}],\"name\":\"Resolve\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"RewardPeriodTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"SlasherRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_provider\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditAddition\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"TokenCreditWithdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"UnbondTimeChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeperOrJob\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_unbonding\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Unbonding\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ETH_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"acceptJobMigration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"acceptJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"activate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"addDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"addJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addLiquidityToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"addSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"addTokenCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"approveLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"approvedLiquidities\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"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\":[],\"name\":\"bondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_payment\",\"type\":\"uint256\"}],\"name\":\"bondedPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canActivateAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canWithdrawAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"changeJobOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"directTokenPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"dispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"firstSeen\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"forceLiquidityCreditsToJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"hasBonded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"inflationPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bond\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minBond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_earned\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_age\",\"type\":\"uint256\"}],\"name\":\"isBondedKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isBondedKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"isKeeper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isKeeper\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobLiquidityCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobPendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"jobPeriodCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"jobTokenCreditsAddedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"jobs\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rHelper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keep3rV1Proxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"keepers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_list\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"liquidityAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidityMinimum\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fromJob\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_toJob\",\"type\":\"address\"}],\"name\":\"migrateJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"observeLiquidity\",\"outputs\":[{\"components\":[{\"internalType\":\"int56\",\"name\":\"current\",\"type\":\"int56\"},{\"internalType\":\"int56\",\"name\":\"difference\",\"type\":\"int56\"},{\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"}],\"internalType\":\"struct IKeep3rJobFundableLiquidity.TickCache\",\"name\":\"_tickCache\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingGovernor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingJobMigrations\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingUnbonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"quoteLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_periodCredits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_disputer\",\"type\":\"address\"}],\"name\":\"removeDisputer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_slasher\",\"type\":\"address\"}],\"name\":\"removeSlasher\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_jobOrKeeper\",\"type\":\"address\"}],\"name\":\"resolve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"}],\"name\":\"revoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"}],\"name\":\"revokeLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardPeriodTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"rewardedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"sendDust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_bondTime\",\"type\":\"uint256\"}],\"name\":\"setBondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_inflationPeriod\",\"type\":\"uint256\"}],\"name\":\"setInflationPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rHelper\",\"type\":\"address\"}],\"name\":\"setKeep3rHelper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1\",\"type\":\"address\"}],\"name\":\"setKeep3rV1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keep3rV1Proxy\",\"type\":\"address\"}],\"name\":\"setKeep3rV1Proxy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_liquidityMinimum\",\"type\":\"uint256\"}],\"name\":\"setLiquidityMinimum\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pendingGovernor\",\"type\":\"address\"}],\"name\":\"setPendingGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardPeriodTime\",\"type\":\"uint256\"}],\"name\":\"setRewardPeriodTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_unbondTime\",\"type\":\"uint256\"}],\"name\":\"setUnbondTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_bonded\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_bondAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_unbondAmount\",\"type\":\"uint256\"}],\"name\":\"slash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"slashTokenFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"slashers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"}],\"name\":\"totalJobCredits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_credits\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"unbondLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unbondTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"virtualReserves\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"_virtualReserves\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bonding\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_liquidity\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawLiquidityFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_job\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdrawTokenCreditsFromJob\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workCompleted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"worked\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_keeper\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_usdPerGasUnit\",\"type\":\"uint256\"}],\"name\":\"worked\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"workedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptJobMigration(address,address)\":{\"details\":\"Unbond/withdraw process doesn't get migrated\",\"params\":{\"_fromJob\":\"The address of the job that requested to migrate\",\"_toJob\":\"The address to which the job wants to migrate to\"}},\"acceptJobOwnership(address)\":{\"params\":{\"_job\":\"The address of the job\"}},\"activate(address)\":{\"params\":{\"_bonding\":\"The asset being activated as bond collateral\"}},\"addJob(address)\":{\"params\":{\"_job\":\"Address of the contract for which work should be performed\"}},\"addLiquidityToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity tokens to add\",\"_job\":\"The address of the job to assign liquidity to\",\"_liquidity\":\"The liquidity being added\"}},\"addTokenCreditsToJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of credit being added\",\"_job\":\"The address of the job being credited\",\"_token\":\"The address of the token being credited\"}},\"approveLiquidity(address)\":{\"details\":\"Function should be called after setting an oracle in Keep3rHelperSidechain\",\"params\":{\"_liquidity\":\"Address of the liquidity token being approved\"}},\"approvedLiquidities()\":{\"returns\":{\"_list\":\"An array of addresses with all the approved liquidity pairs\"}},\"bond(address,uint256)\":{\"params\":{\"_amount\":\"The amount of bonding asset being bonded\",\"_bonding\":\"The asset being bonded\"}},\"bondedPayment(address,uint256)\":{\"details\":\"Pays the keeper that performs the work with KP3R\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\",\"_payment\":\"The reward that should be allocated for the job\"}},\"changeJobOwnership(address,address)\":{\"params\":{\"_job\":\"The address of the job\",\"_newOwner\":\"The address of the proposed new owner\"}},\"constructor\":{\"params\":{\"_governor\":\"Address of governor\",\"_keep3rEscrow\":\"Address of sidechain Keep3rEscrow\",\"_keep3rHelperSidechain\":\"Address of sidechain Keep3rHelper\",\"_wrappedKP3R\":\"Address of wrapped KP3R implementation\"}},\"directTokenPayment(address,address,uint256)\":{\"details\":\"Pays the keeper that performs the work with a specific token\",\"params\":{\"_amount\":\"The reward that should be allocated\",\"_keeper\":\"Address of the keeper that performed the work\",\"_token\":\"The asset being awarded to the keeper\"}},\"dispute(address)\":{\"params\":{\"_jobOrKeeper\":\"The address in dispute\"}},\"forceLiquidityCreditsToJob(address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity credits to gift\",\"_job\":\"The address of the job being credited\"}},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"details\":\"Should be used for protected functions\",\"params\":{\"_age\":\"The minimum keeper age required\",\"_bond\":\"The bond token being evaluated\",\"_earned\":\"The minimum funds earned in the keepers lifetime\",\"_keeper\":\"The keeper to check\",\"_minBond\":\"The minimum amount of bonded tokens\"},\"returns\":{\"_isBondedKeeper\":\"Whether the `_keeper` meets the given requirements\"}},\"isKeeper(address)\":{\"details\":\"Can be used for general (non critical) functions\",\"params\":{\"_keeper\":\"The keeper being investigated\"},\"returns\":{\"_isKeeper\":\"Whether the address passed as a parameter is a keeper or not\"}},\"jobLiquidityCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the liquidity credits\"},\"returns\":{\"_liquidityCredits\":\"The liquidity credits of a given job\"}},\"jobPeriodCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the period credits\"},\"returns\":{\"_periodCredits\":\"The credits the given job has at the current period\"}},\"jobs()\":{\"returns\":{\"_list\":\"Array with all the jobs in _jobs\"}},\"keepers()\":{\"returns\":{\"_list\":\"Array with all the keepers in _keepers\"}},\"migrateJob(address,address)\":{\"params\":{\"_fromJob\":\"The address of the job that is requesting to migrate\",\"_toJob\":\"The address at which the job is requesting to migrate\"}},\"observeLiquidity(address)\":{\"params\":{\"_liquidity\":\"Address of the liquidity token being observed\"}},\"quoteLiquidity(address,uint256)\":{\"details\":\"_periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\",\"params\":{\"_amount\":\"The amount of liquidity to provide\",\"_liquidity\":\"The address of the liquidity to provide\"},\"returns\":{\"_periodCredits\":\"The amount of KP3R periodically minted for the given liquidity\"}},\"resolve(address)\":{\"params\":{\"_jobOrKeeper\":\"The address cleared\"}},\"revoke(address)\":{\"params\":{\"_keeper\":\"The address being slashed\"}},\"revokeLiquidity(address)\":{\"params\":{\"_liquidity\":\"The liquidity no longer accepted\"}},\"sendDust(address,uint256,address)\":{\"params\":{\"_amount\":\"The amont of the token that will be transferred\",\"_to\":\"The address that will receive the idle funds\",\"_token\":\"The token that will be transferred\"}},\"setBondTime(uint256)\":{\"params\":{\"_bond\":\"The new bond time\"}},\"setFee(uint256)\":{\"params\":{\"_fee\":\"The new fee\"}},\"setInflationPeriod(uint256)\":{\"params\":{\"_inflationPeriod\":\"The new inflation period\"}},\"setKeep3rHelper(address)\":{\"params\":{\"_keep3rHelper\":\"The Keep3rHelper address\"}},\"setKeep3rV1(address)\":{\"params\":{\"_keep3rV1\":\"The Keep3rV1 address\"}},\"setKeep3rV1Proxy(address)\":{\"params\":{\"_keep3rV1Proxy\":\"The Keep3rV1Proxy address\"}},\"setLiquidityMinimum(uint256)\":{\"params\":{\"_liquidityMinimum\":\"The new minimum amount of liquidity\"}},\"setPendingGovernor(address)\":{\"params\":{\"_pendingGovernor\":\"Address of the proposed new governor\"}},\"setRewardPeriodTime(uint256)\":{\"params\":{\"_rewardPeriodTime\":\"The new amount of time required to pass between rewards\"}},\"setUnbondTime(uint256)\":{\"params\":{\"_unbond\":\"The new unbond time\"}},\"slash(address,address,uint256,uint256)\":{\"params\":{\"_bondAmount\":\"The bonded amount being slashed\",\"_bonded\":\"The asset being slashed\",\"_keeper\":\"The address being slashed\",\"_unbondAmount\":\"The pending unbond amount being slashed\"}},\"slashLiquidityFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of liquidity that will be slashed\",\"_job\":\"The address being slashed\",\"_liquidity\":\"The address of the liquidity that will be slashed\"}},\"slashTokenFromJob(address,address,uint256)\":{\"params\":{\"_amount\":\"The amount of the token that will be slashed\",\"_job\":\"The address of the job from which the token will be slashed\",\"_token\":\"The address of the token that will be slashed\"}},\"totalJobCredits(address)\":{\"params\":{\"_job\":\"The address of the job of which we want to know the total credits\"},\"returns\":{\"_credits\":\"The total credits of the given job\"}},\"unbond(address,uint256)\":{\"params\":{\"_amount\":\"Allows for partial unbonding\",\"_bonding\":\"The asset being unbonded\"}},\"unbondLiquidityFromJob(address,address,uint256)\":{\"details\":\"Can only be called by the job's owner\",\"params\":{\"_amount\":\"The amount of liquidity being removed\",\"_job\":\"The address of the job being unbonded from\",\"_liquidity\":\"The liquidity being unbonded\"}},\"virtualReserves()\":{\"returns\":{\"_virtualReserves\":\"The surplus amount of wKP3Rs in escrow contract\"}},\"withdraw(address)\":{\"params\":{\"_bonding\":\"The asset to withdraw from the bonding pool\"}},\"withdrawLiquidityFromJob(address,address,address)\":{\"params\":{\"_job\":\"The address of the job being withdrawn from\",\"_liquidity\":\"The liquidity being withdrawn\",\"_receiver\":\"The address that will receive the withdrawn liquidity\"}},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"params\":{\"_amount\":\"The amount of token to be withdrawn\",\"_job\":\"The address of the job from which the credits are withdrawn\",\"_receiver\":\"The user that will receive tokens\",\"_token\":\"The address of the token being withdrawn\"}},\"worked(address)\":{\"details\":\"Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\"},\"worked(address,uint256)\":{\"details\":\"Uses a USD per gas unit payment mechanism\",\"params\":{\"_keeper\":\"Address of the keeper that performed the work\",\"_usdPerGasUnit\":\"Units of USD (in wei) per gas unit that should be rewarded to the keeper\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"AlreadyAJob()\":[{\"notice\":\"Throws when the address that is trying to register as a job is already a job\"}],\"AlreadyAKeeper()\":[{\"notice\":\"Throws when the address that is trying to register as a keeper is already a keeper\"}],\"AlreadyDisputed()\":[{\"notice\":\"Throws when a job or keeper is already disputed\"}],\"BondsLocked()\":[{\"notice\":\"Throws if the time required to bond an asset has not passed yet\"}],\"BondsUnexistent()\":[{\"notice\":\"Throws if there are no bonded assets\"}],\"Deprecated()\":[{\"notice\":\"Throws when job contract calls deprecated worked(address) function\"}],\"Disputed()\":[{\"notice\":\"Throws if either a job or a keeper is disputed\"}],\"DisputerExistent()\":[{\"notice\":\"Throws if the address is already a registered disputer\"}],\"DisputerUnexistent()\":[{\"notice\":\"Throws if caller is not a registered disputer\"}],\"GasNotInitialized()\":[{\"notice\":\"Throws if work method was called without calling isKeeper or isBondedKeeper\"}],\"InsufficientFunds()\":[{\"notice\":\"Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\"}],\"InsufficientJobTokenCredits()\":[{\"notice\":\"Throws when the user tries to withdraw more tokens than it has\"}],\"InvalidAddress()\":[{\"notice\":\"Thrown if an address is invalid\"}],\"InvalidAmount()\":[{\"notice\":\"Thrown if an amount is invalid\"}],\"JobAlreadyAdded()\":[{\"notice\":\"Throws when trying to add a job that has already been added\"}],\"JobDisputed()\":[{\"notice\":\"Throws when an action that requires an undisputed job is applied on a disputed job\"}],\"JobLiquidityInsufficient()\":[{\"notice\":\"Throws when trying to remove more liquidity than the job has\"}],\"JobLiquidityLessThanMin()\":[{\"notice\":\"Throws when trying to add less liquidity than the minimum liquidity required\"}],\"JobLiquidityUnexistent()\":[{\"notice\":\"Throws when the job doesn't have the requested liquidity\"}],\"JobMigrationImpossible()\":[{\"notice\":\"Throws when the address of the job that requests to migrate wants to migrate to its same address\"}],\"JobMigrationLocked()\":[{\"notice\":\"Throws when cooldown between migrations has not yet passed\"}],\"JobMigrationUnavailable()\":[{\"notice\":\"Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\"}],\"JobTokenCreditsLocked()\":[{\"notice\":\"Throws when the token withdraw cooldown has not yet passed\"}],\"JobTokenInsufficient()\":[{\"notice\":\"Throws when someone tries to slash more tokens than the job has\"}],\"JobTokenUnexistent()\":[{\"notice\":\"Throws when the token trying to be slashed doesn't exist\"}],\"JobUnapproved()\":[{\"notice\":\"Throws if the address claiming to be a job is not in the list of approved jobs\"}],\"JobUnavailable()\":[{\"notice\":\"Throws when an address is passed as a job, but that address is not a job\"}],\"LengthMismatch()\":[{\"notice\":\"Thrown if the lengths of a set of lists mismatch\"}],\"LiquidityPairApproved()\":[{\"notice\":\"Throws when the liquidity being approved has already been approved\"}],\"LiquidityPairUnapproved()\":[{\"notice\":\"Throws when trying to add liquidity to an unapproved pool\"}],\"LiquidityPairUnexistent()\":[{\"notice\":\"Throws when the liquidity being removed has not been approved\"}],\"MinRewardPeriod()\":[{\"notice\":\"Throws if the reward period is less than the minimum reward period time\"}],\"NotDisputed()\":[{\"notice\":\"Throws when a job or keeper is not disputed and someone tries to resolve the dispute\"}],\"OnlyDisputer()\":[{\"notice\":\"Throws if the msg.sender is not a disputer or is not a part of governance\"}],\"OnlyGovernor()\":[{\"notice\":\"Thrown if a non-governor user tries to call a OnlyGovernor function\"}],\"OnlyJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the job owner\"}],\"OnlyPendingGovernor()\":[{\"notice\":\"Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\"}],\"OnlyPendingJobOwner()\":[{\"notice\":\"Throws when the caller of the function is not the pending job owner\"}],\"OnlySlasher()\":[{\"notice\":\"Throws if the msg.sender is not a slasher or is not a part of governance\"}],\"SlasherExistent()\":[{\"notice\":\"Throws if the address is already a registered slasher\"}],\"SlasherUnexistent()\":[{\"notice\":\"Throws if caller is not a registered slasher\"}],\"TokenUnallowed()\":[{\"notice\":\"Throws when the token is KP3R, as it should not be used for direct token payments\"}],\"UnbondsLocked()\":[{\"notice\":\"Throws if the time required to withdraw the bonds has not passed yet\"}],\"UnbondsUnexistent()\":[{\"notice\":\"Throws if there are no bonds to withdraw\"}],\"ZeroAddress()\":[{\"notice\":\"Thrown if an address is the zero address\"}],\"ZeroAmount()\":[{\"notice\":\"Thrown if an amount is zero\"}]},\"events\":{\"Activation(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#activate is called\"},\"BondTimeChange(uint256)\":{\"notice\":\"Emitted when bondTime is changed\"},\"Bonding(address,address,uint256)\":{\"notice\":\"Emitted when the bonding process of a new keeper begins\"},\"Dispute(address,address)\":{\"notice\":\"Emitted when a keeper or a job is disputed\"},\"DisputerAdded(address)\":{\"notice\":\"Emitted when a disputer is added\"},\"DisputerRemoved(address)\":{\"notice\":\"Emitted when a disputer is removed\"},\"DustSent(address,uint256,address)\":{\"notice\":\"Emitted when dust is sent\"},\"FeeChange(uint256)\":{\"notice\":\"Emitted when the fee is changed\"},\"InflationPeriodChange(uint256)\":{\"notice\":\"Emitted when the inflationPeriod is changed\"},\"JobAddition(address,address)\":{\"notice\":\"Emitted when Keep3rJobManager#addJob is called\"},\"JobMigrationRequested(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#migrateJob function is called\"},\"JobMigrationSuccessful(address,address)\":{\"notice\":\"Emitted when Keep3rJobMigration#acceptJobMigration function is called\"},\"JobOwnershipAssent(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\"},\"JobOwnershipChange(address,address,address)\":{\"notice\":\"Emitted when Keep3rJobOwnership#changeJobOwnership is called\"},\"JobSlashLiquidity(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\"},\"JobSlashToken(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobDisputable#slashTokenFromJob is called\"},\"Keep3rHelperChange(address)\":{\"notice\":\"Emitted when the Keep3rHelper address is changed\"},\"Keep3rV1Change(address)\":{\"notice\":\"Emitted when the Keep3rV1 address is changed\"},\"Keep3rV1ProxyChange(address)\":{\"notice\":\"Emitted when the Keep3rV1Proxy address is changed\"},\"KeeperRevoke(address,address)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#revoke is called\"},\"KeeperSlash(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperDisputable#slash is called\"},\"KeeperValidation(uint256)\":{\"notice\":\"Emitted when a keeper is validated before a job\"},\"KeeperWork(address,address,address,uint256,uint256)\":{\"notice\":\"Emitted when a keeper works a job\"},\"LiquidityAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityApproval(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\"},\"LiquidityCreditsForced(address,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\"},\"LiquidityCreditsReward(address,uint256,uint256,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\"},\"LiquidityMinimumChange(uint256)\":{\"notice\":\"Emitted when _liquidityMinimum is changed\"},\"LiquidityRevocation(address)\":{\"notice\":\"Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\"},\"LiquidityWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\"},\"PendingGovernorAccepted(address)\":{\"notice\":\"Emitted when a new governor is set\"},\"PendingGovernorSet(address,address)\":{\"notice\":\"Emitted when a new pending governor is set\"},\"Resolve(address,address)\":{\"notice\":\"Emitted when a dispute is resolved\"},\"RewardPeriodTimeChange(uint256)\":{\"notice\":\"Emitted when _rewardPeriodTime is changed\"},\"SlasherAdded(address)\":{\"notice\":\"Emitted when a slasher is added\"},\"SlasherRemoved(address)\":{\"notice\":\"Emitted when a slasher is removed\"},\"TokenCreditAddition(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\"},\"TokenCreditWithdrawal(address,address,address,uint256)\":{\"notice\":\"Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\"},\"UnbondTimeChange(uint256)\":{\"notice\":\"Emitted when _unbondTime is changed\"},\"Unbonding(address,address,uint256)\":{\"notice\":\"Emitted when a keeper or job begins the unbonding process to withdraw the funds\"},\"Withdrawal(address,address,uint256)\":{\"notice\":\"Emitted when Keep3rKeeperFundable#withdraw is called\"}},\"kind\":\"user\",\"methods\":{\"acceptJobMigration(address,address)\":{\"notice\":\"Completes the migration process for a job\"},\"acceptJobOwnership(address)\":{\"notice\":\"The proposed address accepts to be the owner of the job\"},\"acceptPendingGovernor()\":{\"notice\":\"Allows a proposed governor to accept the governance\"},\"activate(address)\":{\"notice\":\"End of the bonding process after bonding time has passed\"},\"addDisputer(address)\":{\"notice\":\"Registers a disputer by updating the disputers mapping\"},\"addJob(address)\":{\"notice\":\"Allows any caller to add a new job\"},\"addLiquidityToJob(address,address,uint256)\":{\"notice\":\"Allows anyone to fund a job with liquidity\"},\"addSlasher(address)\":{\"notice\":\"Registers a slasher by updating the slashers mapping\"},\"addTokenCreditsToJob(address,address,uint256)\":{\"notice\":\"Add credit to a job to be paid out for work\"},\"approveLiquidity(address)\":{\"notice\":\"Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\"},\"approvedLiquidities()\":{\"notice\":\"Lists liquidity pairs\"},\"bond(address,uint256)\":{\"notice\":\"Beginning of the bonding process\"},\"bondTime()\":{\"notice\":\"The amount of time required to pass after a keeper has bonded assets for it to be able to activate\"},\"bondedPayment(address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"bonds(address,address)\":{\"notice\":\"Mapping (job => bonding => amount)\"},\"canActivateAfter(address,address)\":{\"notice\":\"Tracks when a bonding for a keeper can be activated\"},\"canWithdrawAfter(address,address)\":{\"notice\":\"Tracks when keeper bonds are ready to be withdrawn\"},\"changeJobOwnership(address,address)\":{\"notice\":\"Proposes a new address to be the owner of the job\"},\"directTokenPayment(address,address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"dispute(address)\":{\"notice\":\"Allows governor to create a dispute for a given keeper/job\"},\"disputers(address)\":{\"notice\":\"Tracks whether the address is a disputer or not\"},\"disputes(address)\":{\"notice\":\"Tracks if a keeper or job has a pending dispute\"},\"fee()\":{\"notice\":\"The fee to be sent to governor when a user adds liquidity to a job\"},\"firstSeen(address)\":{\"notice\":\"Tracks when a keeper was first registered\"},\"forceLiquidityCreditsToJob(address,uint256)\":{\"notice\":\"Gifts liquidity credits to the specified job\"},\"hasBonded(address)\":{\"notice\":\"Checks whether the address has ever bonded an asset\"},\"inflationPeriod()\":{\"notice\":\"The inflation period is the denominator used to regulate the emission of KP3R\"},\"isBondedKeeper(address,address,uint256,uint256,uint256)\":{\"notice\":\"Confirms if the current keeper is registered and has a minimum bond of any asset.\"},\"isKeeper(address)\":{\"notice\":\"Confirms if the current keeper is registered\"},\"jobLiquidityCredits(address)\":{\"notice\":\"Returns the liquidity credits of a given job\"},\"jobOwner(address)\":{\"notice\":\"Maps the job to the owner of the job\"},\"jobPendingOwner(address)\":{\"notice\":\"Maps the job to its pending owner\"},\"jobPeriodCredits(address)\":{\"notice\":\"Returns the credits of a given job for the current period\"},\"jobTokenCredits(address,address)\":{\"notice\":\"The current token credits available for a job\"},\"jobTokenCreditsAddedAt(address,address)\":{\"notice\":\"Last block where tokens were added to the job\"},\"jobs()\":{\"notice\":\"Lists all jobs\"},\"keep3rHelper()\":{\"notice\":\"Address of Keep3rHelper's contract\"},\"keep3rV1()\":{\"notice\":\"Address of Keep3rV1's contract\"},\"keep3rV1Proxy()\":{\"notice\":\"Address of Keep3rV1Proxy's contract\"},\"keepers()\":{\"notice\":\"Lists all keepers\"},\"liquidityAmount(address,address)\":{\"notice\":\"Amount of liquidity in a specified job\"},\"liquidityMinimum()\":{\"notice\":\"The minimum amount of liquidity required to fund a job per liquidity\"},\"migrateJob(address,address)\":{\"notice\":\"Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\"},\"observeLiquidity(address)\":{\"notice\":\"Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\"},\"pendingBonds(address,address)\":{\"notice\":\"Tracks the amount of assets deposited in pending bonds\"},\"pendingJobMigrations(address)\":{\"notice\":\"Maps the jobs that have requested a migration to the address they have requested to migrate to\"},\"pendingUnbonds(address,address)\":{\"notice\":\"Tracks how much keeper bonds are to be withdrawn\"},\"quoteLiquidity(address,uint256)\":{\"notice\":\"Calculates how many credits should be rewarded periodically for a given liquidity amount\"},\"removeDisputer(address)\":{\"notice\":\"Removes a disputer by updating the disputers mapping\"},\"removeSlasher(address)\":{\"notice\":\"Removes a slasher by updating the slashers mapping\"},\"resolve(address)\":{\"notice\":\"Allows governor to resolve a dispute on a keeper/job\"},\"revoke(address)\":{\"notice\":\"Blacklists a keeper from participating in the network\"},\"revokeLiquidity(address)\":{\"notice\":\"Revoke a liquidity pair from being accepted in future\"},\"rewardPeriodTime()\":{\"notice\":\"The amount of time between each scheduled credits reward given to a job\"},\"rewardedAt(address)\":{\"notice\":\"Last time the job was rewarded liquidity credits\"},\"sendDust(address,uint256,address)\":{\"notice\":\"Allows an authorized user to transfer the tokens or eth that may have been left in a contract\"},\"setBondTime(uint256)\":{\"notice\":\"Sets the bond time required to activate as a keeper\"},\"setFee(uint256)\":{\"notice\":\"Sets the new fee\"},\"setInflationPeriod(uint256)\":{\"notice\":\"Sets the new inflation period\"},\"setKeep3rHelper(address)\":{\"notice\":\"Sets the Keep3rHelper address\"},\"setKeep3rV1(address)\":{\"notice\":\"Sets the Keep3rV1 address\"},\"setKeep3rV1Proxy(address)\":{\"notice\":\"Sets the Keep3rV1Proxy address\"},\"setLiquidityMinimum(uint256)\":{\"notice\":\"Sets the minimum amount of liquidity required to fund a job\"},\"setPendingGovernor(address)\":{\"notice\":\"Allows a governor to propose a new governor\"},\"setRewardPeriodTime(uint256)\":{\"notice\":\"Sets the time required to pass between rewards for jobs\"},\"setUnbondTime(uint256)\":{\"notice\":\"Sets the unbond time required unbond what has been bonded\"},\"slash(address,address,uint256,uint256)\":{\"notice\":\"Allows governor to slash a keeper based on a dispute\"},\"slashLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Allows governor or slasher to slash liquidity from a job\"},\"slashTokenFromJob(address,address,uint256)\":{\"notice\":\"Allows governor or slasher to slash a job specific token\"},\"slashers(address)\":{\"notice\":\"Tracks whether the address is a slasher or not\"},\"totalBonds()\":{\"notice\":\"Tracks the total amount of bonded KP3Rs in the contract\"},\"totalJobCredits(address)\":{\"notice\":\"Calculates the total credits of a given job\"},\"unbond(address,uint256)\":{\"notice\":\"Beginning of the unbonding process\"},\"unbondLiquidityFromJob(address,address,uint256)\":{\"notice\":\"Unbond liquidity for a job\"},\"unbondTime()\":{\"notice\":\"The amount of time required to pass before a keeper can unbond what he has bonded\"},\"virtualReserves()\":{\"notice\":\"The surplus amount of wKP3Rs in escrow contract\"},\"withdraw(address)\":{\"notice\":\"Withdraw funds after unbonding has finished\"},\"withdrawLiquidityFromJob(address,address,address)\":{\"notice\":\"Withdraw liquidity from a job\"},\"withdrawTokenCreditsFromJob(address,address,uint256,address)\":{\"notice\":\"Withdraw credit from a job\"},\"workCompleted(address)\":{\"notice\":\"Tracks the total KP3R earnings of a keeper since it started working\"},\"worked(address,uint256)\":{\"notice\":\"Implemented by jobs to show that a keeper performed work\"},\"workedAt(address)\":{\"notice\":\"Last time the job was worked\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/contracts/sidechain/Keep3rSidechain.sol\":\"Keep3rSidechain\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {Governable} from './Governable.sol';\\nimport {IDustCollector} from '../interfaces/IDustCollector.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\n/// @title DustCollector contract\\nabstract contract DustCollector is IDustCollector, Governable {\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IDustCollector\\n address public constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n /// @inheritdoc IDustCollector\\n function sendDust(address _token, uint256 _amount, address _to) external onlyGovernor {\\n if (_to == address(0)) revert ZeroAddress();\\n if (_token == ETH_ADDRESS) payable(_to).transfer(_amount);\\n else IERC20(_token).safeTransfer(_to, _amount);\\n emit DustSent(_token, _amount, _to);\\n }\\n}\\n\",\"keccak256\":\"0xcdd6d0715406facd602770cca9320eebdc2b7b23b0e0f9e1b7b576fbc0126b47\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from '../interfaces/IGovernable.sol';\\n\\n/// @title Governable contract\\n/// @notice Manages the governor role\\nabstract contract Governable is IGovernable {\\n /// @inheritdoc IGovernable\\n address public governor;\\n\\n /// @inheritdoc IGovernable\\n address public pendingGovernor;\\n\\n constructor(address _governor) {\\n if (_governor == address(0)) revert ZeroAddress();\\n governor = _governor;\\n }\\n\\n /// @inheritdoc IGovernable\\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\\n _setPendingGovernor(_pendingGovernor);\\n }\\n\\n /// @inheritdoc IGovernable\\n function acceptPendingGovernor() external onlyPendingGovernor {\\n _acceptPendingGovernor();\\n }\\n\\n function _setPendingGovernor(address _pendingGovernor) internal {\\n if (_pendingGovernor == address(0)) revert ZeroAddress();\\n pendingGovernor = _pendingGovernor;\\n emit PendingGovernorSet(governor, _pendingGovernor);\\n }\\n\\n function _acceptPendingGovernor() internal {\\n governor = pendingGovernor;\\n delete pendingGovernor;\\n emit PendingGovernorAccepted(governor);\\n }\\n\\n /// @notice Functions with this modifier can only be called by governor\\n modifier onlyGovernor() {\\n if (msg.sender != governor) revert OnlyGovernor();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by pendingGovernor\\n modifier onlyPendingGovernor() {\\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x3f11408cfcb015a99dc417e075c8ebc39b796fc2adc3e81b036487e4486881b3\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\ninterface IBaseErrors {\\n /// @notice Thrown if an address is invalid\\n error InvalidAddress();\\n\\n /// @notice Thrown if an amount is invalid\\n error InvalidAmount();\\n\\n /// @notice Thrown if the lengths of a set of lists mismatch\\n error LengthMismatch();\\n\\n /// @notice Thrown if an address is the zero address\\n error ZeroAddress();\\n\\n /// @notice Thrown if an amount is zero\\n error ZeroAmount();\\n}\\n\",\"keccak256\":\"0xec09b9d248b6fbf6343dee41d6978abdc15d4c8df5ed7721e8df79e8b1a558cf\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IDustCollector.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IGovernable} from './IGovernable.sol';\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title DustCollector interface\\ninterface IDustCollector is IBaseErrors, IGovernable {\\n // STATE VARIABLES\\n\\n /// @return _ethAddress Address used to trigger a native token transfer\\n // solhint-disable-next-line func-name-mixedcase\\n function ETH_ADDRESS() external view returns (address _ethAddress);\\n\\n // EVENTS\\n\\n /// @notice Emitted when dust is sent\\n /// @param _to The address which wil received the funds\\n /// @param _token The token that will be transferred\\n /// @param _amount The amount of the token that will be transferred\\n event DustSent(address _token, uint256 _amount, address _to);\\n\\n // FUNCTIONS\\n\\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\\n /// @param _token The token that will be transferred\\n /// @param _amount The amont of the token that will be transferred\\n /// @param _to The address that will receive the idle funds\\n function sendDust(address _token, uint256 _amount, address _to) external;\\n}\\n\",\"keccak256\":\"0xbe22cc660bd6846093504989146038bd369f511325cef40cdc647fe7e04206b1\",\"license\":\"MIT\"},\"@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.8 <0.9.0;\\n\\nimport {IBaseErrors} from './IBaseErrors.sol';\\n\\n/// @title Governable interface\\ninterface IGovernable is IBaseErrors {\\n // STATE VARIABLES\\n\\n /// @return _governor Address of the current governor\\n function governor() external view returns (address _governor);\\n\\n /// @return _pendingGovernor Address of the current pending governor\\n function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n // EVENTS\\n\\n /// @notice Emitted when a new pending governor is set\\n /// @param _governor Address of the current governor\\n /// @param _pendingGovernor Address of the proposed next governor\\n event PendingGovernorSet(address _governor, address _pendingGovernor);\\n\\n /// @notice Emitted when a new governor is set\\n /// @param _newGovernor Address of the new governor\\n event PendingGovernorAccepted(address _newGovernor);\\n\\n // ERRORS\\n\\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\\n error OnlyGovernor();\\n\\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\\n error OnlyPendingGovernor();\\n\\n // FUNCTIONS\\n\\n /// @notice Allows a governor to propose a new governor\\n /// @param _pendingGovernor Address of the proposed new governor\\n function setPendingGovernor(address _pendingGovernor) external;\\n\\n /// @notice Allows a proposed governor to accept the governance\\n function acceptPendingGovernor() external;\\n}\\n\",\"keccak256\":\"0x40b94706a00d2c092f620807ba84bdd0c5ed8cfa60140c924edc850427e0af13\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"solidity/contracts/Keep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../interfaces/IKeep3r.sol';\\nimport './peripherals/jobs/Keep3rJobs.sol';\\nimport './peripherals/keepers/Keep3rKeepers.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol';\\n\\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\\n constructor(\\n address _governor,\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governor) {}\\n}\\n\",\"keccak256\":\"0x21c3fd585303fbb3686a9f11e13da71ef98c24eb14cf6a9721eee30b03a75ffa\",\"license\":\"MIT\"},\"solidity/contracts/libraries/FullMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Contains 512-bit math functions\\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\\n/// @dev Handles \\\"phantom overflow\\\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\\nlibrary FullMath {\\n /// @notice Calculates floor(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\\n function mulDiv(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = a * b\\n // Compute the product mod 2**256 and mod 2**256 - 1\\n // then use the Chinese Remainder Theorem to reconstruct\\n // the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2**256 + prod0\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(a, b, not(0))\\n prod0 := mul(a, b)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division\\n if (prod1 == 0) {\\n require(denominator > 0);\\n assembly {\\n result := div(prod0, denominator)\\n }\\n return result;\\n }\\n\\n // Make sure the result is less than 2**256.\\n // Also prevents denominator == 0\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0]\\n // Compute remainder using mulmod\\n uint256 remainder;\\n assembly {\\n remainder := mulmod(a, b, denominator)\\n }\\n // Subtract 256 bit number from 512 bit number\\n assembly {\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator\\n // Compute largest power of two divisor of denominator.\\n // Always >= 1.\\n uint256 twos = (~denominator + 1) & denominator;\\n // Divide denominator by power of two\\n assembly {\\n denominator := div(denominator, twos)\\n }\\n\\n // Divide [prod1 prod0] by the factors of two\\n assembly {\\n prod0 := div(prod0, twos)\\n }\\n // Shift in bits from prod1 into prod0. For this we need\\n // to flip `twos` such that it is 2**256 / twos.\\n // If twos is zero, then it becomes one\\n assembly {\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2**256\\n // Now that denominator is an odd number, it has an inverse\\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\\n // Compute the inverse by starting with a seed that is correct\\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\\n uint256 inv = (3 * denominator) ^ 2;\\n // Now use Newton-Raphson iteration to improve the precision.\\n // Thanks to Hensel's lifting lemma, this also works in modular\\n // arithmetic, doubling the correct bits in each step.\\n inv *= 2 - denominator * inv; // inverse mod 2**8\\n inv *= 2 - denominator * inv; // inverse mod 2**16\\n inv *= 2 - denominator * inv; // inverse mod 2**32\\n inv *= 2 - denominator * inv; // inverse mod 2**64\\n inv *= 2 - denominator * inv; // inverse mod 2**128\\n inv *= 2 - denominator * inv; // inverse mod 2**256\\n\\n // Because the division is now exact we can divide by multiplying\\n // with the modular inverse of denominator. This will give us the\\n // correct result modulo 2**256. Since the precoditions guarantee\\n // that the outcome is less than 2**256, this is the final result.\\n // We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inv;\\n return result;\\n }\\n }\\n\\n /// @notice Calculates ceil(a\\u00d7b\\u00f7denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n /// @param a The multiplicand\\n /// @param b The multiplier\\n /// @param denominator The divisor\\n /// @return result The 256-bit result\\n function mulDivRoundingUp(\\n uint256 a,\\n uint256 b,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n result = mulDiv(a, b, denominator);\\n if (mulmod(a, b, denominator) > 0) {\\n require(result < type(uint256).max);\\n result++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1c595da02adf8ba2ae74ac579b9b3c966d1ecb2a99c25081a62ee8550f26569\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\\nimport './Keep3rRoles.sol';\\n\\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @notice List of all enabled keepers\\n EnumerableSet.AddressSet internal _keepers;\\n\\n /// @inheritdoc IKeep3rAccountance\\n uint256 public override totalBonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override workCompleted;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => uint256) public override firstSeen;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override disputes;\\n\\n /// @inheritdoc IKeep3rAccountance\\n /// @notice Mapping (job => bonding => amount)\\n mapping(address => mapping(address => uint256)) public override bonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\\n\\n /// @notice The current liquidity credits available for a job\\n mapping(address => uint256) internal _jobLiquidityCredits;\\n\\n /// @notice Map the address of a job to its correspondent periodCredits\\n mapping(address => uint256) internal _jobPeriodCredits;\\n\\n /// @notice Enumerable array of Job Tokens for Credits\\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\\n\\n /// @notice List of liquidities that a job has (job => liquidities)\\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\\n\\n /// @notice Liquidity pool to observe\\n mapping(address => address) internal _liquidityPool;\\n\\n /// @notice Tracks if a pool has KP3R as token0\\n mapping(address => bool) internal _isKP3RToken0;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingBonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\\n\\n /// @inheritdoc IKeep3rAccountance\\n mapping(address => bool) public override hasBonded;\\n\\n /// @notice List of all enabled jobs\\n EnumerableSet.AddressSet internal _jobs;\\n\\n /// @inheritdoc IKeep3rAccountance\\n function jobs() external view override returns (address[] memory _list) {\\n _list = _jobs.values();\\n }\\n\\n /// @inheritdoc IKeep3rAccountance\\n function keepers() external view override returns (address[] memory _list) {\\n _list = _keepers.values();\\n }\\n}\\n\",\"keccak256\":\"0xcd2a525e6567eea4f2a7f93e8eb686e484d2a078686f2744dde35a8383881730\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rParameters.sol';\\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\\n\\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\\n /// @inheritdoc IKeep3rDisputable\\n function dispute(address _jobOrKeeper) external override onlyDisputer {\\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\\n disputes[_jobOrKeeper] = true;\\n emit Dispute(_jobOrKeeper, msg.sender);\\n }\\n\\n /// @inheritdoc IKeep3rDisputable\\n function resolve(address _jobOrKeeper) external override onlyDisputer {\\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\\n disputes[_jobOrKeeper] = false;\\n emit Resolve(_jobOrKeeper, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x664b54040aa4e734f68a01fcfb5bf67cbb1a70efd03862cd3a456457536b1fb4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/IKeep3rHelper.sol';\\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\\nimport './Keep3rAccountance.sol';\\n\\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rV1Proxy;\\n\\n /// @inheritdoc IKeep3rParameters\\n address public override keep3rHelper;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override bondTime = 3 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override unbondTime = 14 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override liquidityMinimum = 3 ether;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override rewardPeriodTime = 5 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override inflationPeriod = 34 days;\\n\\n /// @inheritdoc IKeep3rParameters\\n uint256 public override fee = 30;\\n\\n /// @notice The base that will be used to calculate the fee\\n uint256 internal constant _BASE = 10_000;\\n\\n /// @notice The minimum reward period\\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\\n\\n constructor(\\n address _keep3rHelper,\\n address _keep3rV1,\\n address _keep3rV1Proxy\\n ) {\\n keep3rHelper = _keep3rHelper;\\n keep3rV1 = _keep3rV1;\\n keep3rV1Proxy = _keep3rV1Proxy;\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernor {\\n if (_keep3rHelper == address(0)) revert ZeroAddress();\\n keep3rHelper = _keep3rHelper;\\n emit Keep3rHelperChange(_keep3rHelper);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernor {\\n if (_keep3rV1 == address(0)) revert ZeroAddress();\\n _mint(totalBonds);\\n\\n keep3rV1 = _keep3rV1;\\n emit Keep3rV1Change(_keep3rV1);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernor {\\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\\n keep3rV1Proxy = _keep3rV1Proxy;\\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setBondTime(uint256 _bondTime) external override onlyGovernor {\\n bondTime = _bondTime;\\n emit BondTimeChange(_bondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernor {\\n unbondTime = _unbondTime;\\n emit UnbondTimeChange(_unbondTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernor {\\n liquidityMinimum = _liquidityMinimum;\\n emit LiquidityMinimumChange(_liquidityMinimum);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernor {\\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\\n rewardPeriodTime = _rewardPeriodTime;\\n emit RewardPeriodTimeChange(_rewardPeriodTime);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernor {\\n inflationPeriod = _inflationPeriod;\\n emit InflationPeriodChange(_inflationPeriod);\\n }\\n\\n /// @inheritdoc IKeep3rParameters\\n function setFee(uint256 _fee) external override onlyGovernor {\\n fee = _fee;\\n emit FeeChange(_fee);\\n }\\n\\n function _mint(uint256 _amount) internal {\\n totalBonds -= _amount;\\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\\n }\\n}\\n\",\"keccak256\":\"0xcbc3784d997d3433461741e68f0119f197fa9e595e79939e540d810f4a76cde6\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/Keep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\\n\\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override slashers;\\n\\n /// @inheritdoc IKeep3rRoles\\n mapping(address => bool) public override disputers;\\n\\n constructor(address _governor) Governable(_governor) DustCollector() {}\\n\\n /// @inheritdoc IKeep3rRoles\\n function addSlasher(address _slasher) external override onlyGovernor {\\n if (_slasher == address(0)) revert ZeroAddress();\\n if (slashers[_slasher]) revert SlasherExistent();\\n slashers[_slasher] = true;\\n emit SlasherAdded(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeSlasher(address _slasher) external override onlyGovernor {\\n if (!slashers[_slasher]) revert SlasherUnexistent();\\n delete slashers[_slasher];\\n emit SlasherRemoved(_slasher);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function addDisputer(address _disputer) external override onlyGovernor {\\n if (_disputer == address(0)) revert ZeroAddress();\\n if (disputers[_disputer]) revert DisputerExistent();\\n disputers[_disputer] = true;\\n emit DisputerAdded(_disputer);\\n }\\n\\n /// @inheritdoc IKeep3rRoles\\n function removeDisputer(address _disputer) external override onlyGovernor {\\n if (!disputers[_disputer]) revert DisputerUnexistent();\\n delete disputers[_disputer];\\n emit DisputerRemoved(_disputer);\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a slasher or governance\\n modifier onlySlasher {\\n if (!slashers[msg.sender]) revert OnlySlasher();\\n _;\\n }\\n\\n /// @notice Functions with this modifier can only be called by either a disputer or governance\\n modifier onlyDisputer {\\n if (!disputers[msg.sender]) revert OnlyDisputer();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x80a56902f12536731155ceff8be13081f940991fdd03b38eccf4f241cb61f23a\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\nimport '../Keep3rDisputable.sol';\\n\\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\\n\\n try IERC20(_token).transfer(governor, _amount) {} catch {}\\n jobTokenCredits[_job][_token] -= _amount;\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit JobSlashToken(_job, _token, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobDisputable\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlySlasher {\\n if (!disputes[_job]) revert NotDisputed();\\n\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n try IERC20(_liquidity).transfer(governor, _amount) {} catch {}\\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x545db29f913063a93e35148c49d1498206d8429f9def33bbea6bb735c4e97dde\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice Cooldown between withdrawals\\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n // KP3R shouldn't be used for direct token payments\\n if (_token == keep3rV1) revert TokenUnallowed();\\n uint256 _before = IERC20(_token).balanceOf(address(this));\\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\\n uint256 _tokenFee = (_received * fee) / _BASE;\\n jobTokenCredits[_job][_token] += _received - _tokenFee;\\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\\n IERC20(_token).safeTransfer(governor, _tokenFee);\\n _jobTokens[_job].add(_token);\\n\\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableCredits\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external override nonReentrant onlyJobOwner(_job) {\\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\\n if (disputes[_job]) revert JobDisputed();\\n\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n\\n if (jobTokenCredits[_job][_token] == 0) {\\n _jobTokens[_job].remove(_token);\\n }\\n\\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x39eae0b2b1e1f19d18d5574a7ada277d694f45991742b4f7410266eca7c50899\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/IPairManager.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '../../libraries/FullMath.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\n\\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @notice List of liquidities that are accepted in the system\\n EnumerableSet.AddressSet internal _approvedLiquidities;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override rewardedAt;\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n mapping(address => uint256) public override workedAt;\\n\\n /// @notice Tracks an address and returns its TickCache\\n mapping(address => TickCache) internal _tick;\\n\\n // Views\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approvedLiquidities() external view override returns (address[] memory _list) {\\n _list = _approvedLiquidities.values();\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n _periodCredits += _getReward(\\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\\n );\\n }\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n\\n // If the job was rewarded in the past 1 period time\\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\\n // If the job has period credits, update minted job credits to new twap\\n _liquidityCredits = _periodCredits > 0\\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\\n } else {\\n // Else return a full period worth of credits if current credits have expired\\n _liquidityCredits = _periodCredits;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\\n uint256 _periodCredits = jobPeriodCredits(_job);\\n uint256 _cooldown = block.timestamp;\\n\\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\\n // Will calculate cooldown if it outdated\\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will calculate cooldown from last reward reference in this period\\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\\n } else {\\n // Will calculate cooldown from last reward timestamp\\n _cooldown -= rewardedAt[_job];\\n }\\n } else {\\n // Will calculate cooldown from period start if expired\\n _cooldown -= _period(block.timestamp);\\n }\\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\\n if (_approvedLiquidities.contains(_liquidity)) {\\n TickCache memory _tickCache = observeLiquidity(_liquidity);\\n if (_tickCache.period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\\n }\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\\n if (_tick[_liquidity].period == _period(block.timestamp)) {\\n // Will return cached twaps if liquidity is updated\\n _tickCache = _tick[_liquidity];\\n } else {\\n bool success;\\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\\n\\n if (_tick[_liquidity].period == lastPeriod) {\\n // Will only ask for current period accumulator if liquidity is outdated\\n uint32[] memory _secondsAgo = new uint32[](1);\\n int56 previousTick = _tick[_liquidity].current;\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n\\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - previousTick;\\n } else if (_tick[_liquidity].period < lastPeriod) {\\n // Will ask for 2 accumulators if liquidity is expired\\n uint32[] memory _secondsAgo = new uint32[](2);\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\\n\\n int56 _tickCumulative2;\\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - _tickCumulative2;\\n }\\n if (success) {\\n _tickCache.period = _period(block.timestamp);\\n } else {\\n delete _tickCache.period;\\n }\\n }\\n }\\n\\n // Methods\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernor {\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n _settleJobAccountance(_job);\\n _jobLiquidityCredits[_job] += _amount;\\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function approveLiquidity(address _liquidity) external virtual override onlyGovernor {\\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n emit LiquidityApproval(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function revokeLiquidity(address _liquidity) external override onlyGovernor {\\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\\n delete _liquidityPool[_liquidity];\\n delete _isKP3RToken0[_liquidity];\\n delete _tick[_liquidity];\\n\\n emit LiquidityRevocation(_liquidity);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override nonReentrant {\\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\\n if (!_jobs.contains(_job)) revert JobUnavailable();\\n\\n _jobLiquidities[_job].add(_liquidity);\\n\\n _settleJobAccountance(_job);\\n\\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\\n liquidityAmount[_job][_liquidity] += _amount;\\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external override onlyJobOwner(_job) {\\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\\n pendingUnbonds[_job][_liquidity] += _amount;\\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\\n\\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\\n\\n emit Unbonding(_job, _liquidity, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rJobFundableLiquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external override onlyJobOwner(_job) {\\n if (_receiver == address(0)) revert ZeroAddress();\\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[_job]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[_job][_liquidity];\\n\\n delete pendingUnbonds[_job][_liquidity];\\n delete canWithdrawAfter[_job][_liquidity];\\n\\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\\n }\\n\\n // Internal functions\\n\\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\\n if (rewardedAt[_job] < _period(block.timestamp)) {\\n // Will exit function if job has been rewarded in current period\\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\\n // Will reset job to period syncronicity if a full period passed without rewards\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] = _period(block.timestamp);\\n _rewarded = true;\\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\\n // Will reset job's syncronicity if last reward was more than epoch ago\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\\n rewardedAt[_job] += rewardPeriodTime;\\n _rewarded = true;\\n } else if (workedAt[_job] < _period(block.timestamp)) {\\n // First keeper on period has to update job accountance to current twaps\\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\\n _updateJobPeriod(_job);\\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\\n // Updating job accountance does not reward job\\n }\\n }\\n }\\n\\n /// @notice Only called if _jobLiquidityCredits < payment\\n function _rewardJobCredits(address _job) internal {\\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\\n rewardedAt[_job] = block.timestamp;\\n }\\n\\n /// @notice Updates accountance for _jobPeriodCredits\\n function _updateJobPeriod(address _job) internal {\\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\\n }\\n\\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\\n address _liquidity = _jobLiquidities[_job].at(i);\\n if (_approvedLiquidities.contains(_liquidity)) {\\n if (_tick[_liquidity].period != _period(block.timestamp)) {\\n // Updates liquidity cache only if needed\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n }\\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\\n }\\n }\\n }\\n\\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\\n function _unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) internal nonReentrant {\\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\\n\\n // Ensures current twaps in job liquidities\\n _updateJobPeriod(_job);\\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\\n\\n // A liquidity can be revoked causing a job to have 0 periodCredits\\n if (_jobPeriodCredits[_job] > 0) {\\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\\n }\\n\\n liquidityAmount[_job][_liquidity] -= _amount;\\n if (liquidityAmount[_job][_liquidity] == 0) {\\n _jobLiquidities[_job].remove(_liquidity);\\n }\\n }\\n\\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\\n if (_timePassed < rewardPeriodTime) {\\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\\n } else _result = _multiplier;\\n }\\n\\n /// @notice Returns the start of the period of the provided timestamp\\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\\n return _timestamp - (_timestamp % rewardPeriodTime);\\n }\\n\\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\\n }\\n\\n /// @notice Returns underlying KP3R amount for a given liquidity amount\\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\\n if (_tick[_liquidity].period != 0) {\\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\\n }\\n }\\n\\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\\n /// @dev Ensures a maximum of 1 period of credits\\n function _settleJobAccountance(address _job) internal virtual {\\n _updateJobCreditsIfNeeded(_job);\\n _rewardJobCredits(_job);\\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n}\\n\",\"keccak256\":\"0x376ccb8e49a29f87104732bfef03fbbb72e3d3d0b92c5cfe1256e718412c5073\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobOwnership.sol';\\nimport '../Keep3rAccountance.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @inheritdoc IKeep3rJobManager\\n function addJob(address _job) external override {\\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\\n if (hasBonded[_job]) revert AlreadyAKeeper();\\n _jobs.add(_job);\\n jobOwner[_job] = msg.sender;\\n emit JobAddition(_job, msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xf6e1577a6a34b674ca34a6d7530dc81349e3ad13d321281c37e0b25b7325d013\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobFundableCredits.sol';\\nimport './Keep3rJobFundableLiquidity.sol';\\n\\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n mapping(address => address) public override pendingJobMigrations;\\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\\n if (_fromJob == _toJob) revert JobMigrationImpossible();\\n\\n pendingJobMigrations[_fromJob] = _toJob;\\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\\n\\n emit JobMigrationRequested(_fromJob, _toJob);\\n }\\n\\n /// @inheritdoc IKeep3rJobMigration\\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\\n\\n // force job credits update for both jobs\\n _settleJobAccountance(_fromJob);\\n _settleJobAccountance(_toJob);\\n\\n // migrate tokens\\n while (_jobTokens[_fromJob].length() > 0) {\\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\\n _jobTokens[_fromJob].remove(_tokenToMigrate);\\n _jobTokens[_toJob].add(_tokenToMigrate);\\n }\\n\\n // migrate liquidities\\n while (_jobLiquidities[_fromJob].length() > 0) {\\n address _liquidity = _jobLiquidities[_fromJob].at(0);\\n\\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\\n delete liquidityAmount[_fromJob][_liquidity];\\n\\n _jobLiquidities[_toJob].add(_liquidity);\\n _jobLiquidities[_fromJob].remove(_liquidity);\\n }\\n\\n // migrate job balances\\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\\n delete _jobPeriodCredits[_fromJob];\\n\\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\\n delete _jobLiquidityCredits[_fromJob];\\n\\n // stop _fromJob from being a job\\n delete rewardedAt[_fromJob];\\n _jobs.remove(_fromJob);\\n\\n // delete unused data slots\\n delete jobOwner[_fromJob];\\n delete jobPendingOwner[_fromJob];\\n delete _migrationCreatedAt[_fromJob][_toJob];\\n delete pendingJobMigrations[_fromJob];\\n\\n emit JobMigrationSuccessful(_fromJob, _toJob);\\n }\\n}\\n\",\"keccak256\":\"0xd46c3c9ce970098d8d75f11966894a341824aceb40583fcfbbc0ebda93d869f9\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n mapping(address => address) public override jobPendingOwner;\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\\n jobPendingOwner[_job] = _newOwner;\\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\\n }\\n\\n /// @inheritdoc IKeep3rJobOwnership\\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\\n address _previousOwner = jobOwner[_job];\\n\\n jobOwner[_job] = jobPendingOwner[_job];\\n delete jobPendingOwner[_job];\\n\\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\\n }\\n\\n modifier onlyJobOwner(address _job) {\\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\\n _;\\n }\\n\\n modifier onlyPendingJobOwner(address _job) {\\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xa837590ade9cd5d25690e3f2d8b9a63e7202f7179b32e42eab4fa4c4324b9728\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rJobMigration.sol';\\nimport '../../../interfaces/IKeep3rHelper.sol';\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n uint256 internal _initialGas;\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\\n _initialGas = _getGasLeft();\\n if (_keepers.contains(_keeper)) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external override returns (bool _isBondedKeeper) {\\n _initialGas = _getGasLeft();\\n if (\\n _keepers.contains(_keeper) &&\\n bonds[_keeper][_bond] >= _minBond &&\\n workCompleted[_keeper] >= _earned &&\\n block.timestamp - firstSeen[_keeper] >= _age\\n ) {\\n emit KeeperValidation(_initialGas);\\n return true;\\n }\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function worked(address _keeper) external virtual override {\\n if (_initialGas == 0) revert GasNotInitialized();\\n address _job = msg.sender;\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\\n\\n uint256 _gasLeft = _getGasLeft();\\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n\\n _gasLeft = _getGasLeft();\\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n delete _initialGas;\\n\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function bondedPayment(address _keeper, uint256 _payment) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n if (_payment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n _bondedPayment(_job, _keeper, _payment);\\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\\n }\\n\\n /// @inheritdoc IKeep3rJobWorkable\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external override {\\n address _job = msg.sender;\\n\\n if (disputes[_job]) revert JobDisputed();\\n if (disputes[_keeper]) revert Disputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\\n jobTokenCredits[_job][_token] -= _amount;\\n IERC20(_token).safeTransfer(_keeper, _amount);\\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\\n }\\n\\n function _bondedPayment(\\n address _job,\\n address _keeper,\\n uint256 _payment\\n ) internal {\\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\\n\\n workedAt[_job] = block.timestamp;\\n _jobLiquidityCredits[_job] -= _payment;\\n bonds[_keeper][keep3rV1] += _payment;\\n workCompleted[_keeper] += _payment;\\n totalBonds += _payment;\\n }\\n\\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\\n /// @param _gasLeft Amount of gas left after working the job\\n /// @param _extraGas Amount of expected unaccounted gas\\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\\n /// @return _payment Amount to be payed in KP3R tokens\\n function _calculatePayment(\\n uint256 _gasLeft,\\n uint256 _extraGas,\\n uint256 _oneEthQuote,\\n uint256 _boost\\n ) internal view returns (uint256 _payment) {\\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\\n }\\n\\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\\n _gasLeft = (gasleft() * 64) / 63;\\n }\\n}\\n\",\"keccak256\":\"0x7e113a0815d9125e760ee75c9d9c55fc93192ae2535afccdb8835984d17b510f\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/jobs/Keep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\\nimport './Keep3rJobManager.sol';\\nimport './Keep3rJobWorkable.sol';\\nimport './Keep3rJobDisputable.sol';\\n\\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\\n\",\"keccak256\":\"0x882e1a19891795de04c4c891dc58d50034ca0a32c8b61651aaf0f47d0bc321d4\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './Keep3rKeeperFundable.sol';\\nimport '../Keep3rDisputable.sol';\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperDisputable\\n function revoke(address _keeper) external override onlySlasher {\\n if (!disputes[_keeper]) revert NotDisputed();\\n _keepers.remove(_keeper);\\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\\n emit KeeperRevoke(_keeper, msg.sender);\\n }\\n\\n function _slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) internal {\\n if (_bonded != keep3rV1) {\\n try IERC20(_bonded).transfer(governor, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\\n }\\n bonds[_keeper][_bonded] -= _bondAmount;\\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\\n }\\n}\\n\",\"keccak256\":\"0x4dba80c119fa75a3fa13b2c910b8e949154453ac9f1158539ec3f1149830890b\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3rAccountance.sol';\\nimport '../Keep3rParameters.sol';\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\n\\nimport '../../../interfaces/external/IKeep3rV1.sol';\\n\\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\\n if (disputes[msg.sender]) revert Disputed();\\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\\n\\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\\n\\n hasBonded[msg.sender] = true;\\n pendingBonds[msg.sender][_bonding] += _amount;\\n\\n emit Bonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function activate(address _bonding) external override {\\n address _keeper = msg.sender;\\n if (disputes[_keeper]) revert Disputed();\\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\\n if (_canActivateAfter == 0) revert BondsUnexistent();\\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\\n\\n if (firstSeen[_keeper] == 0) {\\n firstSeen[_keeper] = block.timestamp;\\n }\\n _keepers.add(_keeper);\\n\\n uint256 _amount = pendingBonds[_keeper][_bonding];\\n delete pendingBonds[_keeper][_bonding];\\n\\n // bond provided tokens\\n bonds[_keeper][_bonding] += _amount;\\n if (_bonding == keep3rV1) {\\n totalBonds += _amount;\\n _depositBonds(_amount);\\n }\\n\\n emit Activation(_keeper, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function unbond(address _bonding, uint256 _amount) external override {\\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\\n bonds[msg.sender][_bonding] -= _amount;\\n pendingUnbonds[msg.sender][_bonding] += _amount;\\n\\n emit Unbonding(msg.sender, _bonding, _amount);\\n }\\n\\n /// @inheritdoc IKeep3rKeeperFundable\\n function withdraw(address _bonding) external override nonReentrant {\\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\\n if (disputes[msg.sender]) revert Disputed();\\n\\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\\n\\n delete pendingUnbonds[msg.sender][_bonding];\\n delete canWithdrawAfter[msg.sender][_bonding];\\n\\n if (_bonding == keep3rV1) _mint(_amount);\\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\\n\\n emit Withdrawal(msg.sender, _bonding, _amount);\\n }\\n\\n function _depositBonds(uint256 _amount) internal virtual {\\n IKeep3rV1(keep3rV1).burn(_amount);\\n }\\n}\\n\",\"keccak256\":\"0x121dc11fa555731679912d54da3bb8282d26ad425deffae6d4d7085ef3c9290d\",\"license\":\"MIT\"},\"solidity/contracts/peripherals/keepers/Keep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\\nimport './Keep3rKeeperDisputable.sol';\\n\\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\\n\",\"keccak256\":\"0xfc762d9fd6ff478acba446c3ab6fc19c7d49a85de097dc35f02c56e928153c5e\",\"license\":\"MIT\"},\"solidity/contracts/sidechain/Keep3rSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n/*\\n\\nCoded for The Keep3r Network with \\u2665 by\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2551\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u2591\\u2588\\u2588\\u2551\\u2591\\u2591\\u2591\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2554\\u255d\\u2591\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u2591\\u2591\\u2588\\u2588\\u2551\\u2588\\u2588\\u2551\\u2591\\u255a\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u255d\\u255a\\u2550\\u255d\\u2591\\u2591\\u255a\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u2591\\n\\nhttps://defi.sucks\\n\\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\\n\\n*/\\n\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../Keep3r.sol';\\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\\n\\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /// @param _governor Address of governor\\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\\n constructor(\\n address _governor, // governor\\n address _keep3rHelperSidechain, // helper\\n address _wrappedKP3R, // keep3rV1\\n address _keep3rEscrow // keep3rV1Proxy\\n ) Keep3r(_governor, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\\n\\n // Keep3rSidechainAccountance\\n\\n /// @inheritdoc IKeep3rSidechainAccountance\\n function virtualReserves() external view override returns (int256 _virtualReserves) {\\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\\n }\\n\\n // Keep3rJobFundableLiquidity\\n\\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\\n /// @param _liquidity Address of the liquidity token being approved\\n function approveLiquidity(address _liquidity) external virtual override onlyGovernor {\\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\\n _tick[_liquidity] = observeLiquidity(_liquidity);\\n emit LiquidityApproval(_liquidity);\\n }\\n\\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\\n /// @param _liquidity Address of the liquidity token being observed\\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\\n if (_tick[_liquidity].period == _period(block.timestamp)) {\\n // Will return cached twaps if liquidity is updated\\n _tickCache = _tick[_liquidity];\\n } else {\\n bool success;\\n\\n // Will always ask for 2 accumulators in sidechain\\n uint32[] memory _secondsAgo = new uint32[](2);\\n\\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\\n\\n int56 _tickCumulative2;\\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\\n\\n _tickCache.difference = _tickCache.current - _tickCumulative2;\\n\\n if (success) {\\n _tickCache.period = _period(block.timestamp);\\n } else {\\n delete _tickCache.period;\\n }\\n }\\n }\\n\\n // Keep3rJobsWorkable\\n\\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\\n function worked(address) external pure override {\\n revert Deprecated();\\n }\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Uses a USD per gas unit payment mechanism\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\\n if (_initialGas == 0) revert GasNotInitialized();\\n // Gas used for quote calculations & payment is not rewarded\\n uint256 _gasLeft = _getGasLeft();\\n\\n address _job = msg.sender;\\n if (disputes[_job]) revert JobDisputed();\\n if (!_jobs.contains(_job)) revert JobUnapproved();\\n\\n if (_updateJobCreditsIfNeeded(_job)) {\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\\n\\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\\n\\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\\n _rewardJobCredits(_job);\\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\\n }\\n\\n _bondedPayment(_job, _keeper, _kp3rPayment);\\n delete _initialGas;\\n\\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\\n }\\n\\n // Keep3rKeeperFundable\\n\\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\\n function _depositBonds(uint256 _amount) internal virtual override {\\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\\n }\\n}\\n\",\"keccak256\":\"0x1f1ea4ebcb9327824bbcfd2dfe5cdbd1e9fefec5f91872140ea2438ff100d3f5\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3r.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './peripherals/IKeep3rJobs.sol';\\nimport './peripherals/IKeep3rKeepers.sol';\\nimport './peripherals/IKeep3rParameters.sol';\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rV2 contract\\n/// @notice This contract inherits all the functionality of Keep3rV2\\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\\n\\n}\\n\",\"keccak256\":\"0x273a39984c1475c60182e636bb91a1b89ec98646a036cac6a87067869b3adeb9\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rHelperParameters.sol';\\n\\n/// @title Keep3rHelper contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelper is IKeep3rHelperParameters {\\n // Errors\\n\\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\\n error LiquidityPairInvalid();\\n\\n // Methods\\n // solhint-enable func-name-mixedcase\\n\\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\\n /// @param _eth The amount of ETH\\n /// @return _amountOut The amount of KP3R\\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\\n\\n /// @notice Returns the amount of KP3R the keeper has bonded\\n /// @param _keeper The address of the keeper to check\\n /// @return _amountBonded The amount of KP3R the keeper has bonded\\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\\n /// @param _keeper The address of the keeper to check\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\\n\\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\\n /// @return _rewardBoost The reward boost that corresponds to the keeper\\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\\n\\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\\n /// @param _gasUsed The amount of gas used that will be rewarded\\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\\n\\n /// @notice Given a pool address, returns the underlying tokens of the pair\\n /// @param _pool Address of the correspondant pool\\n /// @return _token0 Address of the first token of the pair\\n /// @return _token1 Address of the second token of the pair\\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\\n\\n /// @notice Defines the order of the tokens in the pair for twap calculations\\n /// @param _pool Address of the correspondant pool\\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\\n\\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\\n /// @param _pool Address of the pool to observe\\n /// @param _secondsAgo Array with time references to observe\\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\\n /// @return _success Boolean indicating if the observe call was succesfull\\n function observe(address _pool, uint32[] memory _secondsAgo)\\n external\\n view\\n returns (\\n int56 _tickCumulative1,\\n int56 _tickCumulative2,\\n bool _success\\n );\\n\\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\\n /// @param _bonds Amount of bonded KP3R owned by the keeper\\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\\n /// @return _extra Amount of extra gas that should be added to the gas spent\\n function getPaymentParams(uint256 _bonds)\\n external\\n view\\n returns (\\n uint256 _boost,\\n uint256 _oneEthQuote,\\n uint256 _extra\\n );\\n\\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\\n /// @param _liquidityAmount Amount of liquidity to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\\n function getKP3RsAtTick(\\n uint256 _liquidityAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _kp3rAmount);\\n\\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\\n /// @param _baseAmount Amount of token to be converted\\n /// @param _tickDifference Tick value used to calculate the quote\\n /// @param _timeInterval Time value used to calculate the quote\\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\\n function getQuoteAtTick(\\n uint128 _baseAmount,\\n int56 _tickDifference,\\n uint256 _timeInterval\\n ) external pure returns (uint256 _quoteAmount);\\n}\\n\",\"keccak256\":\"0x67817dc98fde9b3a917e25bc16fe60a91772dd5a77e0ce22a208b66b29d3ad8e\",\"license\":\"MIT\"},\"solidity/interfaces/IKeep3rHelperParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rHelperParameters contract\\n/// @notice Contains all the helper functions used throughout the different files.\\ninterface IKeep3rHelperParameters {\\n // Structs\\n\\n /// @dev KP3R-WETH Pool address and isKP3RToken0\\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\\n struct Kp3rWethOraclePool {\\n address poolAddress;\\n bool isKP3RToken0;\\n }\\n\\n // Errors\\n\\n /// @notice Throws when pool does not have KP3R as token0 nor token1\\n error InvalidOraclePool();\\n\\n // Events\\n\\n /// @notice Emitted when the kp3r weth pool is changed\\n /// @param _address Address of the new kp3r weth pool\\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\\n\\n /// @notice Emitted when the minimum boost multiplier is changed\\n /// @param _minBoost The minimum boost multiplier\\n event MinBoostChange(uint256 _minBoost);\\n\\n /// @notice Emitted when the maximum boost multiplier is changed\\n /// @param _maxBoost The maximum boost multiplier\\n event MaxBoostChange(uint256 _maxBoost);\\n\\n /// @notice Emitted when the target bond amount is changed\\n /// @param _targetBond The target bond amount\\n event TargetBondChange(uint256 _targetBond);\\n\\n /// @notice Emitted when the Keep3r V2 address is changed\\n /// @param _keep3rV2 The address of Keep3r V2\\n event Keep3rV2Change(address _keep3rV2);\\n\\n /// @notice Emitted when the work extra gas amount is changed\\n /// @param _workExtraGas The work extra gas\\n event WorkExtraGasChange(uint256 _workExtraGas);\\n\\n /// @notice Emitted when the quote twap time is changed\\n /// @param _quoteTwapTime The twap time for quoting\\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\\n\\n /// @notice Emitted when minimum rewarded gas fee is changed\\n /// @param _minBaseFee The minimum rewarded gas fee\\n event MinBaseFeeChange(uint256 _minBaseFee);\\n\\n /// @notice Emitted when minimum rewarded priority fee is changed\\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\\n event MinPriorityFeeChange(uint256 _minPriorityFee);\\n\\n // Variables\\n\\n /// @notice Address of KP3R token\\n /// @return _kp3r Address of KP3R token\\n // solhint-disable func-name-mixedcase\\n function KP3R() external view returns (address _kp3r);\\n\\n /// @notice The boost base used to calculate the boost rewards for the keeper\\n /// @return _base The boost base number\\n function BOOST_BASE() external view returns (uint256 _base);\\n\\n /// @notice KP3R-WETH pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\\n function kp3rWethPool() external view returns (address poolAddress, bool isKP3RToken0);\\n\\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\\n /// @return _multiplier The minimum boost multiplier\\n function minBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\\n /// @return _multiplier The maximum boost multiplier\\n function maxBoost() external view returns (uint256 _multiplier);\\n\\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\\n /// @return _target The amount of KP3R that comforms the targetBond\\n function targetBond() external view returns (uint256 _target);\\n\\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\\n /// @return _workExtraGas The work unaccounted gas amount\\n function workExtraGas() external view returns (uint256 _workExtraGas);\\n\\n /// @notice The twap time for quoting\\n /// @return _quoteTwapTime The twap time\\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\\n\\n /// @notice The minimum base fee that is used to calculate keeper rewards\\n /// @return _minBaseFee The minimum rewarded gas fee\\n function minBaseFee() external view returns (uint256 _minBaseFee);\\n\\n /// @notice The minimum priority fee that is also rewarded for keepers\\n /// @return _minPriorityFee The minimum rewarded priority fee\\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\\n\\n /// @notice Address of Keep3r V2\\n /// @return _keep3rV2 Address of Keep3r V2\\n function keep3rV2() external view returns (address _keep3rV2);\\n\\n // Methods\\n\\n /// @notice Sets KP3R-WETH pool\\n /// @param _poolAddress The address of the KP3R-WETH pool\\n function setKp3rWethPool(address _poolAddress) external;\\n\\n /// @notice Sets the minimum boost multiplier\\n /// @param _minBoost The minimum boost multiplier\\n function setMinBoost(uint256 _minBoost) external;\\n\\n /// @notice Sets the maximum boost multiplier\\n /// @param _maxBoost The maximum boost multiplier\\n function setMaxBoost(uint256 _maxBoost) external;\\n\\n /// @notice Sets the target bond amount\\n /// @param _targetBond The target bond amount\\n function setTargetBond(uint256 _targetBond) external;\\n\\n /// @notice Sets the Keep3r V2 address\\n /// @param _keep3rV2 The address of Keep3r V2\\n function setKeep3rV2(address _keep3rV2) external;\\n\\n /// @notice Sets the work extra gas amount\\n /// @param _workExtraGas The work extra gas\\n function setWorkExtraGas(uint256 _workExtraGas) external;\\n\\n /// @notice Sets the quote twap time\\n /// @param _quoteTwapTime The twap time for quoting\\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\\n\\n /// @notice Sets the minimum rewarded gas fee\\n /// @param _minBaseFee The minimum rewarded gas fee\\n function setMinBaseFee(uint256 _minBaseFee) external;\\n\\n /// @notice Sets the minimum rewarded gas priority fee\\n /// @param _minPriorityFee The minimum rewarded priority fee\\n function setMinPriorityFee(uint256 _minPriorityFee) external;\\n}\\n\",\"keccak256\":\"0xc571e913c0e3c02f4aa0b27090ca1608c85c68768dc2ab979f8aef7c731f60b2\",\"license\":\"MIT\"},\"solidity/interfaces/IPairManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n/// @title Pair Manager interface\\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\\ninterface IPairManager is IERC20Metadata {\\n /// @notice Address of the factory from which the pair manager was created\\n /// @return _factory The address of the PairManager Factory\\n function factory() external view returns (address _factory);\\n\\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\\n /// @return _pool The address of the pool\\n function pool() external view returns (address _pool);\\n\\n /// @notice Token0 of the pool\\n /// @return _token0 The address of token0\\n function token0() external view returns (address _token0);\\n\\n /// @notice Token1 of the pool\\n /// @return _token1 The address of token1\\n function token1() external view returns (address _token1);\\n}\\n\",\"keccak256\":\"0x345c312b340c5775fb8f68d89ce851c7f75522940bd9bc64f2301a3f8312636a\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\n\\n// solhint-disable func-name-mixedcase\\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\\n // Structs\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint256 votes;\\n }\\n\\n // Events\\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\\n event JobAdded(address indexed _job, uint256 _block, address _governance);\\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\\n event KeeperDispute(address indexed _keeper, uint256 _block);\\n event KeeperResolved(address indexed _keeper, uint256 _block);\\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\\n\\n // Variables\\n function KPRH() external returns (address);\\n\\n function delegates(address _delegator) external view returns (address);\\n\\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\\n\\n function numCheckpoints(address _account) external view returns (uint32);\\n\\n function DOMAIN_TYPEHASH() external returns (bytes32);\\n\\n function DOMAINSEPARATOR() external returns (bytes32);\\n\\n function DELEGATION_TYPEHASH() external returns (bytes32);\\n\\n function PERMIT_TYPEHASH() external returns (bytes32);\\n\\n function nonces(address _user) external view returns (uint256);\\n\\n function BOND() external returns (uint256);\\n\\n function UNBOND() external returns (uint256);\\n\\n function LIQUIDITYBOND() external returns (uint256);\\n\\n function FEE() external returns (uint256);\\n\\n function BASE() external returns (uint256);\\n\\n function ETH() external returns (address);\\n\\n function bondings(address _user, address _bonding) external view returns (uint256);\\n\\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\\n\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function bonds(address _keeper, address _bonding) external view returns (uint256);\\n\\n function votes(address _delegator) external view returns (uint256);\\n\\n function firstSeen(address _keeper) external view returns (uint256);\\n\\n function disputes(address _keeper) external view returns (bool);\\n\\n function lastJob(address _keeper) external view returns (uint256);\\n\\n function workCompleted(address _keeper) external view returns (uint256);\\n\\n function jobs(address _job) external view returns (bool);\\n\\n function credits(address _job, address _credit) external view returns (uint256);\\n\\n function liquidityProvided(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmountsUnbonding(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function jobProposalDelay(address _job) external view returns (uint256);\\n\\n function liquidityApplied(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function liquidityAmount(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external view returns (uint256);\\n\\n function keepers(address _keeper) external view returns (bool);\\n\\n function blacklist(address _keeper) external view returns (bool);\\n\\n function keeperList(uint256 _index) external view returns (address);\\n\\n function jobList(uint256 _index) external view returns (address);\\n\\n function governance() external returns (address);\\n\\n function pendingGovernance() external returns (address);\\n\\n function liquidityAccepted(address _liquidity) external view returns (bool);\\n\\n function liquidityPairs(uint256 _index) external view returns (address);\\n\\n // Methods\\n function getCurrentVotes(address _account) external view returns (uint256);\\n\\n function addCreditETH(address _job) external payable;\\n\\n function addCredit(\\n address _credit,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function pairs() external view returns (address[] memory);\\n\\n function addLiquidityToJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function applyCreditToJob(\\n address _provider,\\n address _liquidity,\\n address _job\\n ) external;\\n\\n function unbondLiquidityFromJob(\\n address _liquidity,\\n address _job,\\n uint256 _amount\\n ) external;\\n\\n function removeLiquidityFromJob(address _liquidity, address _job) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function burn(uint256 _amount) external;\\n\\n function worked(address _keeper) external;\\n\\n function receipt(\\n address _credit,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function receiptETH(address _keeper, uint256 _amount) external;\\n\\n function addJob(address _job) external;\\n\\n function getJobs() external view returns (address[] memory);\\n\\n function removeJob(address _job) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function isKeeper(address _keeper) external returns (bool);\\n\\n function isMinKeeper(\\n address _keeper,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool);\\n\\n function bond(address _bonding, uint256 _amount) external;\\n\\n function getKeepers() external view returns (address[] memory);\\n\\n function activate(address _bonding) external;\\n\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function withdraw(address _bonding) external;\\n\\n function dispute(address _keeper) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function permit(\\n address _owner,\\n address _spender,\\n uint256 _amount,\\n uint256 _deadline,\\n uint8 _v,\\n bytes32 _r,\\n bytes32 _s\\n ) external;\\n}\\n\",\"keccak256\":\"0xa9806cd6666ab1b7375ef72446964a72397fd4cefc7cc8c5b37caa7c50df0246\",\"license\":\"MIT\"},\"solidity/interfaces/external/IKeep3rV1Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\n\\ninterface IKeep3rV1Proxy is IBaseErrors {\\n // Structs\\n struct Recipient {\\n address recipient;\\n uint256 caps;\\n }\\n\\n // Variables\\n function keep3rV1() external view returns (address);\\n\\n function governance() external view returns (address);\\n\\n function pendingGovernance() external view returns (address);\\n\\n function minter() external view returns (address);\\n\\n function next(address) external view returns (uint256);\\n\\n function caps(address) external view returns (uint256);\\n\\n function recipients() external view returns (address[] memory);\\n\\n function recipientsCaps() external view returns (Recipient[] memory);\\n\\n // Errors\\n error Cooldown();\\n error NoDrawableAmount();\\n error OnlyMinter();\\n error OnlyGovernance();\\n error OnlyPendingGovernance();\\n\\n // Methods\\n function addRecipient(address recipient, uint256 amount) external;\\n\\n function removeRecipient(address recipient) external;\\n\\n function draw() external returns (uint256 _amount);\\n\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n function setMinter(address _minter) external;\\n\\n function mint(uint256 _amount) external;\\n\\n function mint(address _account, uint256 _amount) external;\\n\\n function setGovernance(address _governance) external;\\n\\n function acceptGovernance() external;\\n\\n function setKeep3rV1Governance(address _governance) external;\\n\\n function acceptKeep3rV1Governance() external;\\n\\n function dispute(address _keeper) external;\\n\\n function slash(\\n address _bonded,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n\\n function revoke(address _keeper) external;\\n\\n function resolve(address _keeper) external;\\n\\n function addJob(address _job) external;\\n\\n function removeJob(address _job) external;\\n\\n function addKPRCredit(address _job, uint256 _amount) external;\\n\\n function approveLiquidity(address _liquidity) external;\\n\\n function revokeLiquidity(address _liquidity) external;\\n\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n function addVotes(address _voter, uint256 _amount) external;\\n\\n function removeVotes(address _voter, uint256 _amount) external;\\n}\\n\",\"keccak256\":\"0x8d00752ec08a8e550cbcccd7c1032a4cb95e58cdfa9f977cf7f1e00b637f0d95\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rRoles.sol';\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\\ninterface IKeep3rAccountance is IKeep3rRoles {\\n // Events\\n\\n /// @notice Emitted when the bonding process of a new keeper begins\\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\\n /// @param _bonding The asset the keeper has bonded\\n /// @param _amount The amount the keeper has bonded\\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\\n\\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\\n /// @param _keeperOrJob The keeper or job that began the unbonding process\\n /// @param _unbonding The liquidity pair or asset being unbonded\\n /// @param _amount The amount being unbonded\\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\\n\\n // Variables\\n\\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\\n function totalBonds() external view returns (uint256 _totalBonds);\\n\\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\\n /// @param _keeper The address of the keeper\\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\\n\\n /// @notice Tracks when a keeper was first registered\\n /// @param _keeper The address of the keeper\\n /// @return timestamp The time at which the keeper was first registered\\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\\n\\n /// @notice Tracks if a keeper or job has a pending dispute\\n /// @param _keeperOrJob The address of the keeper or job\\n /// @return _disputed Whether a keeper or job has a pending dispute\\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\\n\\n /// @notice Tracks how much a keeper has bonded of a certain token\\n /// @param _keeper The address of the keeper\\n /// @param _bond The address of the token being bonded\\n /// @return _bonds Amount of a certain token that a keeper has bonded\\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\\n\\n /// @notice The current token credits available for a job\\n /// @param _job The address of the job\\n /// @param _token The address of the token bonded\\n /// @return _amount The amount of token credits available for a job\\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\\n\\n /// @notice Tracks the amount of assets deposited in pending bonds\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\\n\\n /// @notice Tracks when a bonding for a keeper can be activated\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being bonded\\n /// @return _timestamp Time at which the bonding for a keeper can be activated\\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks when keeper bonds are ready to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\\n\\n /// @notice Tracks how much keeper bonds are to be withdrawn\\n /// @param _keeper The address of the keeper\\n /// @param _bonding The address of the token being unbonded\\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\\n\\n /// @notice Checks whether the address has ever bonded an asset\\n /// @param _keeper The address of the keeper\\n /// @return _hasBonded Whether the address has ever bonded an asset\\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\\n\\n // Methods\\n\\n /// @notice Lists all jobs\\n /// @return _jobList Array with all the jobs in _jobs\\n function jobs() external view returns (address[] memory _jobList);\\n\\n /// @notice Lists all keepers\\n /// @return _keeperList Array with all the keepers in _keepers\\n function keepers() external view returns (address[] memory _keeperList);\\n\\n // Errors\\n\\n /// @notice Throws when an address is passed as a job, but that address is not a job\\n error JobUnavailable();\\n\\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\\n error JobDisputed();\\n}\\n\",\"keccak256\":\"0xf4748c236ddf409e45e7169c735e2fc54e627b2b3ccd189ebb438ad768f1deb1\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rDisputable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title Keep3rDisputable contract\\n/// @notice Creates/resolves disputes for jobs or keepers\\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\\ninterface IKeep3rDisputable {\\n /// @notice Emitted when a keeper or a job is disputed\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _disputer The user that called the function and disputed the keeper\\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\\n\\n /// @notice Emitted when a dispute is resolved\\n /// @param _jobOrKeeper The address of the disputed keeper/job\\n /// @param _resolver The user that called the function and resolved the dispute\\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\\n\\n /// @notice Throws when a job or keeper is already disputed\\n error AlreadyDisputed();\\n\\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\\n error NotDisputed();\\n\\n /// @notice Allows governor to create a dispute for a given keeper/job\\n /// @param _jobOrKeeper The address in dispute\\n function dispute(address _jobOrKeeper) external;\\n\\n /// @notice Allows governor to resolve a dispute on a keeper/job\\n /// @param _jobOrKeeper The address cleared\\n function resolve(address _jobOrKeeper) external;\\n}\\n\",\"keccak256\":\"0xdfdabcecbed06fcb2eb1b80e6a61d681afecd1f75c58a888451de7927b10c3b2\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rJobs.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rJobOwnership contract\\n/// @notice Handles the ownership of the jobs\\ninterface IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\\n /// @param _job The address of the job proposed to have a change of owner\\n /// @param _owner The current owner of the job\\n /// @param _pendingOwner The new address proposed to be the owner of the job\\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\\n\\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\\n /// @param _job The address of the job which the proposed owner will now own\\n /// @param _previousOwner The previous owner of the job\\n /// @param _newOwner The new owner of the job\\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\\n\\n // Errors\\n\\n /// @notice Throws when the caller of the function is not the job owner\\n error OnlyJobOwner();\\n\\n /// @notice Throws when the caller of the function is not the pending job owner\\n error OnlyPendingJobOwner();\\n\\n // Variables\\n\\n /// @notice Maps the job to the owner of the job\\n /// @param _job The address of the job\\n /// @return _owner The address of the owner of the job\\n function jobOwner(address _job) external view returns (address _owner);\\n\\n /// @notice Maps the job to its pending owner\\n /// @param _job The address of the job\\n /// @return _pendingOwner The address of the pending owner of the job\\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\\n\\n // Methods\\n\\n /// @notice Proposes a new address to be the owner of the job\\n /// @param _job The address of the job\\n /// @param _newOwner The address of the proposed new owner\\n function changeJobOwnership(address _job, address _newOwner) external;\\n\\n /// @notice The proposed address accepts to be the owner of the job\\n /// @param _job The address of the job\\n function acceptJobOwnership(address _job) external;\\n}\\n\\n/// @title Keep3rJobManager contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobManager#addJob is called\\n /// @param _job The address of the job to add\\n /// @param _jobOwner The job's owner\\n event JobAddition(address indexed _job, address indexed _jobOwner);\\n\\n // Errors\\n\\n /// @notice Throws when trying to add a job that has already been added\\n error JobAlreadyAdded();\\n\\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\\n error AlreadyAKeeper();\\n\\n // Methods\\n\\n /// @notice Allows any caller to add a new job\\n /// @param _job Address of the contract for which work should be performed\\n function addJob(address _job) external;\\n}\\n\\n/// @title Keep3rJobFundableCredits contract\\n/// @notice Handles the addition and withdrawal of credits from a job\\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being provided\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of credit being added to the job\\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The credit being withdrawn from the job\\n /// @param _receiver The user that receives the tokens\\n /// @param _amount The amount of credit withdrawn\\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\\n error TokenUnallowed();\\n\\n /// @notice Throws when the token withdraw cooldown has not yet passed\\n error JobTokenCreditsLocked();\\n\\n /// @notice Throws when the user tries to withdraw more tokens than it has\\n error InsufficientJobTokenCredits();\\n\\n // Variables\\n\\n /// @notice Last block where tokens were added to the job\\n /// @param _job The address of the job credited\\n /// @param _token The address of the token credited\\n /// @return _timestamp The last block where tokens were added to the job\\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Add credit to a job to be paid out for work\\n /// @param _job The address of the job being credited\\n /// @param _token The address of the token being credited\\n /// @param _amount The amount of credit being added\\n function addTokenCreditsToJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw credit from a job\\n /// @param _job The address of the job from which the credits are withdrawn\\n /// @param _token The address of the token being withdrawn\\n /// @param _amount The amount of token to be withdrawn\\n /// @param _receiver The user that will receive tokens\\n function withdrawTokenCreditsFromJob(\\n address _job,\\n address _token,\\n uint256 _amount,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobFundableLiquidity contract\\n/// @notice Handles the funding of jobs through specific liquidity pairs\\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being approved\\n event LiquidityApproval(address _liquidity);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\\n /// @param _liquidity The address of the liquidity pair being revoked\\n event LiquidityRevocation(address _liquidity);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job to which liquidity will be added\\n /// @param _liquidity The address of the liquidity being added\\n /// @param _provider The user that calls the function\\n /// @param _amount The amount of liquidity being added\\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\\n\\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\\n /// @param _job The address of the job of which liquidity will be withdrawn from\\n /// @param _liquidity The address of the liquidity being withdrawn\\n /// @param _receiver The receiver of the liquidity tokens\\n /// @param _amount The amount of liquidity being withdrawn from the job\\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n /// @param _periodCredits The credits of the job for the current period\\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\\n\\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\\n /// @param _job The address of the job whose credits will be updated\\n /// @param _rewardedAt The time at which the job was last rewarded\\n /// @param _currentCredits The current credits of the job\\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\\n\\n // Errors\\n\\n /// @notice Throws when the liquidity being approved has already been approved\\n error LiquidityPairApproved();\\n\\n /// @notice Throws when the liquidity being removed has not been approved\\n error LiquidityPairUnexistent();\\n\\n /// @notice Throws when trying to add liquidity to an unapproved pool\\n error LiquidityPairUnapproved();\\n\\n /// @notice Throws when the job doesn't have the requested liquidity\\n error JobLiquidityUnexistent();\\n\\n /// @notice Throws when trying to remove more liquidity than the job has\\n error JobLiquidityInsufficient();\\n\\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\\n error JobLiquidityLessThanMin();\\n\\n // Structs\\n\\n /// @notice Stores the tick information of the different liquidity pairs\\n struct TickCache {\\n int56 current; // Tracks the current tick\\n int56 difference; // Stores the difference between the current tick and the last tick\\n uint256 period; // Stores the period at which the last observation was made\\n }\\n\\n // Variables\\n\\n /// @notice Lists liquidity pairs\\n /// @return _list An array of addresses with all the approved liquidity pairs\\n function approvedLiquidities() external view returns (address[] memory _list);\\n\\n /// @notice Amount of liquidity in a specified job\\n /// @param _job The address of the job being checked\\n /// @param _liquidity The address of the liquidity we are checking\\n /// @return _amount Amount of liquidity in the specified job\\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\\n\\n /// @notice Last time the job was rewarded liquidity credits\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\\n\\n /// @notice Last time the job was worked\\n /// @param _job The address of the job being checked\\n /// @return _timestamp Timestamp of the last time the job was worked\\n function workedAt(address _job) external view returns (uint256 _timestamp);\\n\\n // Methods\\n\\n /// @notice Returns the liquidity credits of a given job\\n /// @param _job The address of the job of which we want to know the liquidity credits\\n /// @return _amount The liquidity credits of a given job\\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Returns the credits of a given job for the current period\\n /// @param _job The address of the job of which we want to know the period credits\\n /// @return _amount The credits the given job has at the current period\\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates the total credits of a given job\\n /// @param _job The address of the job of which we want to know the total credits\\n /// @return _amount The total credits of the given job\\n function totalJobCredits(address _job) external view returns (uint256 _amount);\\n\\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\\n /// @param _liquidity The address of the liquidity to provide\\n /// @param _amount The amount of liquidity to provide\\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\\n\\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\\n /// @param _liquidity The address of the liquidity pair being observed\\n /// @return _tickCache The updated TickCache\\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\\n\\n /// @notice Gifts liquidity credits to the specified job\\n /// @param _job The address of the job being credited\\n /// @param _amount The amount of liquidity credits to gift\\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\\n\\n /// @notice Approve a liquidity pair for being accepted in future\\n /// @param _liquidity The address of the liquidity accepted\\n function approveLiquidity(address _liquidity) external;\\n\\n /// @notice Revoke a liquidity pair from being accepted in future\\n /// @param _liquidity The liquidity no longer accepted\\n function revokeLiquidity(address _liquidity) external;\\n\\n /// @notice Allows anyone to fund a job with liquidity\\n /// @param _job The address of the job to assign liquidity to\\n /// @param _liquidity The liquidity being added\\n /// @param _amount The amount of liquidity tokens to add\\n function addLiquidityToJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Unbond liquidity for a job\\n /// @dev Can only be called by the job's owner\\n /// @param _job The address of the job being unbonded from\\n /// @param _liquidity The liquidity being unbonded\\n /// @param _amount The amount of liquidity being removed\\n function unbondLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Withdraw liquidity from a job\\n /// @param _job The address of the job being withdrawn from\\n /// @param _liquidity The liquidity being withdrawn\\n /// @param _receiver The address that will receive the withdrawn liquidity\\n function withdrawLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n address _receiver\\n ) external;\\n}\\n\\n/// @title Keep3rJobMigration contract\\n/// @notice Handles the migration process of jobs to different addresses\\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\\n /// @param _fromJob The address of the job that requests to migrate\\n /// @param _toJob The address at which the job requests to migrate\\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\\n\\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address at which the job had requested to migrate\\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\\n\\n // Errors\\n\\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\\n error JobMigrationImpossible();\\n\\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\\n error JobMigrationUnavailable();\\n\\n /// @notice Throws when cooldown between migrations has not yet passed\\n error JobMigrationLocked();\\n\\n // Variables\\n\\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\\n /// @return _toJob The address to which the job has requested to migrate to\\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\\n\\n // Methods\\n\\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\\n /// @param _fromJob The address of the job that is requesting to migrate\\n /// @param _toJob The address at which the job is requesting to migrate\\n function migrateJob(address _fromJob, address _toJob) external;\\n\\n /// @notice Completes the migration process for a job\\n /// @dev Unbond/withdraw process doesn't get migrated\\n /// @param _fromJob The address of the job that requested to migrate\\n /// @param _toJob The address to which the job wants to migrate to\\n function acceptJobMigration(address _fromJob, address _toJob) external;\\n}\\n\\n/// @title Keep3rJobWorkable contract\\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\\n // Events\\n\\n /// @notice Emitted when a keeper is validated before a job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\\n event KeeperValidation(uint256 _gasLeft);\\n\\n /// @notice Emitted when a keeper works a job\\n /// @param _credit The address of the asset in which the keeper is paid\\n /// @param _job The address of the job the keeper has worked\\n /// @param _keeper The address of the keeper that has worked the job\\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\\n\\n // Errors\\n\\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\\n error GasNotInitialized();\\n\\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\\n error JobUnapproved();\\n\\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\\n error InsufficientFunds();\\n\\n // Methods\\n\\n /// @notice Confirms if the current keeper is registered\\n /// @dev Can be used for general (non critical) functions\\n /// @param _keeper The keeper being investigated\\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\\n function isKeeper(address _keeper) external returns (bool _isKeeper);\\n\\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\\n /// @dev Should be used for protected functions\\n /// @param _keeper The keeper to check\\n /// @param _bond The bond token being evaluated\\n /// @param _minBond The minimum amount of bonded tokens\\n /// @param _earned The minimum funds earned in the keepers lifetime\\n /// @param _age The minimum keeper age required\\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\\n function isBondedKeeper(\\n address _keeper,\\n address _bond,\\n uint256 _minBond,\\n uint256 _earned,\\n uint256 _age\\n ) external returns (bool _isBondedKeeper);\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n function worked(address _keeper) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _payment The reward that should be allocated for the job\\n function bondedPayment(address _keeper, uint256 _payment) external;\\n\\n /// @notice Implemented by jobs to show that a keeper performed work\\n /// @dev Pays the keeper that performs the work with a specific token\\n /// @param _token The asset being awarded to the keeper\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _amount The reward that should be allocated\\n function directTokenPayment(\\n address _token,\\n address _keeper,\\n uint256 _amount\\n ) external;\\n}\\n\\n/// @title Keep3rJobDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed job\\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\\n // Events\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token being slashed\\n /// @param _slasher The user that slashes the token\\n /// @param _amount The amount of the token being slashed\\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\\n /// @param _job The address of the job from which the liquidity will be slashed\\n /// @param _liquidity The address of the liquidity being slashed\\n /// @param _slasher The user that slashes the liquidity\\n /// @param _amount The amount of the liquidity being slashed\\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the token trying to be slashed doesn't exist\\n error JobTokenUnexistent();\\n\\n /// @notice Throws when someone tries to slash more tokens than the job has\\n error JobTokenInsufficient();\\n\\n // Methods\\n\\n /// @notice Allows governor or slasher to slash a job specific token\\n /// @param _job The address of the job from which the token will be slashed\\n /// @param _token The address of the token that will be slashed\\n /// @param _amount The amount of the token that will be slashed\\n function slashTokenFromJob(\\n address _job,\\n address _token,\\n uint256 _amount\\n ) external;\\n\\n /// @notice Allows governor or slasher to slash liquidity from a job\\n /// @param _job The address being slashed\\n /// @param _liquidity The address of the liquidity that will be slashed\\n /// @param _amount The amount of liquidity that will be slashed\\n function slashLiquidityFromJob(\\n address _job,\\n address _liquidity,\\n uint256 _amount\\n ) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\\n\\n}\\n\",\"keccak256\":\"0x7fb7153d88e9e65d28b278320884517d6b423b2e8cfc78ee0ee16bc04073278e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rKeepers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rDisputable.sol';\\n\\n/// @title Keep3rKeeperFundable contract\\n/// @notice Handles the actions required to become a keeper\\ninterface IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\\n /// @param _keeper The keeper that has been activated\\n /// @param _bond The asset the keeper has bonded\\n /// @param _amount The amount of the asset the keeper has bonded\\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\\n /// @param _bond The asset to withdraw from the bonding pool\\n /// @param _amount The amount of funds withdrawn\\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws when the address that is trying to register as a job is already a job\\n error AlreadyAJob();\\n\\n // Methods\\n\\n /// @notice Beginning of the bonding process\\n /// @param _bonding The asset being bonded\\n /// @param _amount The amount of bonding asset being bonded\\n function bond(address _bonding, uint256 _amount) external;\\n\\n /// @notice Beginning of the unbonding process\\n /// @param _bonding The asset being unbonded\\n /// @param _amount Allows for partial unbonding\\n function unbond(address _bonding, uint256 _amount) external;\\n\\n /// @notice End of the bonding process after bonding time has passed\\n /// @param _bonding The asset being activated as bond collateral\\n function activate(address _bonding) external;\\n\\n /// @notice Withdraw funds after unbonding has finished\\n /// @param _bonding The asset to withdraw from the bonding pool\\n function withdraw(address _bonding) external;\\n}\\n\\n/// @title Keep3rKeeperDisputable contract\\n/// @notice Handles the actions that can be taken on a disputed keeper\\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\\n // Events\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\\n /// @param _keeper The address of the slashed keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\\n /// @param _amount The amount of credits slashed from the keeper\\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\\n /// @param _keeper The address of the revoked keeper\\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\\n\\n // Methods\\n\\n /// @notice Allows governor to slash a keeper based on a dispute\\n /// @param _keeper The address being slashed\\n /// @param _bonded The asset being slashed\\n /// @param _bondAmount The bonded amount being slashed\\n /// @param _unbondAmount The pending unbond amount being slashed\\n function slash(\\n address _keeper,\\n address _bonded,\\n uint256 _bondAmount,\\n uint256 _unbondAmount\\n ) external;\\n\\n /// @notice Blacklists a keeper from participating in the network\\n /// @param _keeper The address being slashed\\n function revoke(address _keeper) external;\\n}\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\n/// @title Keep3rKeepers contract\\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\\n\\n}\\n\",\"keccak256\":\"0x8fe10565035bb918b2b1c7d730533bcfe9ec79078f28544852f8178e76302562\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rParameters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport './IKeep3rAccountance.sol';\\n\\n/// @title Keep3rParameters contract\\n/// @notice Handles and sets all the required parameters for Keep3r\\ninterface IKeep3rParameters is IKeep3rAccountance {\\n // Events\\n\\n /// @notice Emitted when the Keep3rHelper address is changed\\n /// @param _keep3rHelper The address of Keep3rHelper's contract\\n event Keep3rHelperChange(address _keep3rHelper);\\n\\n /// @notice Emitted when the Keep3rV1 address is changed\\n /// @param _keep3rV1 The address of Keep3rV1's contract\\n event Keep3rV1Change(address _keep3rV1);\\n\\n /// @notice Emitted when the Keep3rV1Proxy address is changed\\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\\n\\n /// @notice Emitted when bondTime is changed\\n /// @param _bondTime The new bondTime\\n event BondTimeChange(uint256 _bondTime);\\n\\n /// @notice Emitted when _liquidityMinimum is changed\\n /// @param _liquidityMinimum The new _liquidityMinimum\\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\\n\\n /// @notice Emitted when _unbondTime is changed\\n /// @param _unbondTime The new _unbondTime\\n event UnbondTimeChange(uint256 _unbondTime);\\n\\n /// @notice Emitted when _rewardPeriodTime is changed\\n /// @param _rewardPeriodTime The new _rewardPeriodTime\\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\\n\\n /// @notice Emitted when the inflationPeriod is changed\\n /// @param _inflationPeriod The new inflationPeriod\\n event InflationPeriodChange(uint256 _inflationPeriod);\\n\\n /// @notice Emitted when the fee is changed\\n /// @param _fee The new token credits fee\\n event FeeChange(uint256 _fee);\\n\\n // Variables\\n\\n /// @notice Address of Keep3rHelper's contract\\n /// @return _keep3rHelper The address of Keep3rHelper's contract\\n function keep3rHelper() external view returns (address _keep3rHelper);\\n\\n /// @notice Address of Keep3rV1's contract\\n /// @return _keep3rV1 The address of Keep3rV1's contract\\n function keep3rV1() external view returns (address _keep3rV1);\\n\\n /// @notice Address of Keep3rV1Proxy's contract\\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\\n\\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\\n /// @return _days The required bondTime in days\\n function bondTime() external view returns (uint256 _days);\\n\\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\\n /// @return _days The required unbondTime in days\\n function unbondTime() external view returns (uint256 _days);\\n\\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\\n /// @return _amount The minimum amount of liquidity in KP3R\\n function liquidityMinimum() external view returns (uint256 _amount);\\n\\n /// @notice The amount of time between each scheduled credits reward given to a job\\n /// @return _days The reward period in days\\n function rewardPeriodTime() external view returns (uint256 _days);\\n\\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\\n /// @return _period The denominator used to regulate the emission of KP3R\\n function inflationPeriod() external view returns (uint256 _period);\\n\\n /// @notice The fee to be sent to governor when a user adds liquidity to a job\\n /// @return _amount The fee amount to be sent to governor when a user adds liquidity to a job\\n function fee() external view returns (uint256 _amount);\\n\\n // Errors\\n\\n /// @notice Throws if the reward period is less than the minimum reward period time\\n error MinRewardPeriod();\\n\\n /// @notice Throws if either a job or a keeper is disputed\\n error Disputed();\\n\\n /// @notice Throws if there are no bonded assets\\n error BondsUnexistent();\\n\\n /// @notice Throws if the time required to bond an asset has not passed yet\\n error BondsLocked();\\n\\n /// @notice Throws if there are no bonds to withdraw\\n error UnbondsUnexistent();\\n\\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\\n error UnbondsLocked();\\n\\n // Methods\\n\\n /// @notice Sets the Keep3rHelper address\\n /// @param _keep3rHelper The Keep3rHelper address\\n function setKeep3rHelper(address _keep3rHelper) external;\\n\\n /// @notice Sets the Keep3rV1 address\\n /// @param _keep3rV1 The Keep3rV1 address\\n function setKeep3rV1(address _keep3rV1) external;\\n\\n /// @notice Sets the Keep3rV1Proxy address\\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\\n\\n /// @notice Sets the bond time required to activate as a keeper\\n /// @param _bond The new bond time\\n function setBondTime(uint256 _bond) external;\\n\\n /// @notice Sets the unbond time required unbond what has been bonded\\n /// @param _unbond The new unbond time\\n function setUnbondTime(uint256 _unbond) external;\\n\\n /// @notice Sets the minimum amount of liquidity required to fund a job\\n /// @param _liquidityMinimum The new minimum amount of liquidity\\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\\n\\n /// @notice Sets the time required to pass between rewards for jobs\\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\\n\\n /// @notice Sets the new inflation period\\n /// @param _inflationPeriod The new inflation period\\n function setInflationPeriod(uint256 _inflationPeriod) external;\\n\\n /// @notice Sets the new fee\\n /// @param _fee The new fee\\n function setFee(uint256 _fee) external;\\n}\\n\",\"keccak256\":\"0x2a847a2ab6dbee960ca84e142ad9c578d8953c4adf1d3221669400ea86c9b82e\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IKeep3rRoles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IDustCollector.sol';\\n\\n/// @title Keep3rRoles contract\\n/// @notice Manages the Keep3r specific roles\\ninterface IKeep3rRoles is IBaseErrors, IGovernable, IDustCollector {\\n // Events\\n\\n /// @notice Emitted when a slasher is added\\n /// @param _slasher Address of the added slasher\\n event SlasherAdded(address _slasher);\\n\\n /// @notice Emitted when a slasher is removed\\n /// @param _slasher Address of the removed slasher\\n event SlasherRemoved(address _slasher);\\n\\n /// @notice Emitted when a disputer is added\\n /// @param _disputer Address of the added disputer\\n event DisputerAdded(address _disputer);\\n\\n /// @notice Emitted when a disputer is removed\\n /// @param _disputer Address of the removed disputer\\n event DisputerRemoved(address _disputer);\\n\\n // Variables\\n\\n /// @notice Tracks whether the address is a slasher or not\\n /// @param _slasher Address being checked as a slasher\\n /// @return _isSlasher Whether the address is a slasher or not\\n function slashers(address _slasher) external view returns (bool _isSlasher);\\n\\n /// @notice Tracks whether the address is a disputer or not\\n /// @param _disputer Address being checked as a disputer\\n /// @return _isDisputer Whether the address is a disputer or not\\n function disputers(address _disputer) external view returns (bool _isDisputer);\\n\\n // Errors\\n\\n /// @notice Throws if the address is already a registered slasher\\n error SlasherExistent();\\n\\n /// @notice Throws if caller is not a registered slasher\\n error SlasherUnexistent();\\n\\n /// @notice Throws if the address is already a registered disputer\\n error DisputerExistent();\\n\\n /// @notice Throws if caller is not a registered disputer\\n error DisputerUnexistent();\\n\\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\\n error OnlySlasher();\\n\\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\\n error OnlyDisputer();\\n\\n // Methods\\n\\n /// @notice Registers a slasher by updating the slashers mapping\\n function addSlasher(address _slasher) external;\\n\\n /// @notice Removes a slasher by updating the slashers mapping\\n function removeSlasher(address _slasher) external;\\n\\n /// @notice Registers a disputer by updating the disputers mapping\\n function addDisputer(address _disputer) external;\\n\\n /// @notice Removes a disputer by updating the disputers mapping\\n function removeDisputer(address _disputer) external;\\n}\\n\",\"keccak256\":\"0xc0a19b0dfac535cbffabc0d76cb0569618dedb922b0413bc12358efa47dc32bf\",\"license\":\"MIT\"},\"solidity/interfaces/peripherals/IMintable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\\n\\n/// @title Mintable contract\\n/// @notice Manages the minter role\\ninterface IMintable is IBaseErrors, IGovernable {\\n // Events\\n\\n /// @notice Emitted when governor sets a new minter\\n /// @param _minter Address of the new minter\\n event MinterSet(address _minter);\\n\\n // Errors\\n\\n /// @notice Throws if the caller of the function is not the minter\\n error OnlyMinter();\\n\\n // Variables\\n\\n /// @notice Stores the minter address\\n /// @return _minter The minter addresss\\n function minter() external view returns (address _minter);\\n\\n // Methods\\n\\n /// @notice Sets a new address to be the minter\\n /// @param _minter The address set as the minter\\n function setMinter(address _minter) external;\\n}\\n\",\"keccak256\":\"0x0048c141d747eb1b0e9391ac9e13c268f858f2fec939c597992742e7a5e71597\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rEscrow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n// solhint-disable-next-line no-empty-blocks\\n\\nimport '../peripherals/IMintable.sol';\\n\\n/// @title Keep3rEscrow contract\\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\\ninterface IKeep3rEscrow is IMintable {\\n /// @notice Emitted when Keep3rEscrow#deposit function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _sender The address that called the function\\n /// @param _amount The amount of wKP3R the user deposited\\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#mint function is called\\n /// @param _wKP3R The addess of the wrapped KP3R token\\n /// @param _recipient The address that will received the newly minted wKP3R\\n /// @param _amount The amount of wKP3R minted to the recipient\\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\\n\\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\\n /// @param _newWKP3R The address of the wKP3R contract\\n event wKP3RSet(address _newWKP3R);\\n\\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\\n error InsufficientBalance();\\n\\n /// @notice Lists the address of the wKP3R contract\\n /// @return _wKP3RAddress The address of wKP3R\\n function wKP3R() external view returns (address _wKP3RAddress);\\n\\n /// @notice Deposits wKP3R into the contract\\n /// @param _amount The amount of wKP3R to deposit\\n function deposit(uint256 _amount) external;\\n\\n /// @notice mints wKP3R to the recipient\\n /// @param _amount The amount of wKP3R to mint\\n function mint(uint256 _amount) external;\\n\\n /// @notice sets the wKP3R address\\n /// @param _wKP3R the wKP3R address\\n function setWKP3R(address _wKP3R) external;\\n}\\n\",\"keccak256\":\"0xf4796dde1afba7f50805aeae92ac0a4848525aeca8355d9b1c6b36c15cca4322\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../IKeep3rHelper.sol';\\n\\n/// @title Keep3rHelperSidechain contract\\n/// @notice Contains all the helper functions for sidechain keep3r implementations\\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\\n // Structs\\n\\n /// @dev WETH-USD Pool address, isWETHToken0 and usdDecimals\\n /// @dev Created in order to quote any kind of USD tokens\\n struct WethUsdOraclePool {\\n address poolAddress;\\n bool isWETHToken0;\\n uint8 usdDecimals;\\n }\\n\\n // Events\\n\\n /// @notice The oracle for a liquidity has been saved\\n /// @param _liquidity The address of the given liquidity\\n /// @param _oraclePool The address of the oracle pool\\n event OracleSet(address _liquidity, address _oraclePool);\\n\\n /// @notice Emitted when the WETH USD pool is changed\\n /// @param _address Address of the new WETH USD pool\\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\\n /// @param _usdDecimals The amount of decimals of the USD token paired with ETH\\n event WethUSDPoolChange(address _address, bool _isWETHToken0, uint8 _usdDecimals);\\n\\n /// Variables\\n\\n /// @notice Ethereum mainnet WETH address used for quoting references\\n /// @return _weth Address of WETH token\\n // solhint-disable func-name-mixedcase\\n function WETH() external view returns (address _weth);\\n\\n /// @return _oracle The address of the observable pool for given liquidity\\n function oracle(address _liquidity) external view returns (address _oracle);\\n\\n /// @notice WETH-USD pool that is being used as oracle\\n /// @return poolAddress Address of the pool\\n /// @return isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\\n /// @return usdDecimals The amount of decimals of the USD token paired with ETH\\n function wethUSDPool()\\n external\\n view\\n returns (\\n address poolAddress,\\n bool isWETHToken0,\\n uint8 usdDecimals\\n );\\n\\n /// @notice Quotes USD to ETH\\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\\n /// @param _usd The amount of USD to quote to ETH\\n /// @return _eth The resulting amount of ETH after quoting the USD\\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\\n\\n /// Methods\\n\\n /// @notice Sets an oracle for a given liquidity\\n /// @param _liquidity The address of the liquidity\\n /// @param _oracle The address of the pool used to quote the liquidity from\\n /// @dev The oracle must contain KP3R as either token0 or token1\\n function setOracle(address _liquidity, address _oracle) external;\\n\\n /// @notice Sets an oracle for querying WETH/USD quote\\n /// @param _poolAddress The address of the pool used as oracle\\n /// @param _usdDecimals The amount of decimals of the USD token paired with ETH\\n /// @dev The oracle must contain WETH as either token0 or token1\\n function setWethUsdPool(address _poolAddress, uint8 _usdDecimals) external;\\n}\\n\",\"keccak256\":\"0xf354f6c4182f4f91ccb3cabe823bc28cdc1a8cb20c40266e6b6e277279fc7b56\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '../peripherals/IKeep3rJobs.sol';\\n\\n/// @title Keep3rJobWorkableRated contract\\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\\n /// @notice Throws when job contract calls deprecated worked(address) function\\n error Deprecated();\\n\\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\\n /// @param _keeper Address of the keeper that performed the work\\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\\n}\\n\",\"keccak256\":\"0xce2c2721f1df7d944bf3ae20331cb628d38247e667c47bf4a33a90f0b5753884\",\"license\":\"MIT\"},\"solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\n/// @title IKeep3rSidechainAccountance interface\\n/// @notice Implements a view to get the amount of credits that can be withdrawn\\ninterface IKeep3rSidechainAccountance {\\n /// @notice The surplus amount of wKP3Rs in escrow contract\\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\\n function virtualReserves() external view returns (int256 _virtualReserves);\\n}\\n\",\"keccak256\":\"0x4c11242f13d72b5db97e89672d09a771abb903e795ff85588d02c8e11fdc435e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040526203f480601f55621275006020556729a2241af62c000060215562069780602255622cd300602355601e6024553480156200003e57600080fd5b50604051620061023803806200610283398101604081905262000061916200010f565b60016000558383838382828286806001600160a01b038116620000975760405163d92e233d60e01b815260040160405180910390fd5b600380546001600160a01b03199081166001600160a01b0393841617909155601e8054821696831696909617909555601c805486169482169490941790935550601d80549093169116179055506200016c9650505050505050565b80516001600160a01b03811681146200010a57600080fd5b919050565b600080600080608085870312156200012657600080fd5b6200013185620000f2565b93506200014160208601620000f2565b92506200015160408601620000f2565b91506200016160608601620000f2565b905092959194509250565b615f86806200017c6000396000f3fe608060405234801561001057600080fd5b50600436106104c25760003560e01c806398e90a0f11610278578063c7ae40d01161015c578063ec8ca643116100ce578063f25e311b11610092578063f25e311b14610c40578063f263c47014610c53578063f75f9f7b14610c5c578063f9d46cf214610c6f578063fc253d2b14610c82578063fe75bc4614610c8b57600080fd5b8063ec8ca64314610bbe578063f0f346b914610be7578063f11a1d1a14610bfa578063f136a09d14610c0d578063f235757f14610c2d57600080fd5b8063dd2080d611610120578063dd2080d614610b49578063ddca3f4314610b5c578063e3056a3414610b65578063e326ac4314610b78578063ebbb619414610b98578063ec00cdfc14610bab57600080fd5b8063c7ae40d014610ad2578063cb4be2bb14610ae5578063cb54694d14610af8578063cd22af1b14610b0b578063d55995fe14610b3657600080fd5b8063af320e81116101f5578063b600702a116101b9578063b600702a14610a50578063b70362b914610a63578063b7e7734014610a76578063b87fcbff14610a89578063c20297f014610aac578063c5198abc14610abf57600080fd5b8063af320e81146109d4578063b0103b1a146109e7578063b0f328f114610a0a578063b239223314610a12578063b440027f14610a2557600080fd5b8063a5d059ca1161023c578063a5d059ca1461096a578063a676f9ff1461097d578063a734f06e1461099d578063a7d2e784146109b8578063aac6aa9c146109c157600080fd5b806398e90a0f146108dd5780639d5c33d814610906578063a214580914610919578063a39744b51461092c578063a515366a1461095757600080fd5b806359a2255e116103aa57806372da828a1161031c5780638bb6dfa8116102e05780638bb6dfa8146108665780638cb22b76146108795780638fe204dd1461089c57806390a4684e146108af578063951dc22c146108c2578063966abd00146108ca57600080fd5b806372da828a1461080657806374a8f10314610819578063768b5d901461082c5780637c8fce2314610835578063878c723e1461083d57600080fd5b806368a9f19c1161036e57806368a9f19c1461077c578063694798e61461078f57806369fe0e2d146107ba5780636ba42aaa146107cd5780636cf262bc146107e05780636e2a9ca6146107f357600080fd5b806359a2255e146107315780635ebe23f0146107445780635feeb7941461074d578063633fb68f1461076057806364bb43ee1461076957600080fd5b8063168f92e711610443578063274a8db411610407578063274a8db41461069f57806351cff8d9146106d257806352a4de29146106e557806355ea6c47146106f8578063575288bf1461070b578063594a3a931461071e57600080fd5b8063168f92e7146106035780631b44555e1461062e5780631c5a9d9c1461064e5780631ef94b911461066157806321040b011461067457600080fd5b80631101eb411161048a5780631101eb411461056b57806311466d721461058057806313f6986d1461059357806315006b821461059b578063165e62e7146105c657600080fd5b8063034d4c61146104c757806307b435c2146104ed5780630c340a24146105185780630c620bce146105435780630d6a1f8714610558575b600080fd5b6104da6104d536600461590a565b610c9e565b6040519081526020015b60405180910390f35b6104da6104fb366004615927565b601760209081526000928352604080842090915290825290205481565b60035461052b906001600160a01b031681565b6040516001600160a01b0390911681526020016104e4565b61054b610da4565b6040516104e49190615960565b6104da6105663660046159ad565b610db5565b61057e6105793660046159d9565b610ec8565b005b61057e61058e3660046159ad565b611022565b61057e6111c7565b6104da6105a9366004615927565b601560209081526000928352604080842090915290825290205481565b6105d96105d436600461590a565b6111fc565b604080518251600690810b825260208085015190910b9082015291810151908201526060016104e4565b6104da610611366004615927565b600e60209081526000928352604080842090915290825290205481565b6104da61063c36600461590a565b600a6020526000908152604090205481565b61057e61065c36600461590a565b61141b565b601c5461052b906001600160a01b031681565b6104da610682366004615927565b601860209081526000928352604080842090915290825290205481565b6106c26106ad36600461590a565b60066020526000908152604090205460ff1681565b60405190151581526020016104e4565b61057e6106e036600461590a565b6115d6565b61057e6106f33660046159d9565b61176e565b61057e61070636600461590a565b6119a1565b61057e6107193660046159d9565b611a55565b61057e61072c366004615927565b611d10565b61057e61073f36600461590a565b611db5565b6104da601f5481565b61057e61075b36600461590a565b611e67565b6104da60215481565b61057e61077736600461590a565b611e80565b61057e61078a36600461590a565b611f5b565b6104da61079d366004615927565b602860209081526000928352604080842090915290825290205481565b61057e6107c8366004615a1a565b61203b565b6106c26107db36600461590a565b61209b565b6104da6107ee36600461590a565b6120fb565b61057e6108013660046159d9565b612243565b61057e61081436600461590a565b61238f565b61057e61082736600461590a565b61242f565b6104da60225481565b61054b61252a565b61052b61084b36600461590a565b6001602052600090815260409020546001600160a01b031681565b6104da61087436600461590a565b612536565b6106c261088736600461590a565b60196020526000908152604090205460ff1681565b61057e6108aa366004615a1a565b6125d9565b61057e6108bd366004615927565b612637565b61054b612721565b61057e6108d8366004615a33565b61272d565b61052b6108eb36600461590a565b6002602052600090815260409020546001600160a01b031681565b61057e61091436600461590a565b612843565b61057e610927366004615a75565b612923565b6104da61093a366004615927565b600d60209081526000928352604080842090915290825290205481565b61057e6109653660046159ad565b612af3565b61057e6109783660046159ad565b612d4a565b6104da61098b36600461590a565b60296020526000908152604090205481565b61052b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6104da60205481565b61057e6109cf36600461590a565b612e24565b61057e6109e2366004615927565b612ed9565b6106c26109f536600461590a565b600c6020526000908152604090205460ff1681565b6104da613356565b61057e610a20366004615a1a565b6133e8565b6104da610a33366004615927565b602560209081526000928352604080842090915290825290205481565b61057e610a5e36600461590a565b613448565b61057e610a713660046159ad565b6136a5565b61057e610a84366004615a1a565b61393f565b6106c2610a9736600461590a565b60056020526000908152604090205460ff1681565b61057e610aba366004615ab5565b61399f565b61057e610acd36600461590a565b613a58565b601d5461052b906001600160a01b031681565b61057e610af336600461590a565b613b1e565b61057e610b06366004615a1a565b613bbe565b6104da610b19366004615927565b601660209081526000928352604080842090915290825290205481565b61057e610b44366004615afb565b613c42565b61057e610b573660046159d9565b613e79565b6104da60245481565b60045461052b906001600160a01b031681565b6104da610b8636600461590a565b600b6020526000908152604090205481565b61057e610ba6366004615a1a565b614008565b61057e610bb936600461590a565b614068565b61052b610bcc36600461590a565b602c602052600090815260409020546001600160a01b031681565b61057e610bf536600461590a565b614113565b601e5461052b906001600160a01b031681565b6104da610c1b36600461590a565b602a6020526000908152604090205481565b61057e610c3b36600461590a565b6141c8565b61057e610c4e3660046159d9565b6141ff565b6104da60095481565b61057e610c6a36600461590a565b614445565b6106c2610c7d366004615b4e565b6144fd565b6104da60235481565b61057e610c993660046159ad565b6145e6565b600080610caa836120fb565b6022549091504290610cc590610cc09083615bb5565b6146d6565b6001600160a01b0385166000908152602960205260409020541115610d69576022546001600160a01b038516600090815260296020526040902054610d0a9042615bb5565b10610d46576022546001600160a01b038516600090815260296020526040902054610d359190615bcc565b610d3f9082615bb5565b9050610d7f565b6001600160a01b038416600090815260296020526040902054610d3f9082615bb5565b610d72426146d6565b610d7c9082615bb5565b90505b610d8981836146f0565b610d9285612536565b610d9c9190615bcc565b949350505050565b6060610db0602661471a565b905090565b6000610dc260268461472e565b15610ec2576000610dd2846111fc565b90508060400151600014610ec0576001600160a01b03841660009081526014602052604081205460ff16610e13578160200151610e0e90615be4565b610e19565b81602001515b601e5460225460405163a0d2710760e01b815260048101889052600684900b60248201526044810191909152919250610eb7916001600160a01b039091169063a0d27107906064015b60206040518083038186803b158015610e7a57600080fd5b505afa158015610e8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb29190615c0b565b614750565b92505050610ec2565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610f0457604051636efb4f4160e11b815260040160405180910390fd5b602054610f119042615bcc565b6001600160a01b03808616600081815260176020908152604080832094891680845294825280832095909555918152601882528381209281529190529081208054849290610f60908490615bcc565b90915550610f719050848484614761565b6001600160a01b038085166000908152602860209081526040808320938716835292905220548015801590610fb05750602154610fae828661496f565b105b15610fce57604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de8560405161101391815260200190565b60405180910390a35050505050565b336000818152600c602052604090205460ff16156110535760405163ad2fdf3b60e01b815260040160405180910390fd5b61105e601a8261472e565b61107a5760405162941a5760e11b815260040160405180910390fd5b61108381614a97565b156110e0576001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615f318339815191529060600160405180910390a25b6001600160a01b0381166000908152600f60205260409020548211156111615761110981614c6d565b6001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615f318339815191529060600160405180910390a25b61116c818484614cfb565b601c546001600160a01b038085169183821691167f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa856111aa614df8565b6040805192835260208301919091520160405180910390a4505050565b6004546001600160a01b031633146111f257604051639ba0305d60e01b815260040160405180910390fd5b6111fa614e12565b565b6040805160608101825260008082526020820181905291810191909152611222426146d6565b6001600160a01b0383166000908152602b6020526040902060010154141561129057506001600160a01b03166000908152602b602090815260409182902082516060810184528154600681810b8352600160381b909104900b92810192909252600101549181019190915290565b604080516002808252606082018352600092839291906020830190803683370190505090506112be426146d6565b6112c89042615bb5565b816000815181106112db576112db615c24565b602002602001019063ffffffff16908163ffffffff1681525050602254611301426146d6565b61130b9042615bb5565b6113159190615bcc565b8160018151811061132857611328615c24565b63ffffffff909216602092830291909101820152601e546001600160a01b0386811660009081526013909352604080842054905163dc686d9160e01b81529282169263dc686d91926113809216908690600401615c3a565b60606040518083038186803b15801561139857600080fd5b505afa1580156113ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d09190615cb8565b60069290920b80875291945091506113e9908290615cfb565b60060b6020850152821561140a57611400426146d6565b6040850152611412565b600060408501525b5050505b919050565b336000818152600c602052604090205460ff161561144c576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b038082166000908152601660209081526040808320938616835292905220548061149057604051636258f48160e01b815260040160405180910390fd5b4281106114b057604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600b60205260409020546114e9576001600160a01b0382166000908152600b602052604090204290555b6114f4600783614e70565b506001600160a01b038083166000818152601560209081526040808320948816808452948252808320805490849055938352600d8252808320948352939052918220805491928392611547908490615bcc565b9091555050601c546001600160a01b03858116911614156115835780600960008282546115749190615bcc565b90915550611583905081614e85565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a75836040516115c891815260200190565b60405180910390a350505050565b600260005414156116025760405162461bcd60e51b81526004016115f990615d4b565b60405180910390fd5b600260009081553381526018602090815260408083206001600160a01b03851684529091529020546116475760405163184c088160e21b815260040160405180910390fd5b3360009081526017602090815260408083206001600160a01b0385168452909152902054421161168a576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600c602052604090205460ff16156116bb576040516362e6201d60e01b815260040160405180910390fd5b3360008181526018602090815260408083206001600160a01b038681168086529184528285208054908690559585526017845282852082865290935290832092909255601c541614156117115761171181614f70565b6117256001600160a01b0383163383614fb8565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b600260005414156117915760405162461bcd60e51b81526004016115f990615d4b565b60026000556117a160268361472e565b6117be5760405163e0b6aead60e01b815260040160405180910390fd5b6117c9601a8461472e565b6117e657604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526012602052604090206118089083614e70565b5061181283615020565b6021546001600160a01b038085166000908152602860209081526040808320938716835292905220546118509061184a908490615bcc565b8461496f565b101561186f57604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615f318339815191529060600160405180910390a26118db6001600160a01b03831633308461507e565b6001600160a01b03808416600090815260286020908152604080832093861683529290529081208054839290611912908490615bcc565b909155506119259050610eb2828461496f565b6001600160a01b0384166000908152601060205260408120805490919061194d908490615bcc565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff166119d157604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16611a0a576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b60026000541415611a785760405162461bcd60e51b81526004016115f990615d4b565b6002600055611a88601a8461472e565b611aa557604051636211d34960e01b815260040160405180910390fd5b601c546001600160a01b0383811691161415611ad35760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a082319060240160206040518083038186803b158015611b1557600080fd5b505afa158015611b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4d9190615c0b565b9050611b646001600160a01b03841633308561507e565b6040516370a0823160e01b815230600482015260009082906001600160a01b038616906370a082319060240160206040518083038186803b158015611ba857600080fd5b505afa158015611bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be09190615c0b565b611bea9190615bb5565b9050600061271060245483611bff9190615d82565b611c099190615db7565b9050611c158183615bb5565b6001600160a01b038088166000908152600e60209081526040808320938a1683529290529081208054909190611c4c908490615bcc565b90915550506001600160a01b0380871660009081526025602090815260408083208985168085529252909120429055600354611c89921683614fb8565b6001600160a01b0386166000908152601160205260409020611cab9086614e70565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611cfb91815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611d4c57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611df15760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b6040516331cee75f60e21b815260040160405180910390fd5b6003546001600160a01b03163314611eab5760405163070545c960e51b815260040160405180910390fd5b611eb66026826150bc565b611ed357604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600081815260136020908152604080832080546001600160a01b031916905560148252808320805460ff19169055602b825280832080546001600160701b03191681556001019290925590519182527f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e5691015b60405180910390a150565b6003546001600160a01b03163314611f865760405163070545c960e51b815260040160405180910390fd5b6001600160a01b038116611fad5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff1615611fe75760405163546da66560e11b815260040160405180910390fd5b6001600160a01b038116600081815260056020908152604091829020805460ff1916600117905590519182527f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b9101611f50565b6003546001600160a01b031633146120665760405163070545c960e51b815260040160405180910390fd5b60248190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d90602001611f50565b60006120a5614df8565b602e556120b360078361472e565b15611416577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e546040516120eb91815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b0383166000908152601260205260409020612120906150d1565b81101561223d576001600160a01b038316600090815260126020526040812061214990836150db565b905061215660268261472e565b1561222a576000612166826111fc565b90508060400151600014612228576001600160a01b03821660009081526014602052604081205460ff166121a75781602001516121a290615be4565b6121ad565b81602001515b601e546001600160a01b03888116600090815260286020908152604080832089851684529091529081902054602254915163a0d2710760e01b81526004810191909152600685900b6024820152604481019190915292935061221a9291169063a0d2710790606401610e62565b6122249086615bcc565b9450505b505b508061223581615dcb565b9150506120ff565b50919050565b3360009081526005602052604090205460ff1661227357604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff166122ac576040516310cec38560e21b815260040160405180910390fd5b6122b7838383614761565b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb90604401602060405180830381600087803b15801561230557600080fd5b505af1925050508015612335575060408051601f3d908101601f1916820190925261233291810190615de6565b60015b61233e57612340565b505b604080516001600160a01b038481168252602082018490523392908616917f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e91015b60405180910390a3505050565b6003546001600160a01b031633146123ba5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0381166123e15760405163d92e233d60e01b815260040160405180910390fd5b601e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b090602001611f50565b3360009081526005602052604090205460ff1661245f57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16612498576040516310cec38560e21b815260040160405180910390fd5b6124a36007826150bc565b50601c546001600160a01b038083166000818152600d60209081526040808320949095168083529381528482205492825260188152848220848352905292909220546124f1928492916150e7565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610db0601a61471a565b600080612542836120fb565b6022546001600160a01b0385166000908152602960205260409020549192509061256c9042615bb5565b1015610ec25760008111612598576001600160a01b0383166000908152600f60205260409020546125d2565b6001600160a01b038316600090815260106020908152604080832054600f909252909120546125c8908390615d82565b6125d29190615db7565b915061223d565b6003546001600160a01b031633146126045760405163070545c960e51b815260040160405180910390fd5b60208181556040518281527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee29101611f50565b6001600160a01b03828116600090815260016020526040902054839116331461267357604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156126a65760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602c6020908152604080832080546001600160a01b0319169588169586179055602d8252808320858452825291829020429055905192835290917fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c91015b60405180910390a2505050565b6060610db0600761471a565b6003546001600160a01b031633146127585760405163070545c960e51b815260040160405180910390fd5b6001600160a01b03811661277f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156127e0576040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156127da573d6000803e3d6000fd5b506127f4565b6127f46001600160a01b0384168284614fb8565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b0316331461286e5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0381166128955760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff16156128cf5760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b038116600081815260066020908152604091829020805460ff1916600117905590519182527f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f9101611f50565b6001600160a01b03838116600090815260016020526040902054849116331461295f57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0382166129865760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038085166000908152601860209081526040808320938716835292905220546129c95760405163184c088160e21b815260040160405180910390fd5b6001600160a01b038085166000908152601760209081526040808320938716835292905220544211612a0e576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff1615612a48576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b0380851660008181526018602090815260408083209488168084529482528083208054908490559383526017825280832085845290915281205590612a95908483614fb8565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca792886284604051612ae491815260200190565b60405180910390a45050505050565b60026000541415612b165760405162461bcd60e51b81526004016115f990615d4b565b60026000908155338152600c602052604090205460ff1615612b4b576040516362e6201d60e01b815260040160405180910390fd5b612b56601a3361472e565b15612b745760405163d7229c4360e01b815260040160405180910390fd5b601f54612b819042615bcc565b3360009081526016602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81523060048201529091906370a082319060240160206040518083038186803b158015612bdf57600080fd5b505afa158015612bf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c179190615c0b565b9050612c2e6001600160a01b03841633308561507e565b6040516370a0823160e01b815230600482015281906001600160a01b038516906370a082319060240160206040518083038186803b158015612c6f57600080fd5b505afa158015612c83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca79190615c0b565b612cb19190615bb5565b336000908152601960209081526040808320805460ff19166001179055601582528083206001600160a01b0388168452909152812080549294508492909190612cfb908490615bcc565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b602054612d579042615bcc565b3360008181526017602090815260408083206001600160a01b03881680855290835281842095909555928252600d81528282209382529290925281208054839290612da3908490615bb5565b90915550503360009081526018602090815260408083206001600160a01b038616845290915281208054839290612ddb908490615bcc565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b03163314612e4f5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16612e88576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b038116600081815260056020908152604091829020805460ff1916905590519182527f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d0259101611f50565b6001600160a01b038181166000908152600160205260409020548291163314612f1557604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1680612f5457506001600160a01b0382166000908152600c602052604090205460ff165b15612f725760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602c6020526040902054811690831614612faf57604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602d6020908152604080832093861683529290522054612fe190603c90615bcc565b421015613001576040516356248e9760e01b815260040160405180910390fd5b61300a83615020565b61301382615020565b6001600160a01b0383166000908152601160205260408120613034906150d1565b1115613116576001600160a01b038316600090815260116020526040812061305c90826150db565b6001600160a01b038086166000908152600e6020818152604080842085871680865290835281852054958a1685529282528084209284529190528120805493945091926130aa908490615bcc565b90915550506001600160a01b038085166000818152600e6020908152604080832094861683529381528382208290559181526011909152206130ec90826150bc565b506001600160a01b038316600090815260116020526040902061310f9082614e70565b5050613013565b6001600160a01b0383166000908152601260205260408120613137906150d1565b1115613219576001600160a01b038316600090815260126020526040812061315f90826150db565b6001600160a01b03808616600090815260286020818152604080842085871680865290835281852054958a1685529282528084209284529190528120805493945091926131ad908490615bcc565b90915550506001600160a01b03808516600090815260286020908152604080832085851684528252808320839055928616825260129052206131ef9082614e70565b506001600160a01b038416600090815260126020526040902061321290826150bc565b5050613116565b6001600160a01b038084166000908152601060205260408082205492851682528120805490919061324b908490615bcc565b90915550506001600160a01b038084166000908152601060209081526040808320839055600f9091528082205492851682528120805490919061328f908490615bcc565b90915550506001600160a01b0383166000908152600f6020908152604080832083905560299091528120556132c5601a846150bc565b506001600160a01b03838116600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602d8352818420958816808552958352818420849055848452602c835292819020805490931690925590519182527f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f29101612714565b600954601c54601d546040516370a0823160e01b81526001600160a01b0391821660048201526000939291909116906370a082319060240160206040518083038186803b1580156133a657600080fd5b505afa1580156133ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133de9190615c0b565b610db09190615e01565b6003546001600160a01b031633146134135760405163070545c960e51b815260040160405180910390fd5b60238190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb6990602001611f50565b6003546001600160a01b031633146134735760405163070545c960e51b815260040160405180910390fd5b61347e602682614e70565b61349b5760405163f25e6b9f60e01b815260040160405180910390fd5b601e5460405163eb37d34960e01b81526001600160a01b0383811660048301529091169063eb37d3499060240160206040518083038186803b1580156134e057600080fd5b505afa1580156134f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135189190615e40565b6001600160a01b03828116600090815260136020526040902080546001600160a01b0319169290911691821790556135635760405163d92e233d60e01b815260040160405180910390fd5b601e546001600160a01b038281166000908152601360205260409081902054905163696a437b60e01b8152908216600482015291169063696a437b9060240160206040518083038186803b1580156135ba57600080fd5b505afa1580156135ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135f29190615de6565b6001600160a01b0382166000908152601460205260409020805460ff1916911515919091179055613622816111fc565b6001600160a01b0382166000818152602b6020908152604091829020845181548684015166ffffffffffffff908116600160381b026001600160701b031990921692169190911717815593820151600190940193909355519081527fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b9101611f50565b602e546136c557604051630262ab9b60e61b815260040160405180910390fd5b60006136cf614df8565b336000818152600c60205260409020549192509060ff16156137045760405163ad2fdf3b60e01b815260040160405180910390fd5b61370f601a8261472e565b61372b5760405162941a5760e11b815260040160405180910390fd5b61373481614a97565b15613791576001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615f318339815191529060600160405180910390a25b601e546001600160a01b038581166000908152600d60209081526040808320601c548516845290915280822054905163435b21c160e01b8152600481019190915290928392839291169063435b21c19060240160606040518083038186803b1580156137fc57600080fd5b505afa158015613810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138349190615e5d565b919450925090506000613852868361384c8a87615d82565b8761524c565b6001600160a01b0386166000908152600f60205260409020549091508111156138d65761387e85614c6d565b6001600160a01b038516600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615f318339815191529060600160405180910390a25b6138e1858983614cfb565b6000602e55601c5460408051838152602081018990526001600160a01b038b811693898216939116917f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa910160405180910390a45050505050505050565b6003546001600160a01b0316331461396a5760405163070545c960e51b815260040160405180910390fd5b601f8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b4390602001611f50565b3360009081526005602052604090205460ff166139cf57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff16613a08576040516310cec38560e21b815260040160405180910390fd5b613a14848484846150e7565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613a4a8486615bcc565b6040519081526020016115c8565b613a63601a8261472e565b15613a8157604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526019602052604090205460ff1615613abb57604051632f3d320560e01b815260040160405180910390fd5b613ac6601a82614e70565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613b495760405163070545c960e51b815260040160405180910390fd5b6001600160a01b038116613b705760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383169081179091556040519081527feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae25090602001611f50565b6003546001600160a01b03163314613be95760405163070545c960e51b815260040160405180910390fd5b62015180811015613c0d57604051633f384aad60e21b815260040160405180910390fd5b60228190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d990602001611f50565b60026000541415613c655760405162461bcd60e51b81526004016115f990615d4b565b600260009081556001600160a01b03858116825260016020526040909120548591163314613ca657604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260256020908152604080832093881683529290522054613cd890603c90615bcc565b4211613cf757604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054831115613d3d5760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600c602052604090205460ff1615613d775760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290529081208054859290613dae908490615bb5565b90915550613dc890506001600160a01b0385168385614fb8565b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054613e16576001600160a01b0385166000908152601160205260409020613e1490856150bc565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613e6591815260200190565b60405180910390a450506001600055505050565b336000818152600c602052604090205460ff1615613eaa5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1615613ee4576040516362e6201d60e01b815260040160405180910390fd5b613eef601a8261472e565b613f0b5760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290522054821115613f515760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290529081208054849290613f88908490615bb5565b90915550613fa290506001600160a01b0385168484614fb8565b826001600160a01b0316816001600160a01b0316856001600160a01b03167f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa85613fea614df8565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b031633146140335760405163070545c960e51b815260040160405180910390fd5b60218190556040518181527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e790602001611f50565b6003546001600160a01b031633146140935760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0381166140ba5760405163d92e233d60e01b815260040160405180910390fd5b6140c5600954614f70565b601c80546001600160a01b0319166001600160a01b0383169081179091556040519081527f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf90602001611f50565b6003546001600160a01b0316331461413e5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1661417757604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b038116600081815260066020908152604091829020805460ff1916905590519182527f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e9101611f50565b6003546001600160a01b031633146141f35760405163070545c960e51b815260040160405180910390fd5b6141fc816152a9565b50565b3360009081526005602052604090205460ff1661422f57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff16614268576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b038316600090815260116020526040902061428a908361472e565b6142a757604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600e60209081526040808320938616835292905220548111156142ec5760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb90604401602060405180830381600087803b15801561433a57600080fd5b505af192505050801561436a575060408051601f3d908101601f1916820190925261436791810190615de6565b60015b61437357614375565b505b6001600160a01b038084166000908152600e60209081526040808320938616835292905290812080548392906143ac908490615bb5565b90915550506001600160a01b038084166000908152600e60209081526040808320938616835292905220546143ff576001600160a01b03831660009081526011602052604090206143fd90836150bc565b505b604080516001600160a01b038481168252602082018490523392908616917f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d3183331049101612382565b3360009081526006602052604090205460ff1661447557604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16156144af576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b6000614507614df8565b602e5561451560078761472e565b801561454657506001600160a01b038087166000908152600d60209081526040808320938916835292905220548411155b801561456a57506001600160a01b0386166000908152600a60205260409020548311155b801561459957506001600160a01b0386166000908152600b602052604090205482906145969042615bb5565b10155b156145dd577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e546040516145d191815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b031633146146115760405163070545c960e51b815260040160405180910390fd5b61461c601a8361472e565b61463957604051636211d34960e01b815260040160405180910390fd5b61464282615020565b6001600160a01b0382166000908152600f60205260408120805483929061466a908490615bcc565b90915550506001600160a01b038216600081815260296020908152604080832054600f909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d1926146ca928252602082015260400190565b60405180910390a25050565b6000602254826146e69190615e8b565b610ec29083615bb5565b600060225483101561223d576022546147098385615d82565b6147139190615db7565b9050610ec2565b606060006147278361532c565b9392505050565b6001600160a01b03811660009081526001830160205260408120541515614727565b6000610ec282602254602354615388565b600260005414156147845760405162461bcd60e51b81526004016115f990615d4b565b600260009081556001600160a01b03841681526012602052604090206147aa908361472e565b6147c6576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b0380841660009081526028602090815260408083209386168352929052205481111561480c5760405163435b562560e01b815260040160405180910390fd5b61481583615436565b6000614824610eb2838561496f565b6001600160a01b038516600090815260106020526040902054909150156148da576001600160a01b038416600090815260106020908152604080832054600f90925290912054614875908390615d82565b61487f9190615db7565b6001600160a01b0385166000908152600f6020526040812080549091906148a7908490615bb5565b90915550506001600160a01b038416600090815260106020526040812080548392906148d4908490615bb5565b90915550505b6001600160a01b03808516600090815260286020908152604080832093871683529290529081208054849290614911908490615bb5565b90915550506001600160a01b03808516600090815260286020908152604080832093871683529290522054614964576001600160a01b038416600090815260126020526040902061496290846150bc565b505b505060016000555050565b6001600160a01b0381166000908152602b602052604081206001015415610ec2576001600160a01b03821660009081526014602052604081205460ff166149e1576001600160a01b0383166000908152602b60205260409020546149dc90600160381b900460060b615be4565b614a05565b6001600160a01b0383166000908152602b6020526040902054600160381b900460060b5b601e5460225460405163a0d2710760e01b815260048101889052600684900b602482015260448101919091529192506001600160a01b03169063a0d271079060640160206040518083038186803b158015614a5f57600080fd5b505afa158015614a73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9c9190615c0b565b6000614aa2426146d6565b6001600160a01b038316600090815260296020526040902054101561141657614ad260225442610cc09190615bb5565b6001600160a01b03831660009081526029602052604090205411614b4857614af982615436565b6001600160a01b038216600090815260106020908152604080832054600f90925290912055614b27426146d6565b6001600160a01b038316600090815260296020526040902055506001919050565b6022546001600160a01b038316600090815260296020526040902054614b6e9042615bb5565b10614bca57614b7c82615436565b6001600160a01b038216600090815260106020908152604080832054600f83528184205560225460299092528220805491929091614bbb908490615bcc565b90915550600191506114169050565b614bd3426146d6565b6001600160a01b0383166000908152602a60205260409020541015611416576001600160a01b038216600090815260106020526040902054614c1483615436565b6001600160a01b038316600090815260106020908152604080832054600f909252909120548291614c4491615d82565b614c4e9190615db7565b6001600160a01b0384166000908152600f602052604090205550919050565b6001600160a01b038116600090815260296020526040902054614cb290614c949042615bb5565b6001600160a01b0383166000908152601060205260409020546146f0565b6001600160a01b0382166000908152600f602052604081208054909190614cda908490615bcc565b90915550506001600160a01b03166000908152602960205260409020429055565b6001600160a01b0383166000908152600f6020526040902054811115614d345760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602a60209081526040808320429055600f90915281208054839290614d69908490615bb5565b90915550506001600160a01b038083166000908152600d60209081526040808320601c5490941683529290529081208054839290614da8908490615bcc565b90915550506001600160a01b0382166000908152600a602052604081208054839290614dd5908490615bcc565b925050819055508060096000828254614dee9190615bcc565b9091555050505050565b6000603f5a614e08906040615d82565b610db09190615db7565b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6000614727836001600160a01b03841661545b565b601c54601d5460405163095ea7b360e01b81526001600160a01b0391821660048201526024810184905291169063095ea7b390604401602060405180830381600087803b158015614ed557600080fd5b505af1158015614ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f0d9190615de6565b50601d5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f25906024015b600060405180830381600087803b158015614f5557600080fd5b505af1158015614f69573d6000803e3d6000fd5b5050505050565b8060096000828254614f829190615bb5565b9091555050601d5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401614f3b565b6040516001600160a01b03831660248201526044810182905261501b90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526154aa565b505050565b61502981614a97565b5061503381614c6d565b6001600160a01b0381166000908152600f6020908152604080832054601090925290912054615062919061557c565b6001600160a01b039091166000908152600f6020526040902055565b6040516001600160a01b03808516602483015283166044820152606481018290526150b69085906323b872dd60e01b90608401614fe4565b50505050565b6000614727836001600160a01b038416615592565b6000610ec2825490565b60006147278383615685565b601c546001600160a01b038481169116146151ce576003546001600160a01b038085169163a9059cbb911661511c8486615bcc565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561516257600080fd5b505af1925050508015615192575060408051601f3d908101601f1916820190925261518f91810190615de6565b60015b6151cc573d8080156151c0576040519150601f19603f3d011682016040523d82523d6000602084013e6151c5565b606091505b50506151ce565b505b6001600160a01b038085166000908152600d6020908152604080832093871683529290529081208054849290615205908490615bb5565b90915550506001600160a01b03808516600090815260186020908152604080832093871683529290529081208054839290615241908490615bb5565b909155505050505050565b6000808486602e5461525e9190615bb5565b6152689190615bcc565b9050670de0b6b3a7640000846127106152818685615d82565b61528b9190615db7565b6152959190615d82565b61529f9190615db7565b9695505050505050565b6001600160a01b0381166152d05760405163d92e233d60e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b038381169182179092556003546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec9101611f50565b60608160000180548060200260200160405190810160405280929190818152602001828054801561537c57602002820191906000526020600020905b815481526020019060010190808311615368575b50505050509050919050565b6000808060001985870985870292508281108382030391505080600014156153c257600084116153b757600080fd5b508290049050614727565b8084116153ce57600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b61543f816156af565b6001600160a01b03909116600090815260106020526040902055565b60008181526001830160205260408120546154a257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ec2565b506000610ec2565b60006154ff826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166157ea9092919063ffffffff16565b80519091501561501b578080602001905181019061551d9190615de6565b61501b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016115f9565b600081831061558b5781614727565b5090919050565b6000818152600183016020526040812054801561567b5760006155b6600183615bb5565b85549091506000906155ca90600190615bb5565b905081811461562f5760008660000182815481106155ea576155ea615c24565b906000526020600020015490508087600001848154811061560d5761560d615c24565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061564057615640615e9f565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610ec2565b6000915050610ec2565b600082600001828154811061569c5761569c615c24565b9060005260206000200154905092915050565b6000805b6001600160a01b03831660009081526012602052604090206156d4906150d1565b81101561223d576001600160a01b03831660009081526012602052604081206156fd90836150db565b905061570a60268261472e565b156157d757615718426146d6565b6001600160a01b0382166000908152602b60205260409020600101541461579657615742816111fc565b6001600160a01b0382166000908152602b6020908152604091829020835181549285015166ffffffffffffff908116600160381b026001600160701b03199094169116179190911781559101516001909101555b6001600160a01b038085166000908152602860209081526040808320938516835292905220546157ca90610eb2908361496f565b6157d49084615bcc565b92505b50806157e281615dcb565b9150506156b3565b6060610d9c848460008585843b6158435760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016115f9565b600080866001600160a01b0316858760405161585f9190615ee1565b60006040518083038185875af1925050503d806000811461589c576040519150601f19603f3d011682016040523d82523d6000602084013e6158a1565b606091505b50915091506158b18282866158bc565b979650505050505050565b606083156158cb575081614727565b8251156158db5782518084602001fd5b8160405162461bcd60e51b81526004016115f99190615efd565b6001600160a01b03811681146141fc57600080fd5b60006020828403121561591c57600080fd5b8135614727816158f5565b6000806040838503121561593a57600080fd5b8235615945816158f5565b91506020830135615955816158f5565b809150509250929050565b6020808252825182820181905260009190848201906040850190845b818110156159a15783516001600160a01b03168352928401929184019160010161597c565b50909695505050505050565b600080604083850312156159c057600080fd5b82356159cb816158f5565b946020939093013593505050565b6000806000606084860312156159ee57600080fd5b83356159f9816158f5565b92506020840135615a09816158f5565b929592945050506040919091013590565b600060208284031215615a2c57600080fd5b5035919050565b600080600060608486031215615a4857600080fd5b8335615a53816158f5565b9250602084013591506040840135615a6a816158f5565b809150509250925092565b600080600060608486031215615a8a57600080fd5b8335615a95816158f5565b92506020840135615aa5816158f5565b91506040840135615a6a816158f5565b60008060008060808587031215615acb57600080fd5b8435615ad6816158f5565b93506020850135615ae6816158f5565b93969395505050506040820135916060013590565b60008060008060808587031215615b1157600080fd5b8435615b1c816158f5565b93506020850135615b2c816158f5565b9250604085013591506060850135615b43816158f5565b939692955090935050565b600080600080600060a08688031215615b6657600080fd5b8535615b71816158f5565b94506020860135615b81816158f5565b94979496505050506040830135926060810135926080909101359150565b634e487b7160e01b600052601160045260246000fd5b600082821015615bc757615bc7615b9f565b500390565b60008219821115615bdf57615bdf615b9f565b500190565b60008160060b667fffffffffffff19811415615c0257615c02615b9f565b60000392915050565b600060208284031215615c1d57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615c8957845163ffffffff1683529383019391830191600101615c67565b5090979650505050505050565b8051600681900b811461141657600080fd5b8051801515811461141657600080fd5b600080600060608486031215615ccd57600080fd5b615cd684615c96565b9250615ce460208501615c96565b9150615cf260408501615ca8565b90509250925092565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615d2657615d26615b9f565b81667fffffffffffff018313811615615d4157615d41615b9f565b5090039392505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000816000190483118215151615615d9c57615d9c615b9f565b500290565b634e487b7160e01b600052601260045260246000fd5b600082615dc657615dc6615da1565b500490565b6000600019821415615ddf57615ddf615b9f565b5060010190565b600060208284031215615df857600080fd5b61472782615ca8565b60008083128015600160ff1b850184121615615e1f57615e1f615b9f565b6001600160ff1b0384018313811615615e3a57615e3a615b9f565b50500390565b600060208284031215615e5257600080fd5b8151614727816158f5565b600080600060608486031215615e7257600080fd5b8351925060208401519150604084015190509250925092565b600082615e9a57615e9a615da1565b500690565b634e487b7160e01b600052603160045260246000fd5b60005b83811015615ed0578181015183820152602001615eb8565b838111156150b65750506000910152565b60008251615ef3818460208701615eb5565b9190910192915050565b6020815260008251806020840152615f1c816040850160208701615eb5565b601f01601f1916919091016040019291505056feee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a264697066735822122092dd1a4589672def8dde508250ee75a31216dad323e874a66fb20fdcae6d923064736f6c63430008080033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106104c25760003560e01c806398e90a0f11610278578063c7ae40d01161015c578063ec8ca643116100ce578063f25e311b11610092578063f25e311b14610c40578063f263c47014610c53578063f75f9f7b14610c5c578063f9d46cf214610c6f578063fc253d2b14610c82578063fe75bc4614610c8b57600080fd5b8063ec8ca64314610bbe578063f0f346b914610be7578063f11a1d1a14610bfa578063f136a09d14610c0d578063f235757f14610c2d57600080fd5b8063dd2080d611610120578063dd2080d614610b49578063ddca3f4314610b5c578063e3056a3414610b65578063e326ac4314610b78578063ebbb619414610b98578063ec00cdfc14610bab57600080fd5b8063c7ae40d014610ad2578063cb4be2bb14610ae5578063cb54694d14610af8578063cd22af1b14610b0b578063d55995fe14610b3657600080fd5b8063af320e81116101f5578063b600702a116101b9578063b600702a14610a50578063b70362b914610a63578063b7e7734014610a76578063b87fcbff14610a89578063c20297f014610aac578063c5198abc14610abf57600080fd5b8063af320e81146109d4578063b0103b1a146109e7578063b0f328f114610a0a578063b239223314610a12578063b440027f14610a2557600080fd5b8063a5d059ca1161023c578063a5d059ca1461096a578063a676f9ff1461097d578063a734f06e1461099d578063a7d2e784146109b8578063aac6aa9c146109c157600080fd5b806398e90a0f146108dd5780639d5c33d814610906578063a214580914610919578063a39744b51461092c578063a515366a1461095757600080fd5b806359a2255e116103aa57806372da828a1161031c5780638bb6dfa8116102e05780638bb6dfa8146108665780638cb22b76146108795780638fe204dd1461089c57806390a4684e146108af578063951dc22c146108c2578063966abd00146108ca57600080fd5b806372da828a1461080657806374a8f10314610819578063768b5d901461082c5780637c8fce2314610835578063878c723e1461083d57600080fd5b806368a9f19c1161036e57806368a9f19c1461077c578063694798e61461078f57806369fe0e2d146107ba5780636ba42aaa146107cd5780636cf262bc146107e05780636e2a9ca6146107f357600080fd5b806359a2255e146107315780635ebe23f0146107445780635feeb7941461074d578063633fb68f1461076057806364bb43ee1461076957600080fd5b8063168f92e711610443578063274a8db411610407578063274a8db41461069f57806351cff8d9146106d257806352a4de29146106e557806355ea6c47146106f8578063575288bf1461070b578063594a3a931461071e57600080fd5b8063168f92e7146106035780631b44555e1461062e5780631c5a9d9c1461064e5780631ef94b911461066157806321040b011461067457600080fd5b80631101eb411161048a5780631101eb411461056b57806311466d721461058057806313f6986d1461059357806315006b821461059b578063165e62e7146105c657600080fd5b8063034d4c61146104c757806307b435c2146104ed5780630c340a24146105185780630c620bce146105435780630d6a1f8714610558575b600080fd5b6104da6104d536600461590a565b610c9e565b6040519081526020015b60405180910390f35b6104da6104fb366004615927565b601760209081526000928352604080842090915290825290205481565b60035461052b906001600160a01b031681565b6040516001600160a01b0390911681526020016104e4565b61054b610da4565b6040516104e49190615960565b6104da6105663660046159ad565b610db5565b61057e6105793660046159d9565b610ec8565b005b61057e61058e3660046159ad565b611022565b61057e6111c7565b6104da6105a9366004615927565b601560209081526000928352604080842090915290825290205481565b6105d96105d436600461590a565b6111fc565b604080518251600690810b825260208085015190910b9082015291810151908201526060016104e4565b6104da610611366004615927565b600e60209081526000928352604080842090915290825290205481565b6104da61063c36600461590a565b600a6020526000908152604090205481565b61057e61065c36600461590a565b61141b565b601c5461052b906001600160a01b031681565b6104da610682366004615927565b601860209081526000928352604080842090915290825290205481565b6106c26106ad36600461590a565b60066020526000908152604090205460ff1681565b60405190151581526020016104e4565b61057e6106e036600461590a565b6115d6565b61057e6106f33660046159d9565b61176e565b61057e61070636600461590a565b6119a1565b61057e6107193660046159d9565b611a55565b61057e61072c366004615927565b611d10565b61057e61073f36600461590a565b611db5565b6104da601f5481565b61057e61075b36600461590a565b611e67565b6104da60215481565b61057e61077736600461590a565b611e80565b61057e61078a36600461590a565b611f5b565b6104da61079d366004615927565b602860209081526000928352604080842090915290825290205481565b61057e6107c8366004615a1a565b61203b565b6106c26107db36600461590a565b61209b565b6104da6107ee36600461590a565b6120fb565b61057e6108013660046159d9565b612243565b61057e61081436600461590a565b61238f565b61057e61082736600461590a565b61242f565b6104da60225481565b61054b61252a565b61052b61084b36600461590a565b6001602052600090815260409020546001600160a01b031681565b6104da61087436600461590a565b612536565b6106c261088736600461590a565b60196020526000908152604090205460ff1681565b61057e6108aa366004615a1a565b6125d9565b61057e6108bd366004615927565b612637565b61054b612721565b61057e6108d8366004615a33565b61272d565b61052b6108eb36600461590a565b6002602052600090815260409020546001600160a01b031681565b61057e61091436600461590a565b612843565b61057e610927366004615a75565b612923565b6104da61093a366004615927565b600d60209081526000928352604080842090915290825290205481565b61057e6109653660046159ad565b612af3565b61057e6109783660046159ad565b612d4a565b6104da61098b36600461590a565b60296020526000908152604090205481565b61052b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6104da60205481565b61057e6109cf36600461590a565b612e24565b61057e6109e2366004615927565b612ed9565b6106c26109f536600461590a565b600c6020526000908152604090205460ff1681565b6104da613356565b61057e610a20366004615a1a565b6133e8565b6104da610a33366004615927565b602560209081526000928352604080842090915290825290205481565b61057e610a5e36600461590a565b613448565b61057e610a713660046159ad565b6136a5565b61057e610a84366004615a1a565b61393f565b6106c2610a9736600461590a565b60056020526000908152604090205460ff1681565b61057e610aba366004615ab5565b61399f565b61057e610acd36600461590a565b613a58565b601d5461052b906001600160a01b031681565b61057e610af336600461590a565b613b1e565b61057e610b06366004615a1a565b613bbe565b6104da610b19366004615927565b601660209081526000928352604080842090915290825290205481565b61057e610b44366004615afb565b613c42565b61057e610b573660046159d9565b613e79565b6104da60245481565b60045461052b906001600160a01b031681565b6104da610b8636600461590a565b600b6020526000908152604090205481565b61057e610ba6366004615a1a565b614008565b61057e610bb936600461590a565b614068565b61052b610bcc36600461590a565b602c602052600090815260409020546001600160a01b031681565b61057e610bf536600461590a565b614113565b601e5461052b906001600160a01b031681565b6104da610c1b36600461590a565b602a6020526000908152604090205481565b61057e610c3b36600461590a565b6141c8565b61057e610c4e3660046159d9565b6141ff565b6104da60095481565b61057e610c6a36600461590a565b614445565b6106c2610c7d366004615b4e565b6144fd565b6104da60235481565b61057e610c993660046159ad565b6145e6565b600080610caa836120fb565b6022549091504290610cc590610cc09083615bb5565b6146d6565b6001600160a01b0385166000908152602960205260409020541115610d69576022546001600160a01b038516600090815260296020526040902054610d0a9042615bb5565b10610d46576022546001600160a01b038516600090815260296020526040902054610d359190615bcc565b610d3f9082615bb5565b9050610d7f565b6001600160a01b038416600090815260296020526040902054610d3f9082615bb5565b610d72426146d6565b610d7c9082615bb5565b90505b610d8981836146f0565b610d9285612536565b610d9c9190615bcc565b949350505050565b6060610db0602661471a565b905090565b6000610dc260268461472e565b15610ec2576000610dd2846111fc565b90508060400151600014610ec0576001600160a01b03841660009081526014602052604081205460ff16610e13578160200151610e0e90615be4565b610e19565b81602001515b601e5460225460405163a0d2710760e01b815260048101889052600684900b60248201526044810191909152919250610eb7916001600160a01b039091169063a0d27107906064015b60206040518083038186803b158015610e7a57600080fd5b505afa158015610e8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb29190615c0b565b614750565b92505050610ec2565b505b92915050565b6001600160a01b038381166000908152600160205260409020548491163314610f0457604051636efb4f4160e11b815260040160405180910390fd5b602054610f119042615bcc565b6001600160a01b03808616600081815260176020908152604080832094891680845294825280832095909555918152601882528381209281529190529081208054849290610f60908490615bcc565b90915550610f719050848484614761565b6001600160a01b038085166000908152602860209081526040808320938716835292905220548015801590610fb05750602154610fae828661496f565b105b15610fce57604051636f447fcd60e11b815260040160405180910390fd5b836001600160a01b0316856001600160a01b03167f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de8560405161101391815260200190565b60405180910390a35050505050565b336000818152600c602052604090205460ff16156110535760405163ad2fdf3b60e01b815260040160405180910390fd5b61105e601a8261472e565b61107a5760405162941a5760e11b815260040160405180910390fd5b61108381614a97565b156110e0576001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615f318339815191529060600160405180910390a25b6001600160a01b0381166000908152600f60205260409020548211156111615761110981614c6d565b6001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615f318339815191529060600160405180910390a25b61116c818484614cfb565b601c546001600160a01b038085169183821691167f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa856111aa614df8565b6040805192835260208301919091520160405180910390a4505050565b6004546001600160a01b031633146111f257604051639ba0305d60e01b815260040160405180910390fd5b6111fa614e12565b565b6040805160608101825260008082526020820181905291810191909152611222426146d6565b6001600160a01b0383166000908152602b6020526040902060010154141561129057506001600160a01b03166000908152602b602090815260409182902082516060810184528154600681810b8352600160381b909104900b92810192909252600101549181019190915290565b604080516002808252606082018352600092839291906020830190803683370190505090506112be426146d6565b6112c89042615bb5565b816000815181106112db576112db615c24565b602002602001019063ffffffff16908163ffffffff1681525050602254611301426146d6565b61130b9042615bb5565b6113159190615bcc565b8160018151811061132857611328615c24565b63ffffffff909216602092830291909101820152601e546001600160a01b0386811660009081526013909352604080842054905163dc686d9160e01b81529282169263dc686d91926113809216908690600401615c3a565b60606040518083038186803b15801561139857600080fd5b505afa1580156113ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d09190615cb8565b60069290920b80875291945091506113e9908290615cfb565b60060b6020850152821561140a57611400426146d6565b6040850152611412565b600060408501525b5050505b919050565b336000818152600c602052604090205460ff161561144c576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b038082166000908152601660209081526040808320938616835292905220548061149057604051636258f48160e01b815260040160405180910390fd5b4281106114b057604051630fd0eeef60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600b60205260409020546114e9576001600160a01b0382166000908152600b602052604090204290555b6114f4600783614e70565b506001600160a01b038083166000818152601560209081526040808320948816808452948252808320805490849055938352600d8252808320948352939052918220805491928392611547908490615bcc565b9091555050601c546001600160a01b03858116911614156115835780600960008282546115749190615bcc565b90915550611583905081614e85565b836001600160a01b0316836001600160a01b03167f3673530133b6da67e9854f605b0cfa7bb9798cd33c18036dfc10d8da7c4d4a75836040516115c891815260200190565b60405180910390a350505050565b600260005414156116025760405162461bcd60e51b81526004016115f990615d4b565b60405180910390fd5b600260009081553381526018602090815260408083206001600160a01b03851684529091529020546116475760405163184c088160e21b815260040160405180910390fd5b3360009081526017602090815260408083206001600160a01b0385168452909152902054421161168a576040516327cfdcb760e01b815260040160405180910390fd5b336000908152600c602052604090205460ff16156116bb576040516362e6201d60e01b815260040160405180910390fd5b3360008181526018602090815260408083206001600160a01b038681168086529184528285208054908690559585526017845282852082865290935290832092909255601c541614156117115761171181614f70565b6117256001600160a01b0383163383614fb8565b6040518181526001600160a01b0383169033907f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989060200160405180910390a350506001600055565b600260005414156117915760405162461bcd60e51b81526004016115f990615d4b565b60026000556117a160268361472e565b6117be5760405163e0b6aead60e01b815260040160405180910390fd5b6117c9601a8461472e565b6117e657604051636211d34960e01b815260040160405180910390fd5b6001600160a01b03831660009081526012602052604090206118089083614e70565b5061181283615020565b6021546001600160a01b038085166000908152602860209081526040808320938716835292905220546118509061184a908490615bcc565b8461496f565b101561186f57604051636f447fcd60e11b815260040160405180910390fd5b6001600160a01b038316600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615f318339815191529060600160405180910390a26118db6001600160a01b03831633308461507e565b6001600160a01b03808416600090815260286020908152604080832093861683529290529081208054839290611912908490615bcc565b909155506119259050610eb2828461496f565b6001600160a01b0384166000908152601060205260408120805490919061194d908490615bcc565b909155505060405181815233906001600160a01b0384811691908616907f4e186bc75a2220191b826baff3ee63c3e970e94e58a9007ff94c9a7b8e6ebb3f9060200160405180910390a45050600160005550565b3360009081526006602052604090205460ff166119d157604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16611a0a576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19169055513392917fe02b2375d8fb4aef3e5bc5d53bffcf70b6f185c5c93e69dcbe8b6cfc58e837e291a350565b60026000541415611a785760405162461bcd60e51b81526004016115f990615d4b565b6002600055611a88601a8461472e565b611aa557604051636211d34960e01b815260040160405180910390fd5b601c546001600160a01b0383811691161415611ad35760405162822d9760e71b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a082319060240160206040518083038186803b158015611b1557600080fd5b505afa158015611b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4d9190615c0b565b9050611b646001600160a01b03841633308561507e565b6040516370a0823160e01b815230600482015260009082906001600160a01b038616906370a082319060240160206040518083038186803b158015611ba857600080fd5b505afa158015611bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be09190615c0b565b611bea9190615bb5565b9050600061271060245483611bff9190615d82565b611c099190615db7565b9050611c158183615bb5565b6001600160a01b038088166000908152600e60209081526040808320938a1683529290529081208054909190611c4c908490615bcc565b90915550506001600160a01b0380871660009081526025602090815260408083208985168085529252909120429055600354611c89921683614fb8565b6001600160a01b0386166000908152601160205260409020611cab9086614e70565b50336001600160a01b0316856001600160a01b0316876001600160a01b03167fec1a37d4a331a5059081e0fb5da1735e7890900cd215a4fb1e9f2779fd7b83eb85604051611cfb91815260200190565b60405180910390a45050600160005550505050565b6001600160a01b038281166000908152600160205260409020548391163314611d4c57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03838116600081815260026020908152604080832080546001600160a01b031916888716908117909155600190925280832054905191941692917fa8bad3f0b781e1d954af9945167d5f80bfe5e57930f17c93843187c77557a6b891a4505050565b6001600160a01b038181166000908152600260205260409020548291163314611df15760405163cfe9663360e01b815260040160405180910390fd5b6001600160a01b03828116600081815260016020908152604080832080546002909352818420805487166001600160a01b031980861691909117909255805490911690555193169283929133917fcf30c54296d5eee76168b564c59c50578d49c271733a470f32707c8cfbc88a8b9190a4505050565b6040516331cee75f60e21b815260040160405180910390fd5b6003546001600160a01b03163314611eab5760405163070545c960e51b815260040160405180910390fd5b611eb66026826150bc565b611ed357604051630a8d08b160e01b815260040160405180910390fd5b6001600160a01b038116600081815260136020908152604080832080546001600160a01b031916905560148252808320805460ff19169055602b825280832080546001600160701b03191681556001019290925590519182527f51199d699bdfd516fa88dd0d2f8487c40c147b4867acaa23adc8d4df6b098e5691015b60405180910390a150565b6003546001600160a01b03163314611f865760405163070545c960e51b815260040160405180910390fd5b6001600160a01b038116611fad5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff1615611fe75760405163546da66560e11b815260040160405180910390fd5b6001600160a01b038116600081815260056020908152604091829020805460ff1916600117905590519182527f049ccb28ab796d3225573a065712f6e7754487ced56056cda8889c337511807b9101611f50565b6003546001600160a01b031633146120665760405163070545c960e51b815260040160405180910390fd5b60248190556040518181527f4c10ca068ff7002cf5da78f2f697d1e91f6f0ac27f7344b28e8ef25263f87e5d90602001611f50565b60006120a5614df8565b602e556120b360078361472e565b15611416577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e546040516120eb91815260200190565b60405180910390a1506001919050565b6000805b6001600160a01b0383166000908152601260205260409020612120906150d1565b81101561223d576001600160a01b038316600090815260126020526040812061214990836150db565b905061215660268261472e565b1561222a576000612166826111fc565b90508060400151600014612228576001600160a01b03821660009081526014602052604081205460ff166121a75781602001516121a290615be4565b6121ad565b81602001515b601e546001600160a01b03888116600090815260286020908152604080832089851684529091529081902054602254915163a0d2710760e01b81526004810191909152600685900b6024820152604481019190915292935061221a9291169063a0d2710790606401610e62565b6122249086615bcc565b9450505b505b508061223581615dcb565b9150506120ff565b50919050565b3360009081526005602052604090205460ff1661227357604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff166122ac576040516310cec38560e21b815260040160405180910390fd5b6122b7838383614761565b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb90604401602060405180830381600087803b15801561230557600080fd5b505af1925050508015612335575060408051601f3d908101601f1916820190925261233291810190615de6565b60015b61233e57612340565b505b604080516001600160a01b038481168252602082018490523392908616917f6e10247c3c094d220ee99436c164b7f38d63b335a20ed817cbefaee4bb02d20e91015b60405180910390a3505050565b6003546001600160a01b031633146123ba5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0381166123e15760405163d92e233d60e01b815260040160405180910390fd5b601e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f71973fd672e51deb8f739b1f7e1eab991936645acd6f83e2bde6eeeaff5490b090602001611f50565b3360009081526005602052604090205460ff1661245f57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16612498576040516310cec38560e21b815260040160405180910390fd5b6124a36007826150bc565b50601c546001600160a01b038083166000818152600d60209081526040808320949095168083529381528482205492825260188152848220848352905292909220546124f1928492916150e7565b60405133906001600160a01b038316907f038a17b9b553c0c3fc2ed14b957a5d8420a1666fd2efe5c1b3fe5f23eea61bb390600090a350565b6060610db0601a61471a565b600080612542836120fb565b6022546001600160a01b0385166000908152602960205260409020549192509061256c9042615bb5565b1015610ec25760008111612598576001600160a01b0383166000908152600f60205260409020546125d2565b6001600160a01b038316600090815260106020908152604080832054600f909252909120546125c8908390615d82565b6125d29190615db7565b915061223d565b6003546001600160a01b031633146126045760405163070545c960e51b815260040160405180910390fd5b60208181556040518281527fc8d443472c9783cc36f8f5f5091f08ce9f37fc2f9e6d79cf1d9aaf40a433fee29101611f50565b6001600160a01b03828116600090815260016020526040902054839116331461267357604051636efb4f4160e11b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031614156126a65760405163afe7ad4960e01b815260040160405180910390fd5b6001600160a01b038381166000818152602c6020908152604080832080546001600160a01b0319169588169586179055602d8252808320858452825291829020429055905192835290917fff0456758201108de53c0ff04c69988d4678ff455b2ce6f733328cf85722c04c91015b60405180910390a2505050565b6060610db0600761471a565b6003546001600160a01b031633146127585760405163070545c960e51b815260040160405180910390fd5b6001600160a01b03811661277f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156127e0576040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156127da573d6000803e3d6000fd5b506127f4565b6127f46001600160a01b0384168284614fb8565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6003546001600160a01b0316331461286e5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0381166128955760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff16156128cf5760405163274e25dd60e11b815260040160405180910390fd5b6001600160a01b038116600081815260066020908152604091829020805460ff1916600117905590519182527f8addc69f897ecca0e41d70ed4ff9d75a9148a615a0fbda8597e53aea2684302f9101611f50565b6001600160a01b03838116600090815260016020526040902054849116331461295f57604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0382166129865760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038085166000908152601860209081526040808320938716835292905220546129c95760405163184c088160e21b815260040160405180910390fd5b6001600160a01b038085166000908152601760209081526040808320938716835292905220544211612a0e576040516327cfdcb760e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff1615612a48576040516362e6201d60e01b815260040160405180910390fd5b6001600160a01b0380851660008181526018602090815260408083209488168084529482528083208054908490559383526017825280832085845290915281205590612a95908483614fb8565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffdb7893bf11f50c621e59cc7f1cf540e94295cb27ca869ec7ed7618ca792886284604051612ae491815260200190565b60405180910390a45050505050565b60026000541415612b165760405162461bcd60e51b81526004016115f990615d4b565b60026000908155338152600c602052604090205460ff1615612b4b576040516362e6201d60e01b815260040160405180910390fd5b612b56601a3361472e565b15612b745760405163d7229c4360e01b815260040160405180910390fd5b601f54612b819042615bcc565b3360009081526016602090815260408083206001600160a01b03871680855292528083209390935591516370a0823160e01b81523060048201529091906370a082319060240160206040518083038186803b158015612bdf57600080fd5b505afa158015612bf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c179190615c0b565b9050612c2e6001600160a01b03841633308561507e565b6040516370a0823160e01b815230600482015281906001600160a01b038516906370a082319060240160206040518083038186803b158015612c6f57600080fd5b505afa158015612c83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca79190615c0b565b612cb19190615bb5565b336000908152601960209081526040808320805460ff19166001179055601582528083206001600160a01b0388168452909152812080549294508492909190612cfb908490615bcc565b90915550506040518281526001600160a01b0384169033907fa7e66869262026842e8d81f5e6806cdc8d846e27c824e2e22f4fe51442771b349060200160405180910390a35050600160005550565b602054612d579042615bcc565b3360008181526017602090815260408083206001600160a01b03881680855290835281842095909555928252600d81528282209382529290925281208054839290612da3908490615bb5565b90915550503360009081526018602090815260408083206001600160a01b038616845290915281208054839290612ddb908490615bcc565b90915550506040518181526001600160a01b0383169033907f9aaab310d247ad45aef26bbdefc4ebf20c728fdb84c92b95b2b05d21826940de9060200160405180910390a35050565b6003546001600160a01b03163314612e4f5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff16612e88576040516336fe17e760e21b815260040160405180910390fd5b6001600160a01b038116600081815260056020908152604091829020805460ff1916905590519182527f3ed8cbce8cab40e59282f1743e2b607effa08b5cbe0111bb4721134f2f80d0259101611f50565b6001600160a01b038181166000908152600160205260409020548291163314612f1557604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1680612f5457506001600160a01b0382166000908152600c602052604090205460ff165b15612f725760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038381166000908152602c6020526040902054811690831614612faf57604051630ced616b60e21b815260040160405180910390fd5b6001600160a01b038084166000908152602d6020908152604080832093861683529290522054612fe190603c90615bcc565b421015613001576040516356248e9760e01b815260040160405180910390fd5b61300a83615020565b61301382615020565b6001600160a01b0383166000908152601160205260408120613034906150d1565b1115613116576001600160a01b038316600090815260116020526040812061305c90826150db565b6001600160a01b038086166000908152600e6020818152604080842085871680865290835281852054958a1685529282528084209284529190528120805493945091926130aa908490615bcc565b90915550506001600160a01b038085166000818152600e6020908152604080832094861683529381528382208290559181526011909152206130ec90826150bc565b506001600160a01b038316600090815260116020526040902061310f9082614e70565b5050613013565b6001600160a01b0383166000908152601260205260408120613137906150d1565b1115613219576001600160a01b038316600090815260126020526040812061315f90826150db565b6001600160a01b03808616600090815260286020818152604080842085871680865290835281852054958a1685529282528084209284529190528120805493945091926131ad908490615bcc565b90915550506001600160a01b03808516600090815260286020908152604080832085851684528252808320839055928616825260129052206131ef9082614e70565b506001600160a01b038416600090815260126020526040902061321290826150bc565b5050613116565b6001600160a01b038084166000908152601060205260408082205492851682528120805490919061324b908490615bcc565b90915550506001600160a01b038084166000908152601060209081526040808320839055600f9091528082205492851682528120805490919061328f908490615bcc565b90915550506001600160a01b0383166000908152600f6020908152604080832083905560299091528120556132c5601a846150bc565b506001600160a01b03838116600081815260016020908152604080832080546001600160a01b031990811690915560028352818420805482169055602d8352818420958816808552958352818420849055848452602c835292819020805490931690925590519182527f9b712b63e3fb1325fa042d3c238ce8144937875065900528ea1e4f3b00f379f29101612714565b600954601c54601d546040516370a0823160e01b81526001600160a01b0391821660048201526000939291909116906370a082319060240160206040518083038186803b1580156133a657600080fd5b505afa1580156133ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133de9190615c0b565b610db09190615e01565b6003546001600160a01b031633146134135760405163070545c960e51b815260040160405180910390fd5b60238190556040518181527fbdcfd7b8482f31cff6a87c362d9e2e3887f4cdc2018c7c485d8e78a7b2fadb6990602001611f50565b6003546001600160a01b031633146134735760405163070545c960e51b815260040160405180910390fd5b61347e602682614e70565b61349b5760405163f25e6b9f60e01b815260040160405180910390fd5b601e5460405163eb37d34960e01b81526001600160a01b0383811660048301529091169063eb37d3499060240160206040518083038186803b1580156134e057600080fd5b505afa1580156134f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135189190615e40565b6001600160a01b03828116600090815260136020526040902080546001600160a01b0319169290911691821790556135635760405163d92e233d60e01b815260040160405180910390fd5b601e546001600160a01b038281166000908152601360205260409081902054905163696a437b60e01b8152908216600482015291169063696a437b9060240160206040518083038186803b1580156135ba57600080fd5b505afa1580156135ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135f29190615de6565b6001600160a01b0382166000908152601460205260409020805460ff1916911515919091179055613622816111fc565b6001600160a01b0382166000818152602b6020908152604091829020845181548684015166ffffffffffffff908116600160381b026001600160701b031990921692169190911717815593820151600190940193909355519081527fabfa8db4d238fa78bf4e15fcc91328dd35f3978f200e2857a56bb719732b7b0b9101611f50565b602e546136c557604051630262ab9b60e61b815260040160405180910390fd5b60006136cf614df8565b336000818152600c60205260409020549192509060ff16156137045760405163ad2fdf3b60e01b815260040160405180910390fd5b61370f601a8261472e565b61372b5760405162941a5760e11b815260040160405180910390fd5b61373481614a97565b15613791576001600160a01b038116600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615f318339815191529060600160405180910390a25b601e546001600160a01b038581166000908152600d60209081526040808320601c548516845290915280822054905163435b21c160e01b8152600481019190915290928392839291169063435b21c19060240160606040518083038186803b1580156137fc57600080fd5b505afa158015613810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138349190615e5d565b919450925090506000613852868361384c8a87615d82565b8761524c565b6001600160a01b0386166000908152600f60205260409020549091508111156138d65761387e85614c6d565b6001600160a01b038516600081815260296020908152604080832054600f835281842054601084529382902054825191825292810193909352820152600080516020615f318339815191529060600160405180910390a25b6138e1858983614cfb565b6000602e55601c5460408051838152602081018990526001600160a01b038b811693898216939116917f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa910160405180910390a45050505050505050565b6003546001600160a01b0316331461396a5760405163070545c960e51b815260040160405180910390fd5b601f8190556040518181527fd319ef78d2b690bb773fcccc2d096306bac7c9222dd0bb6b300f461e4a376b4390602001611f50565b3360009081526005602052604090205460ff166139cf57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0384166000908152600c602052604090205460ff16613a08576040516310cec38560e21b815260040160405180910390fd5b613a14848484846150e7565b336001600160a01b0385167f10a73de7ab6e9023aa6e2bc23f7abf4dcef591487e7e55f44c00e34fe60d56db613a4a8486615bcc565b6040519081526020016115c8565b613a63601a8261472e565b15613a8157604051630809740d60e01b815260040160405180910390fd5b6001600160a01b03811660009081526019602052604090205460ff1615613abb57604051632f3d320560e01b815260040160405180910390fd5b613ac6601a82614e70565b506001600160a01b03811660008181526001602052604080822080546001600160a01b0319163390811790915590519092917fed3faef50715743626cd57de74281a2b17cdbfc11c0486feda541fb911e0293d91a350565b6003546001600160a01b03163314613b495760405163070545c960e51b815260040160405180910390fd5b6001600160a01b038116613b705760405163d92e233d60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b0383169081179091556040519081527feb931b4b5a98d20a6b1e6693a7c59d8e337a06e2f1473bb776e19251db7ae25090602001611f50565b6003546001600160a01b03163314613be95760405163070545c960e51b815260040160405180910390fd5b62015180811015613c0d57604051633f384aad60e21b815260040160405180910390fd5b60228190556040518181527f54aafa56429e22230b52f1495588ffc632277d74f3a85ec755e13ac50c1584d990602001611f50565b60026000541415613c655760405162461bcd60e51b81526004016115f990615d4b565b600260009081556001600160a01b03858116825260016020526040909120548591163314613ca657604051636efb4f4160e11b815260040160405180910390fd5b6001600160a01b03808616600090815260256020908152604080832093881683529290522054613cd890603c90615bcc565b4211613cf757604051631e0b407560e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054831115613d3d5760405163024ae82d60e61b815260040160405180910390fd5b6001600160a01b0385166000908152600c602052604090205460ff1615613d775760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b038086166000908152600e6020908152604080832093881683529290529081208054859290613dae908490615bb5565b90915550613dc890506001600160a01b0385168385614fb8565b6001600160a01b038086166000908152600e6020908152604080832093881683529290522054613e16576001600160a01b0385166000908152601160205260409020613e1490856150bc565b505b816001600160a01b0316846001600160a01b0316866001600160a01b03167f53e982dd9ec088d634c74c98fbbc161f808b4b6469a26c657120b9a31cb34bfe86604051613e6591815260200190565b60405180910390a450506001600055505050565b336000818152600c602052604090205460ff1615613eaa5760405163ad2fdf3b60e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff1615613ee4576040516362e6201d60e01b815260040160405180910390fd5b613eef601a8261472e565b613f0b5760405162941a5760e11b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290522054821115613f515760405163356680b760e01b815260040160405180910390fd5b6001600160a01b038082166000908152600e6020908152604080832093881683529290529081208054849290613f88908490615bb5565b90915550613fa290506001600160a01b0385168484614fb8565b826001600160a01b0316816001600160a01b0316856001600160a01b03167f46f2180879a7123a197cc3828c28955d70d661c70acbdc02450daf5f9a9c1cfa85613fea614df8565b6040805192835260208301919091520160405180910390a450505050565b6003546001600160a01b031633146140335760405163070545c960e51b815260040160405180910390fd5b60218190556040518181527f24d51b415694a791b1c77df7817c075ac82b83ce611bcd8627d2e66cf37aa3e790602001611f50565b6003546001600160a01b031633146140935760405163070545c960e51b815260040160405180910390fd5b6001600160a01b0381166140ba5760405163d92e233d60e01b815260040160405180910390fd5b6140c5600954614f70565b601c80546001600160a01b0319166001600160a01b0383169081179091556040519081527f1d1a3e7caf0717056e48dc8aefa54d806c7af86324fece4e5d49f8e1f01f84bf90602001611f50565b6003546001600160a01b0316331461413e5760405163070545c960e51b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1661417757604051633ca0d42760e11b815260040160405180910390fd5b6001600160a01b038116600081815260066020908152604091829020805460ff1916905590519182527f5e8bd21d0a98cb2caf33706e56139ff40ffbdca7ec5d9d412a0a2292496dc70e9101611f50565b6003546001600160a01b031633146141f35760405163070545c960e51b815260040160405180910390fd5b6141fc816152a9565b50565b3360009081526005602052604090205460ff1661422f57604051637e57b1e160e01b815260040160405180910390fd5b6001600160a01b0383166000908152600c602052604090205460ff16614268576040516310cec38560e21b815260040160405180910390fd5b6001600160a01b038316600090815260116020526040902061428a908361472e565b6142a757604051632eda7a1160e01b815260040160405180910390fd5b6001600160a01b038084166000908152600e60209081526040808320938616835292905220548111156142ec5760405162919bed60e01b815260040160405180910390fd5b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb90604401602060405180830381600087803b15801561433a57600080fd5b505af192505050801561436a575060408051601f3d908101601f1916820190925261436791810190615de6565b60015b61437357614375565b505b6001600160a01b038084166000908152600e60209081526040808320938616835292905290812080548392906143ac908490615bb5565b90915550506001600160a01b038084166000908152600e60209081526040808320938616835292905220546143ff576001600160a01b03831660009081526011602052604090206143fd90836150bc565b505b604080516001600160a01b038481168252602082018490523392908616917f20262b97130b5cb8f80624eed2733df2b05db4a0789b4a3d0157e1d3183331049101612382565b3360009081526006602052604090205460ff1661447557604051630942721960e31b815260040160405180910390fd5b6001600160a01b0381166000908152600c602052604090205460ff16156144af576040516304ee891b60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600c6020526040808220805460ff19166001179055513392917f070125a1c0f5202217aae14ec399abfaaa13c2fd98a91d43bd3a897dd4751e8091a350565b6000614507614df8565b602e5561451560078761472e565b801561454657506001600160a01b038087166000908152600d60209081526040808320938916835292905220548411155b801561456a57506001600160a01b0386166000908152600a60205260409020548311155b801561459957506001600160a01b0386166000908152600b602052604090205482906145969042615bb5565b10155b156145dd577f4851cad52e624c8f7a1d44c28a80db05988ba2451fc0db6b0ec338d8eca95afb602e546040516145d191815260200190565b60405180910390a15060015b95945050505050565b6003546001600160a01b031633146146115760405163070545c960e51b815260040160405180910390fd5b61461c601a8361472e565b61463957604051636211d34960e01b815260040160405180910390fd5b61464282615020565b6001600160a01b0382166000908152600f60205260408120805483929061466a908490615bcc565b90915550506001600160a01b038216600081815260296020908152604080832054600f909252918290205491517f5abcf5031fdbd3badb9d1e09094208de329aee72730e87650f346584205d23d1926146ca928252602082015260400190565b60405180910390a25050565b6000602254826146e69190615e8b565b610ec29083615bb5565b600060225483101561223d576022546147098385615d82565b6147139190615db7565b9050610ec2565b606060006147278361532c565b9392505050565b6001600160a01b03811660009081526001830160205260408120541515614727565b6000610ec282602254602354615388565b600260005414156147845760405162461bcd60e51b81526004016115f990615d4b565b600260009081556001600160a01b03841681526012602052604090206147aa908361472e565b6147c6576040516241cfa560e21b815260040160405180910390fd5b6001600160a01b0380841660009081526028602090815260408083209386168352929052205481111561480c5760405163435b562560e01b815260040160405180910390fd5b61481583615436565b6000614824610eb2838561496f565b6001600160a01b038516600090815260106020526040902054909150156148da576001600160a01b038416600090815260106020908152604080832054600f90925290912054614875908390615d82565b61487f9190615db7565b6001600160a01b0385166000908152600f6020526040812080549091906148a7908490615bb5565b90915550506001600160a01b038416600090815260106020526040812080548392906148d4908490615bb5565b90915550505b6001600160a01b03808516600090815260286020908152604080832093871683529290529081208054849290614911908490615bb5565b90915550506001600160a01b03808516600090815260286020908152604080832093871683529290522054614964576001600160a01b038416600090815260126020526040902061496290846150bc565b505b505060016000555050565b6001600160a01b0381166000908152602b602052604081206001015415610ec2576001600160a01b03821660009081526014602052604081205460ff166149e1576001600160a01b0383166000908152602b60205260409020546149dc90600160381b900460060b615be4565b614a05565b6001600160a01b0383166000908152602b6020526040902054600160381b900460060b5b601e5460225460405163a0d2710760e01b815260048101889052600684900b602482015260448101919091529192506001600160a01b03169063a0d271079060640160206040518083038186803b158015614a5f57600080fd5b505afa158015614a73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9c9190615c0b565b6000614aa2426146d6565b6001600160a01b038316600090815260296020526040902054101561141657614ad260225442610cc09190615bb5565b6001600160a01b03831660009081526029602052604090205411614b4857614af982615436565b6001600160a01b038216600090815260106020908152604080832054600f90925290912055614b27426146d6565b6001600160a01b038316600090815260296020526040902055506001919050565b6022546001600160a01b038316600090815260296020526040902054614b6e9042615bb5565b10614bca57614b7c82615436565b6001600160a01b038216600090815260106020908152604080832054600f83528184205560225460299092528220805491929091614bbb908490615bcc565b90915550600191506114169050565b614bd3426146d6565b6001600160a01b0383166000908152602a60205260409020541015611416576001600160a01b038216600090815260106020526040902054614c1483615436565b6001600160a01b038316600090815260106020908152604080832054600f909252909120548291614c4491615d82565b614c4e9190615db7565b6001600160a01b0384166000908152600f602052604090205550919050565b6001600160a01b038116600090815260296020526040902054614cb290614c949042615bb5565b6001600160a01b0383166000908152601060205260409020546146f0565b6001600160a01b0382166000908152600f602052604081208054909190614cda908490615bcc565b90915550506001600160a01b03166000908152602960205260409020429055565b6001600160a01b0383166000908152600f6020526040902054811115614d345760405163356680b760e01b815260040160405180910390fd5b6001600160a01b0383166000908152602a60209081526040808320429055600f90915281208054839290614d69908490615bb5565b90915550506001600160a01b038083166000908152600d60209081526040808320601c5490941683529290529081208054839290614da8908490615bcc565b90915550506001600160a01b0382166000908152600a602052604081208054839290614dd5908490615bcc565b925050819055508060096000828254614dee9190615bcc565b9091555050505050565b6000603f5a614e08906040615d82565b610db09190615db7565b60048054600380546001600160a01b0383166001600160a01b031991821681179092559091169091556040519081527f5d5d6e01b731c3e68060f7fe13156f6197d4aeffc2d6f498e34c717ae616b7349060200160405180910390a1565b6000614727836001600160a01b03841661545b565b601c54601d5460405163095ea7b360e01b81526001600160a01b0391821660048201526024810184905291169063095ea7b390604401602060405180830381600087803b158015614ed557600080fd5b505af1158015614ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f0d9190615de6565b50601d5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f25906024015b600060405180830381600087803b158015614f5557600080fd5b505af1158015614f69573d6000803e3d6000fd5b5050505050565b8060096000828254614f829190615bb5565b9091555050601d5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d6890602401614f3b565b6040516001600160a01b03831660248201526044810182905261501b90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526154aa565b505050565b61502981614a97565b5061503381614c6d565b6001600160a01b0381166000908152600f6020908152604080832054601090925290912054615062919061557c565b6001600160a01b039091166000908152600f6020526040902055565b6040516001600160a01b03808516602483015283166044820152606481018290526150b69085906323b872dd60e01b90608401614fe4565b50505050565b6000614727836001600160a01b038416615592565b6000610ec2825490565b60006147278383615685565b601c546001600160a01b038481169116146151ce576003546001600160a01b038085169163a9059cbb911661511c8486615bcc565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561516257600080fd5b505af1925050508015615192575060408051601f3d908101601f1916820190925261518f91810190615de6565b60015b6151cc573d8080156151c0576040519150601f19603f3d011682016040523d82523d6000602084013e6151c5565b606091505b50506151ce565b505b6001600160a01b038085166000908152600d6020908152604080832093871683529290529081208054849290615205908490615bb5565b90915550506001600160a01b03808516600090815260186020908152604080832093871683529290529081208054839290615241908490615bb5565b909155505050505050565b6000808486602e5461525e9190615bb5565b6152689190615bcc565b9050670de0b6b3a7640000846127106152818685615d82565b61528b9190615db7565b6152959190615d82565b61529f9190615db7565b9695505050505050565b6001600160a01b0381166152d05760405163d92e233d60e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b038381169182179092556003546040805191909316815260208101919091527f6353ec38ac394f8be94bfafcdd3580d356470599059eaeebedc3207e1cc03dec9101611f50565b60608160000180548060200260200160405190810160405280929190818152602001828054801561537c57602002820191906000526020600020905b815481526020019060010190808311615368575b50505050509050919050565b6000808060001985870985870292508281108382030391505080600014156153c257600084116153b757600080fd5b508290049050614727565b8084116153ce57600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b61543f816156af565b6001600160a01b03909116600090815260106020526040902055565b60008181526001830160205260408120546154a257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ec2565b506000610ec2565b60006154ff826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166157ea9092919063ffffffff16565b80519091501561501b578080602001905181019061551d9190615de6565b61501b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016115f9565b600081831061558b5781614727565b5090919050565b6000818152600183016020526040812054801561567b5760006155b6600183615bb5565b85549091506000906155ca90600190615bb5565b905081811461562f5760008660000182815481106155ea576155ea615c24565b906000526020600020015490508087600001848154811061560d5761560d615c24565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061564057615640615e9f565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610ec2565b6000915050610ec2565b600082600001828154811061569c5761569c615c24565b9060005260206000200154905092915050565b6000805b6001600160a01b03831660009081526012602052604090206156d4906150d1565b81101561223d576001600160a01b03831660009081526012602052604081206156fd90836150db565b905061570a60268261472e565b156157d757615718426146d6565b6001600160a01b0382166000908152602b60205260409020600101541461579657615742816111fc565b6001600160a01b0382166000908152602b6020908152604091829020835181549285015166ffffffffffffff908116600160381b026001600160701b03199094169116179190911781559101516001909101555b6001600160a01b038085166000908152602860209081526040808320938516835292905220546157ca90610eb2908361496f565b6157d49084615bcc565b92505b50806157e281615dcb565b9150506156b3565b6060610d9c848460008585843b6158435760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016115f9565b600080866001600160a01b0316858760405161585f9190615ee1565b60006040518083038185875af1925050503d806000811461589c576040519150601f19603f3d011682016040523d82523d6000602084013e6158a1565b606091505b50915091506158b18282866158bc565b979650505050505050565b606083156158cb575081614727565b8251156158db5782518084602001fd5b8160405162461bcd60e51b81526004016115f99190615efd565b6001600160a01b03811681146141fc57600080fd5b60006020828403121561591c57600080fd5b8135614727816158f5565b6000806040838503121561593a57600080fd5b8235615945816158f5565b91506020830135615955816158f5565b809150509250929050565b6020808252825182820181905260009190848201906040850190845b818110156159a15783516001600160a01b03168352928401929184019160010161597c565b50909695505050505050565b600080604083850312156159c057600080fd5b82356159cb816158f5565b946020939093013593505050565b6000806000606084860312156159ee57600080fd5b83356159f9816158f5565b92506020840135615a09816158f5565b929592945050506040919091013590565b600060208284031215615a2c57600080fd5b5035919050565b600080600060608486031215615a4857600080fd5b8335615a53816158f5565b9250602084013591506040840135615a6a816158f5565b809150509250925092565b600080600060608486031215615a8a57600080fd5b8335615a95816158f5565b92506020840135615aa5816158f5565b91506040840135615a6a816158f5565b60008060008060808587031215615acb57600080fd5b8435615ad6816158f5565b93506020850135615ae6816158f5565b93969395505050506040820135916060013590565b60008060008060808587031215615b1157600080fd5b8435615b1c816158f5565b93506020850135615b2c816158f5565b9250604085013591506060850135615b43816158f5565b939692955090935050565b600080600080600060a08688031215615b6657600080fd5b8535615b71816158f5565b94506020860135615b81816158f5565b94979496505050506040830135926060810135926080909101359150565b634e487b7160e01b600052601160045260246000fd5b600082821015615bc757615bc7615b9f565b500390565b60008219821115615bdf57615bdf615b9f565b500190565b60008160060b667fffffffffffff19811415615c0257615c02615b9f565b60000392915050565b600060208284031215615c1d57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b81811015615c8957845163ffffffff1683529383019391830191600101615c67565b5090979650505050505050565b8051600681900b811461141657600080fd5b8051801515811461141657600080fd5b600080600060608486031215615ccd57600080fd5b615cd684615c96565b9250615ce460208501615c96565b9150615cf260408501615ca8565b90509250925092565b60008160060b8360060b6000811281667fffffffffffff1901831281151615615d2657615d26615b9f565b81667fffffffffffff018313811615615d4157615d41615b9f565b5090039392505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000816000190483118215151615615d9c57615d9c615b9f565b500290565b634e487b7160e01b600052601260045260246000fd5b600082615dc657615dc6615da1565b500490565b6000600019821415615ddf57615ddf615b9f565b5060010190565b600060208284031215615df857600080fd5b61472782615ca8565b60008083128015600160ff1b850184121615615e1f57615e1f615b9f565b6001600160ff1b0384018313811615615e3a57615e3a615b9f565b50500390565b600060208284031215615e5257600080fd5b8151614727816158f5565b600080600060608486031215615e7257600080fd5b8351925060208401519150604084015190509250925092565b600082615e9a57615e9a615da1565b500690565b634e487b7160e01b600052603160045260246000fd5b60005b83811015615ed0578181015183820152602001615eb8565b838111156150b65750506000910152565b60008251615ef3818460208701615eb5565b9190910192915050565b6020815260008251806020840152615f1c816040850160208701615eb5565b601f01601f1916919091016040019291505056feee3f0daba9837d1ab0597acf34328550e4832d02e24e467825e7c2dd318c3820a264697066735822122092dd1a4589672def8dde508250ee75a31216dad323e874a66fb20fdcae6d923064736f6c63430008080033", + "devdoc": { + "kind": "dev", + "methods": { + "acceptJobMigration(address,address)": { + "details": "Unbond/withdraw process doesn't get migrated", + "params": { + "_fromJob": "The address of the job that requested to migrate", + "_toJob": "The address to which the job wants to migrate to" + } + }, + "acceptJobOwnership(address)": { + "params": { + "_job": "The address of the job" + } + }, + "activate(address)": { + "params": { + "_bonding": "The asset being activated as bond collateral" + } + }, + "addJob(address)": { + "params": { + "_job": "Address of the contract for which work should be performed" + } + }, + "addLiquidityToJob(address,address,uint256)": { + "params": { + "_amount": "The amount of liquidity tokens to add", + "_job": "The address of the job to assign liquidity to", + "_liquidity": "The liquidity being added" + } + }, + "addTokenCreditsToJob(address,address,uint256)": { + "params": { + "_amount": "The amount of credit being added", + "_job": "The address of the job being credited", + "_token": "The address of the token being credited" + } + }, + "approveLiquidity(address)": { + "details": "Function should be called after setting an oracle in Keep3rHelperSidechain", + "params": { + "_liquidity": "Address of the liquidity token being approved" + } + }, + "approvedLiquidities()": { + "returns": { + "_list": "An array of addresses with all the approved liquidity pairs" + } + }, + "bond(address,uint256)": { + "params": { + "_amount": "The amount of bonding asset being bonded", + "_bonding": "The asset being bonded" + } + }, + "bondedPayment(address,uint256)": { + "details": "Pays the keeper that performs the work with KP3R", + "params": { + "_keeper": "Address of the keeper that performed the work", + "_payment": "The reward that should be allocated for the job" + } + }, + "changeJobOwnership(address,address)": { + "params": { + "_job": "The address of the job", + "_newOwner": "The address of the proposed new owner" + } + }, + "constructor": { + "params": { + "_governor": "Address of governor", + "_keep3rEscrow": "Address of sidechain Keep3rEscrow", + "_keep3rHelperSidechain": "Address of sidechain Keep3rHelper", + "_wrappedKP3R": "Address of wrapped KP3R implementation" + } + }, + "directTokenPayment(address,address,uint256)": { + "details": "Pays the keeper that performs the work with a specific token", + "params": { + "_amount": "The reward that should be allocated", + "_keeper": "Address of the keeper that performed the work", + "_token": "The asset being awarded to the keeper" + } + }, + "dispute(address)": { + "params": { + "_jobOrKeeper": "The address in dispute" + } + }, + "forceLiquidityCreditsToJob(address,uint256)": { + "params": { + "_amount": "The amount of liquidity credits to gift", + "_job": "The address of the job being credited" + } + }, + "isBondedKeeper(address,address,uint256,uint256,uint256)": { + "details": "Should be used for protected functions", + "params": { + "_age": "The minimum keeper age required", + "_bond": "The bond token being evaluated", + "_earned": "The minimum funds earned in the keepers lifetime", + "_keeper": "The keeper to check", + "_minBond": "The minimum amount of bonded tokens" + }, + "returns": { + "_isBondedKeeper": "Whether the `_keeper` meets the given requirements" + } + }, + "isKeeper(address)": { + "details": "Can be used for general (non critical) functions", + "params": { + "_keeper": "The keeper being investigated" + }, + "returns": { + "_isKeeper": "Whether the address passed as a parameter is a keeper or not" + } + }, + "jobLiquidityCredits(address)": { + "params": { + "_job": "The address of the job of which we want to know the liquidity credits" + }, + "returns": { + "_liquidityCredits": "The liquidity credits of a given job" + } + }, + "jobPeriodCredits(address)": { + "params": { + "_job": "The address of the job of which we want to know the period credits" + }, + "returns": { + "_periodCredits": "The credits the given job has at the current period" + } + }, + "jobs()": { + "returns": { + "_list": "Array with all the jobs in _jobs" + } + }, + "keepers()": { + "returns": { + "_list": "Array with all the keepers in _keepers" + } + }, + "migrateJob(address,address)": { + "params": { + "_fromJob": "The address of the job that is requesting to migrate", + "_toJob": "The address at which the job is requesting to migrate" + } + }, + "observeLiquidity(address)": { + "params": { + "_liquidity": "Address of the liquidity token being observed" + } + }, + "quoteLiquidity(address,uint256)": { + "details": "_periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod", + "params": { + "_amount": "The amount of liquidity to provide", + "_liquidity": "The address of the liquidity to provide" + }, + "returns": { + "_periodCredits": "The amount of KP3R periodically minted for the given liquidity" + } + }, + "resolve(address)": { + "params": { + "_jobOrKeeper": "The address cleared" + } + }, + "revoke(address)": { + "params": { + "_keeper": "The address being slashed" + } + }, + "revokeLiquidity(address)": { + "params": { + "_liquidity": "The liquidity no longer accepted" + } + }, + "sendDust(address,uint256,address)": { + "params": { + "_amount": "The amont of the token that will be transferred", + "_to": "The address that will receive the idle funds", + "_token": "The token that will be transferred" + } + }, + "setBondTime(uint256)": { + "params": { + "_bond": "The new bond time" + } + }, + "setFee(uint256)": { + "params": { + "_fee": "The new fee" + } + }, + "setInflationPeriod(uint256)": { + "params": { + "_inflationPeriod": "The new inflation period" + } + }, + "setKeep3rHelper(address)": { + "params": { + "_keep3rHelper": "The Keep3rHelper address" + } + }, + "setKeep3rV1(address)": { + "params": { + "_keep3rV1": "The Keep3rV1 address" + } + }, + "setKeep3rV1Proxy(address)": { + "params": { + "_keep3rV1Proxy": "The Keep3rV1Proxy address" + } + }, + "setLiquidityMinimum(uint256)": { + "params": { + "_liquidityMinimum": "The new minimum amount of liquidity" + } + }, + "setPendingGovernor(address)": { + "params": { + "_pendingGovernor": "Address of the proposed new governor" + } + }, + "setRewardPeriodTime(uint256)": { + "params": { + "_rewardPeriodTime": "The new amount of time required to pass between rewards" + } + }, + "setUnbondTime(uint256)": { + "params": { + "_unbond": "The new unbond time" + } + }, + "slash(address,address,uint256,uint256)": { + "params": { + "_bondAmount": "The bonded amount being slashed", + "_bonded": "The asset being slashed", + "_keeper": "The address being slashed", + "_unbondAmount": "The pending unbond amount being slashed" + } + }, + "slashLiquidityFromJob(address,address,uint256)": { + "params": { + "_amount": "The amount of liquidity that will be slashed", + "_job": "The address being slashed", + "_liquidity": "The address of the liquidity that will be slashed" + } + }, + "slashTokenFromJob(address,address,uint256)": { + "params": { + "_amount": "The amount of the token that will be slashed", + "_job": "The address of the job from which the token will be slashed", + "_token": "The address of the token that will be slashed" + } + }, + "totalJobCredits(address)": { + "params": { + "_job": "The address of the job of which we want to know the total credits" + }, + "returns": { + "_credits": "The total credits of the given job" + } + }, + "unbond(address,uint256)": { + "params": { + "_amount": "Allows for partial unbonding", + "_bonding": "The asset being unbonded" + } + }, + "unbondLiquidityFromJob(address,address,uint256)": { + "details": "Can only be called by the job's owner", + "params": { + "_amount": "The amount of liquidity being removed", + "_job": "The address of the job being unbonded from", + "_liquidity": "The liquidity being unbonded" + } + }, + "virtualReserves()": { + "returns": { + "_virtualReserves": "The surplus amount of wKP3Rs in escrow contract" + } + }, + "withdraw(address)": { + "params": { + "_bonding": "The asset to withdraw from the bonding pool" + } + }, + "withdrawLiquidityFromJob(address,address,address)": { + "params": { + "_job": "The address of the job being withdrawn from", + "_liquidity": "The liquidity being withdrawn", + "_receiver": "The address that will receive the withdrawn liquidity" + } + }, + "withdrawTokenCreditsFromJob(address,address,uint256,address)": { + "params": { + "_amount": "The amount of token to be withdrawn", + "_job": "The address of the job from which the credits are withdrawn", + "_receiver": "The user that will receive tokens", + "_token": "The address of the token being withdrawn" + } + }, + "worked(address)": { + "details": "Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter" + }, + "worked(address,uint256)": { + "details": "Uses a USD per gas unit payment mechanism", + "params": { + "_keeper": "Address of the keeper that performed the work", + "_usdPerGasUnit": "Units of USD (in wei) per gas unit that should be rewarded to the keeper" + } + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "AlreadyAJob()": [ + { + "notice": "Throws when the address that is trying to register as a job is already a job" + } + ], + "AlreadyAKeeper()": [ + { + "notice": "Throws when the address that is trying to register as a keeper is already a keeper" + } + ], + "AlreadyDisputed()": [ + { + "notice": "Throws when a job or keeper is already disputed" + } + ], + "BondsLocked()": [ + { + "notice": "Throws if the time required to bond an asset has not passed yet" + } + ], + "BondsUnexistent()": [ + { + "notice": "Throws if there are no bonded assets" + } + ], + "Deprecated()": [ + { + "notice": "Throws when job contract calls deprecated worked(address) function" + } + ], + "Disputed()": [ + { + "notice": "Throws if either a job or a keeper is disputed" + } + ], + "DisputerExistent()": [ + { + "notice": "Throws if the address is already a registered disputer" + } + ], + "DisputerUnexistent()": [ + { + "notice": "Throws if caller is not a registered disputer" + } + ], + "GasNotInitialized()": [ + { + "notice": "Throws if work method was called without calling isKeeper or isBondedKeeper" + } + ], + "InsufficientFunds()": [ + { + "notice": "Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job" + } + ], + "InsufficientJobTokenCredits()": [ + { + "notice": "Throws when the user tries to withdraw more tokens than it has" + } + ], + "InvalidAddress()": [ + { + "notice": "Thrown if an address is invalid" + } + ], + "InvalidAmount()": [ + { + "notice": "Thrown if an amount is invalid" + } + ], + "JobAlreadyAdded()": [ + { + "notice": "Throws when trying to add a job that has already been added" + } + ], + "JobDisputed()": [ + { + "notice": "Throws when an action that requires an undisputed job is applied on a disputed job" + } + ], + "JobLiquidityInsufficient()": [ + { + "notice": "Throws when trying to remove more liquidity than the job has" + } + ], + "JobLiquidityLessThanMin()": [ + { + "notice": "Throws when trying to add less liquidity than the minimum liquidity required" + } + ], + "JobLiquidityUnexistent()": [ + { + "notice": "Throws when the job doesn't have the requested liquidity" + } + ], + "JobMigrationImpossible()": [ + { + "notice": "Throws when the address of the job that requests to migrate wants to migrate to its same address" + } + ], + "JobMigrationLocked()": [ + { + "notice": "Throws when cooldown between migrations has not yet passed" + } + ], + "JobMigrationUnavailable()": [ + { + "notice": "Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping" + } + ], + "JobTokenCreditsLocked()": [ + { + "notice": "Throws when the token withdraw cooldown has not yet passed" + } + ], + "JobTokenInsufficient()": [ + { + "notice": "Throws when someone tries to slash more tokens than the job has" + } + ], + "JobTokenUnexistent()": [ + { + "notice": "Throws when the token trying to be slashed doesn't exist" + } + ], + "JobUnapproved()": [ + { + "notice": "Throws if the address claiming to be a job is not in the list of approved jobs" + } + ], + "JobUnavailable()": [ + { + "notice": "Throws when an address is passed as a job, but that address is not a job" + } + ], + "LengthMismatch()": [ + { + "notice": "Thrown if the lengths of a set of lists mismatch" + } + ], + "LiquidityPairApproved()": [ + { + "notice": "Throws when the liquidity being approved has already been approved" + } + ], + "LiquidityPairUnapproved()": [ + { + "notice": "Throws when trying to add liquidity to an unapproved pool" + } + ], + "LiquidityPairUnexistent()": [ + { + "notice": "Throws when the liquidity being removed has not been approved" + } + ], + "MinRewardPeriod()": [ + { + "notice": "Throws if the reward period is less than the minimum reward period time" + } + ], + "NotDisputed()": [ + { + "notice": "Throws when a job or keeper is not disputed and someone tries to resolve the dispute" + } + ], + "OnlyDisputer()": [ + { + "notice": "Throws if the msg.sender is not a disputer or is not a part of governance" + } + ], + "OnlyGovernor()": [ + { + "notice": "Thrown if a non-governor user tries to call a OnlyGovernor function" + } + ], + "OnlyJobOwner()": [ + { + "notice": "Throws when the caller of the function is not the job owner" + } + ], + "OnlyPendingGovernor()": [ + { + "notice": "Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function" + } + ], + "OnlyPendingJobOwner()": [ + { + "notice": "Throws when the caller of the function is not the pending job owner" + } + ], + "OnlySlasher()": [ + { + "notice": "Throws if the msg.sender is not a slasher or is not a part of governance" + } + ], + "SlasherExistent()": [ + { + "notice": "Throws if the address is already a registered slasher" + } + ], + "SlasherUnexistent()": [ + { + "notice": "Throws if caller is not a registered slasher" + } + ], + "TokenUnallowed()": [ + { + "notice": "Throws when the token is KP3R, as it should not be used for direct token payments" + } + ], + "UnbondsLocked()": [ + { + "notice": "Throws if the time required to withdraw the bonds has not passed yet" + } + ], + "UnbondsUnexistent()": [ + { + "notice": "Throws if there are no bonds to withdraw" + } + ], + "ZeroAddress()": [ + { + "notice": "Thrown if an address is the zero address" + } + ], + "ZeroAmount()": [ + { + "notice": "Thrown if an amount is zero" + } + ] + }, + "events": { + "Activation(address,address,uint256)": { + "notice": "Emitted when Keep3rKeeperFundable#activate is called" + }, + "BondTimeChange(uint256)": { + "notice": "Emitted when bondTime is changed" + }, + "Bonding(address,address,uint256)": { + "notice": "Emitted when the bonding process of a new keeper begins" + }, + "Dispute(address,address)": { + "notice": "Emitted when a keeper or a job is disputed" + }, + "DisputerAdded(address)": { + "notice": "Emitted when a disputer is added" + }, + "DisputerRemoved(address)": { + "notice": "Emitted when a disputer is removed" + }, + "DustSent(address,uint256,address)": { + "notice": "Emitted when dust is sent" + }, + "FeeChange(uint256)": { + "notice": "Emitted when the fee is changed" + }, + "InflationPeriodChange(uint256)": { + "notice": "Emitted when the inflationPeriod is changed" + }, + "JobAddition(address,address)": { + "notice": "Emitted when Keep3rJobManager#addJob is called" + }, + "JobMigrationRequested(address,address)": { + "notice": "Emitted when Keep3rJobMigration#migrateJob function is called" + }, + "JobMigrationSuccessful(address,address)": { + "notice": "Emitted when Keep3rJobMigration#acceptJobMigration function is called" + }, + "JobOwnershipAssent(address,address,address)": { + "notice": "Emitted when Keep3rJobOwnership#JobOwnershipAssent is called" + }, + "JobOwnershipChange(address,address,address)": { + "notice": "Emitted when Keep3rJobOwnership#changeJobOwnership is called" + }, + "JobSlashLiquidity(address,address,address,uint256)": { + "notice": "Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called" + }, + "JobSlashToken(address,address,address,uint256)": { + "notice": "Emitted when Keep3rJobDisputable#slashTokenFromJob is called" + }, + "Keep3rHelperChange(address)": { + "notice": "Emitted when the Keep3rHelper address is changed" + }, + "Keep3rV1Change(address)": { + "notice": "Emitted when the Keep3rV1 address is changed" + }, + "Keep3rV1ProxyChange(address)": { + "notice": "Emitted when the Keep3rV1Proxy address is changed" + }, + "KeeperRevoke(address,address)": { + "notice": "Emitted when Keep3rKeeperDisputable#revoke is called" + }, + "KeeperSlash(address,address,uint256)": { + "notice": "Emitted when Keep3rKeeperDisputable#slash is called" + }, + "KeeperValidation(uint256)": { + "notice": "Emitted when a keeper is validated before a job" + }, + "KeeperWork(address,address,address,uint256,uint256)": { + "notice": "Emitted when a keeper works a job" + }, + "LiquidityAddition(address,address,address,uint256)": { + "notice": "Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called" + }, + "LiquidityApproval(address)": { + "notice": "Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called" + }, + "LiquidityCreditsForced(address,uint256,uint256)": { + "notice": "Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called" + }, + "LiquidityCreditsReward(address,uint256,uint256,uint256)": { + "notice": "Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called" + }, + "LiquidityMinimumChange(uint256)": { + "notice": "Emitted when _liquidityMinimum is changed" + }, + "LiquidityRevocation(address)": { + "notice": "Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called" + }, + "LiquidityWithdrawal(address,address,address,uint256)": { + "notice": "Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called" + }, + "PendingGovernorAccepted(address)": { + "notice": "Emitted when a new governor is set" + }, + "PendingGovernorSet(address,address)": { + "notice": "Emitted when a new pending governor is set" + }, + "Resolve(address,address)": { + "notice": "Emitted when a dispute is resolved" + }, + "RewardPeriodTimeChange(uint256)": { + "notice": "Emitted when _rewardPeriodTime is changed" + }, + "SlasherAdded(address)": { + "notice": "Emitted when a slasher is added" + }, + "SlasherRemoved(address)": { + "notice": "Emitted when a slasher is removed" + }, + "TokenCreditAddition(address,address,address,uint256)": { + "notice": "Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called" + }, + "TokenCreditWithdrawal(address,address,address,uint256)": { + "notice": "Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called" + }, + "UnbondTimeChange(uint256)": { + "notice": "Emitted when _unbondTime is changed" + }, + "Unbonding(address,address,uint256)": { + "notice": "Emitted when a keeper or job begins the unbonding process to withdraw the funds" + }, + "Withdrawal(address,address,uint256)": { + "notice": "Emitted when Keep3rKeeperFundable#withdraw is called" + } + }, + "kind": "user", + "methods": { + "acceptJobMigration(address,address)": { + "notice": "Completes the migration process for a job" + }, + "acceptJobOwnership(address)": { + "notice": "The proposed address accepts to be the owner of the job" + }, + "acceptPendingGovernor()": { + "notice": "Allows a proposed governor to accept the governance" + }, + "activate(address)": { + "notice": "End of the bonding process after bonding time has passed" + }, + "addDisputer(address)": { + "notice": "Registers a disputer by updating the disputers mapping" + }, + "addJob(address)": { + "notice": "Allows any caller to add a new job" + }, + "addLiquidityToJob(address,address,uint256)": { + "notice": "Allows anyone to fund a job with liquidity" + }, + "addSlasher(address)": { + "notice": "Registers a slasher by updating the slashers mapping" + }, + "addTokenCreditsToJob(address,address,uint256)": { + "notice": "Add credit to a job to be paid out for work" + }, + "approveLiquidity(address)": { + "notice": "Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20" + }, + "approvedLiquidities()": { + "notice": "Lists liquidity pairs" + }, + "bond(address,uint256)": { + "notice": "Beginning of the bonding process" + }, + "bondTime()": { + "notice": "The amount of time required to pass after a keeper has bonded assets for it to be able to activate" + }, + "bondedPayment(address,uint256)": { + "notice": "Implemented by jobs to show that a keeper performed work" + }, + "bonds(address,address)": { + "notice": "Mapping (job => bonding => amount)" + }, + "canActivateAfter(address,address)": { + "notice": "Tracks when a bonding for a keeper can be activated" + }, + "canWithdrawAfter(address,address)": { + "notice": "Tracks when keeper bonds are ready to be withdrawn" + }, + "changeJobOwnership(address,address)": { + "notice": "Proposes a new address to be the owner of the job" + }, + "directTokenPayment(address,address,uint256)": { + "notice": "Implemented by jobs to show that a keeper performed work" + }, + "dispute(address)": { + "notice": "Allows governor to create a dispute for a given keeper/job" + }, + "disputers(address)": { + "notice": "Tracks whether the address is a disputer or not" + }, + "disputes(address)": { + "notice": "Tracks if a keeper or job has a pending dispute" + }, + "fee()": { + "notice": "The fee to be sent to governor when a user adds liquidity to a job" + }, + "firstSeen(address)": { + "notice": "Tracks when a keeper was first registered" + }, + "forceLiquidityCreditsToJob(address,uint256)": { + "notice": "Gifts liquidity credits to the specified job" + }, + "hasBonded(address)": { + "notice": "Checks whether the address has ever bonded an asset" + }, + "inflationPeriod()": { + "notice": "The inflation period is the denominator used to regulate the emission of KP3R" + }, + "isBondedKeeper(address,address,uint256,uint256,uint256)": { + "notice": "Confirms if the current keeper is registered and has a minimum bond of any asset." + }, + "isKeeper(address)": { + "notice": "Confirms if the current keeper is registered" + }, + "jobLiquidityCredits(address)": { + "notice": "Returns the liquidity credits of a given job" + }, + "jobOwner(address)": { + "notice": "Maps the job to the owner of the job" + }, + "jobPendingOwner(address)": { + "notice": "Maps the job to its pending owner" + }, + "jobPeriodCredits(address)": { + "notice": "Returns the credits of a given job for the current period" + }, + "jobTokenCredits(address,address)": { + "notice": "The current token credits available for a job" + }, + "jobTokenCreditsAddedAt(address,address)": { + "notice": "Last block where tokens were added to the job" + }, + "jobs()": { + "notice": "Lists all jobs" + }, + "keep3rHelper()": { + "notice": "Address of Keep3rHelper's contract" + }, + "keep3rV1()": { + "notice": "Address of Keep3rV1's contract" + }, + "keep3rV1Proxy()": { + "notice": "Address of Keep3rV1Proxy's contract" + }, + "keepers()": { + "notice": "Lists all keepers" + }, + "liquidityAmount(address,address)": { + "notice": "Amount of liquidity in a specified job" + }, + "liquidityMinimum()": { + "notice": "The minimum amount of liquidity required to fund a job per liquidity" + }, + "migrateJob(address,address)": { + "notice": "Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping" + }, + "observeLiquidity(address)": { + "notice": "Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing" + }, + "pendingBonds(address,address)": { + "notice": "Tracks the amount of assets deposited in pending bonds" + }, + "pendingJobMigrations(address)": { + "notice": "Maps the jobs that have requested a migration to the address they have requested to migrate to" + }, + "pendingUnbonds(address,address)": { + "notice": "Tracks how much keeper bonds are to be withdrawn" + }, + "quoteLiquidity(address,uint256)": { + "notice": "Calculates how many credits should be rewarded periodically for a given liquidity amount" + }, + "removeDisputer(address)": { + "notice": "Removes a disputer by updating the disputers mapping" + }, + "removeSlasher(address)": { + "notice": "Removes a slasher by updating the slashers mapping" + }, + "resolve(address)": { + "notice": "Allows governor to resolve a dispute on a keeper/job" + }, + "revoke(address)": { + "notice": "Blacklists a keeper from participating in the network" + }, + "revokeLiquidity(address)": { + "notice": "Revoke a liquidity pair from being accepted in future" + }, + "rewardPeriodTime()": { + "notice": "The amount of time between each scheduled credits reward given to a job" + }, + "rewardedAt(address)": { + "notice": "Last time the job was rewarded liquidity credits" + }, + "sendDust(address,uint256,address)": { + "notice": "Allows an authorized user to transfer the tokens or eth that may have been left in a contract" + }, + "setBondTime(uint256)": { + "notice": "Sets the bond time required to activate as a keeper" + }, + "setFee(uint256)": { + "notice": "Sets the new fee" + }, + "setInflationPeriod(uint256)": { + "notice": "Sets the new inflation period" + }, + "setKeep3rHelper(address)": { + "notice": "Sets the Keep3rHelper address" + }, + "setKeep3rV1(address)": { + "notice": "Sets the Keep3rV1 address" + }, + "setKeep3rV1Proxy(address)": { + "notice": "Sets the Keep3rV1Proxy address" + }, + "setLiquidityMinimum(uint256)": { + "notice": "Sets the minimum amount of liquidity required to fund a job" + }, + "setPendingGovernor(address)": { + "notice": "Allows a governor to propose a new governor" + }, + "setRewardPeriodTime(uint256)": { + "notice": "Sets the time required to pass between rewards for jobs" + }, + "setUnbondTime(uint256)": { + "notice": "Sets the unbond time required unbond what has been bonded" + }, + "slash(address,address,uint256,uint256)": { + "notice": "Allows governor to slash a keeper based on a dispute" + }, + "slashLiquidityFromJob(address,address,uint256)": { + "notice": "Allows governor or slasher to slash liquidity from a job" + }, + "slashTokenFromJob(address,address,uint256)": { + "notice": "Allows governor or slasher to slash a job specific token" + }, + "slashers(address)": { + "notice": "Tracks whether the address is a slasher or not" + }, + "totalBonds()": { + "notice": "Tracks the total amount of bonded KP3Rs in the contract" + }, + "totalJobCredits(address)": { + "notice": "Calculates the total credits of a given job" + }, + "unbond(address,uint256)": { + "notice": "Beginning of the unbonding process" + }, + "unbondLiquidityFromJob(address,address,uint256)": { + "notice": "Unbond liquidity for a job" + }, + "unbondTime()": { + "notice": "The amount of time required to pass before a keeper can unbond what he has bonded" + }, + "virtualReserves()": { + "notice": "The surplus amount of wKP3Rs in escrow contract" + }, + "withdraw(address)": { + "notice": "Withdraw funds after unbonding has finished" + }, + "withdrawLiquidityFromJob(address,address,address)": { + "notice": "Withdraw liquidity from a job" + }, + "withdrawTokenCreditsFromJob(address,address,uint256,address)": { + "notice": "Withdraw credit from a job" + }, + "workCompleted(address)": { + "notice": "Tracks the total KP3R earnings of a keeper since it started working" + }, + "worked(address,uint256)": { + "notice": "Implemented by jobs to show that a keeper performed work" + }, + "workedAt(address)": { + "notice": "Last time the job was worked" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 309, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_status", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 8568, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "jobOwner", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 8574, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "jobPendingOwner", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 82, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "governor", + "offset": 0, + "slot": "3", + "type": "t_address" + }, + { + "astId": 85, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "pendingGovernor", + "offset": 0, + "slot": "4", + "type": "t_address" + }, + { + "astId": 6136, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "slashers", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 6142, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "disputers", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 5604, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_keepers", + "offset": 0, + "slot": "7", + "type": "t_struct(AddressSet)1930_storage" + }, + { + "astId": 5608, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "totalBonds", + "offset": 0, + "slot": "9", + "type": "t_uint256" + }, + { + "astId": 5614, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "workCompleted", + "offset": 0, + "slot": "10", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 5620, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "firstSeen", + "offset": 0, + "slot": "11", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 5626, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "disputes", + "offset": 0, + "slot": "12", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 5634, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "bonds", + "offset": 0, + "slot": "13", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5642, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "jobTokenCredits", + "offset": 0, + "slot": "14", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5647, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_jobLiquidityCredits", + "offset": 0, + "slot": "15", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 5652, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_jobPeriodCredits", + "offset": 0, + "slot": "16", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 5658, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_jobTokens", + "offset": 0, + "slot": "17", + "type": "t_mapping(t_address,t_struct(AddressSet)1930_storage)" + }, + { + "astId": 5664, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_jobLiquidities", + "offset": 0, + "slot": "18", + "type": "t_mapping(t_address,t_struct(AddressSet)1930_storage)" + }, + { + "astId": 5669, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_liquidityPool", + "offset": 0, + "slot": "19", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 5674, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_isKP3RToken0", + "offset": 0, + "slot": "20", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 5682, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "pendingBonds", + "offset": 0, + "slot": "21", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5690, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "canActivateAfter", + "offset": 0, + "slot": "22", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5698, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "canWithdrawAfter", + "offset": 0, + "slot": "23", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5706, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "pendingUnbonds", + "offset": 0, + "slot": "24", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5712, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "hasBonded", + "offset": 0, + "slot": "25", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 5716, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_jobs", + "offset": 0, + "slot": "26", + "type": "t_struct(AddressSet)1930_storage" + }, + { + "astId": 5829, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "keep3rV1", + "offset": 0, + "slot": "28", + "type": "t_address" + }, + { + "astId": 5833, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "keep3rV1Proxy", + "offset": 0, + "slot": "29", + "type": "t_address" + }, + { + "astId": 5837, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "keep3rHelper", + "offset": 0, + "slot": "30", + "type": "t_address" + }, + { + "astId": 5842, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "bondTime", + "offset": 0, + "slot": "31", + "type": "t_uint256" + }, + { + "astId": 5847, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "unbondTime", + "offset": 0, + "slot": "32", + "type": "t_uint256" + }, + { + "astId": 5852, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "liquidityMinimum", + "offset": 0, + "slot": "33", + "type": "t_uint256" + }, + { + "astId": 5857, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "rewardPeriodTime", + "offset": 0, + "slot": "34", + "type": "t_uint256" + }, + { + "astId": 5862, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "inflationPeriod", + "offset": 0, + "slot": "35", + "type": "t_uint256" + }, + { + "astId": 5867, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "fee", + "offset": 0, + "slot": "36", + "type": "t_uint256" + }, + { + "astId": 6569, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "jobTokenCreditsAddedAt", + "offset": 0, + "slot": "37", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 6812, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_approvedLiquidities", + "offset": 0, + "slot": "38", + "type": "t_struct(AddressSet)1930_storage" + }, + { + "astId": 6820, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "liquidityAmount", + "offset": 0, + "slot": "40", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 6826, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "rewardedAt", + "offset": 0, + "slot": "41", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 6832, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "workedAt", + "offset": 0, + "slot": "42", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 6838, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_tick", + "offset": 0, + "slot": "43", + "type": "t_mapping(t_address,t_struct(TickCache)14687_storage)" + }, + { + "astId": 8289, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "pendingJobMigrations", + "offset": 0, + "slot": "44", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 8295, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_migrationCreatedAt", + "offset": 0, + "slot": "45", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 8692, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_initialGas", + "offset": 0, + "slot": "46", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_int56": { + "encoding": "inplace", + "label": "int56", + "numberOfBytes": "7" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1930_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1930_storage" + }, + "t_mapping(t_address,t_struct(TickCache)14687_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct IKeep3rJobFundableLiquidity.TickCache)", + "numberOfBytes": "32", + "value": "t_struct(TickCache)14687_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1930_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1929, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1629_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1629_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1624, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1628, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(TickCache)14687_storage": { + "encoding": "inplace", + "label": "struct IKeep3rJobFundableLiquidity.TickCache", + "members": [ + { + "astId": 14682, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "current", + "offset": 0, + "slot": "0", + "type": "t_int56" + }, + { + "astId": 14684, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "difference", + "offset": 7, + "slot": "0", + "type": "t_int56" + }, + { + "astId": 14686, + "contract": "solidity/contracts/sidechain/Keep3rSidechain.sol:Keep3rSidechain", + "label": "period", + "offset": 0, + "slot": "1", + "type": "t_uint256" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/Kp3rWethOracle.json b/deployments/polygon/Kp3rWethOracle.json new file mode 100644 index 0000000..4301f39 --- /dev/null +++ b/deployments/polygon/Kp3rWethOracle.json @@ -0,0 +1,987 @@ +{ + "address": "0x6A060BF6579318c15138160Ee1f1d225fcC9D409", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint32", + "name": "blockTimestamp", + "type": "uint32" + }, + { + "internalType": "int56", + "name": "tickCumulative", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "secondsAgos", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint128", + "name": "_liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { + "internalType": "uint128", + "name": "token0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "token1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "feeProtocol0", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "feeProtocol1", + "type": "uint8" + } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "feeProtocol", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "unlocked", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsInside", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + }, + { + "internalType": "int256", + "name": "amountSpecified", + "type": "int256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int16", + "name": "wordPosition", + "type": "int16" + } + ], + "name": "tickBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsOutside", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/polygon/WethUsdOracle.json b/deployments/polygon/WethUsdOracle.json new file mode 100644 index 0000000..c52b6df --- /dev/null +++ b/deployments/polygon/WethUsdOracle.json @@ -0,0 +1,987 @@ +{ + "address": "0x45dDa9cb7c25131DF268515131f647d726f50608", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint32", + "name": "blockTimestamp", + "type": "uint32" + }, + { + "internalType": "int56", + "name": "tickCumulative", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "secondsAgos", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint128", + "name": "_liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { + "internalType": "uint128", + "name": "token0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "token1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "feeProtocol0", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "feeProtocol1", + "type": "uint8" + } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "feeProtocol", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "unlocked", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsInside", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + }, + { + "internalType": "int256", + "name": "amountSpecified", + "type": "int256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int16", + "name": "wordPosition", + "type": "int16" + } + ], + "name": "tickBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsOutside", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/polygon/solcInputs/3a869c3b827b38468356d50761a61b47.json b/deployments/polygon/solcInputs/3a869c3b827b38468356d50761a61b47.json new file mode 100644 index 0000000..35e21ab --- /dev/null +++ b/deployments/polygon/solcInputs/3a869c3b827b38468356d50761a61b47.json @@ -0,0 +1,325 @@ +{ + "language": "Solidity", + "sources": { + "solidity/contracts/Keep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport './peripherals/jobs/Keep3rJobs.sol';\nimport './peripherals/keepers/Keep3rKeepers.sol';\nimport '@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol';\n\ncontract Keep3r is IKeep3r, Keep3rJobs, Keep3rKeepers {\n constructor(\n address _governor,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(_governor) {}\n}\n" + }, + "solidity/interfaces/IKeep3r.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './peripherals/IKeep3rJobs.sol';\nimport './peripherals/IKeep3rKeepers.sol';\nimport './peripherals/IKeep3rParameters.sol';\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rV2 contract\n/// @notice This contract inherits all the functionality of Keep3rV2\ninterface IKeep3r is IKeep3rJobs, IKeep3rKeepers, IKeep3rParameters {\n\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobManager.sol';\nimport './Keep3rJobWorkable.sol';\nimport './Keep3rJobDisputable.sol';\n\nabstract contract Keep3rJobs is IKeep3rJobs, Keep3rJobManager, Keep3rJobWorkable, Keep3rJobDisputable {}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\nimport './Keep3rKeeperDisputable.sol';\n\nabstract contract Keep3rKeepers is IKeep3rKeepers, Keep3rKeeperDisputable {}\n" + }, + "@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {Governable} from './Governable.sol';\nimport {IDustCollector} from '../interfaces/IDustCollector.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\n/// @title DustCollector contract\nabstract contract DustCollector is IDustCollector, Governable {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IDustCollector\n address public constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n /// @inheritdoc IDustCollector\n function sendDust(address _token, uint256 _amount, address _to) external onlyGovernor {\n if (_to == address(0)) revert ZeroAddress();\n if (_token == ETH_ADDRESS) payable(_to).transfer(_amount);\n else IERC20(_token).safeTransfer(_to, _amount);\n emit DustSent(_token, _amount, _to);\n }\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rJobs.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rJobOwnership contract\n/// @notice Handles the ownership of the jobs\ninterface IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called\n /// @param _job The address of the job proposed to have a change of owner\n /// @param _owner The current owner of the job\n /// @param _pendingOwner The new address proposed to be the owner of the job\n event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner);\n\n /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called\n /// @param _job The address of the job which the proposed owner will now own\n /// @param _previousOwner The previous owner of the job\n /// @param _newOwner The new owner of the job\n event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the job owner\n error OnlyJobOwner();\n\n /// @notice Throws when the caller of the function is not the pending job owner\n error OnlyPendingJobOwner();\n\n // Variables\n\n /// @notice Maps the job to the owner of the job\n /// @param _job The address of the job\n /// @return _owner The address of the owner of the job\n function jobOwner(address _job) external view returns (address _owner);\n\n /// @notice Maps the job to its pending owner\n /// @param _job The address of the job\n /// @return _pendingOwner The address of the pending owner of the job\n function jobPendingOwner(address _job) external view returns (address _pendingOwner);\n\n // Methods\n\n /// @notice Proposes a new address to be the owner of the job\n /// @param _job The address of the job\n /// @param _newOwner The address of the proposed new owner\n function changeJobOwnership(address _job, address _newOwner) external;\n\n /// @notice The proposed address accepts to be the owner of the job\n /// @param _job The address of the job\n function acceptJobOwnership(address _job) external;\n}\n\n/// @title Keep3rJobManager contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobManager is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobManager#addJob is called\n /// @param _job The address of the job to add\n /// @param _jobOwner The job's owner\n event JobAddition(address indexed _job, address indexed _jobOwner);\n\n // Errors\n\n /// @notice Throws when trying to add a job that has already been added\n error JobAlreadyAdded();\n\n /// @notice Throws when the address that is trying to register as a keeper is already a keeper\n error AlreadyAKeeper();\n\n // Methods\n\n /// @notice Allows any caller to add a new job\n /// @param _job Address of the contract for which work should be performed\n function addJob(address _job) external;\n}\n\n/// @title Keep3rJobFundableCredits contract\n/// @notice Handles the addition and withdrawal of credits from a job\ninterface IKeep3rJobFundableCredits is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being provided\n /// @param _provider The user that calls the function\n /// @param _amount The amount of credit being added to the job\n event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The credit being withdrawn from the job\n /// @param _receiver The user that receives the tokens\n /// @param _amount The amount of credit withdrawn\n event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token is KP3R, as it should not be used for direct token payments\n error TokenUnallowed();\n\n /// @notice Throws when the token withdraw cooldown has not yet passed\n error JobTokenCreditsLocked();\n\n /// @notice Throws when the user tries to withdraw more tokens than it has\n error InsufficientJobTokenCredits();\n\n // Variables\n\n /// @notice Last block where tokens were added to the job\n /// @param _job The address of the job credited\n /// @param _token The address of the token credited\n /// @return _timestamp The last block where tokens were added to the job\n function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Add credit to a job to be paid out for work\n /// @param _job The address of the job being credited\n /// @param _token The address of the token being credited\n /// @param _amount The amount of credit being added\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw credit from a job\n /// @param _job The address of the job from which the credits are withdrawn\n /// @param _token The address of the token being withdrawn\n /// @param _amount The amount of token to be withdrawn\n /// @param _receiver The user that will receive tokens\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobFundableLiquidity contract\n/// @notice Handles the funding of jobs through specific liquidity pairs\ninterface IKeep3rJobFundableLiquidity is IKeep3rJobOwnership {\n // Events\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being approved\n event LiquidityApproval(address _liquidity);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called\n /// @param _liquidity The address of the liquidity pair being revoked\n event LiquidityRevocation(address _liquidity);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job to which liquidity will be added\n /// @param _liquidity The address of the liquidity being added\n /// @param _provider The user that calls the function\n /// @param _amount The amount of liquidity being added\n event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount);\n\n /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called\n /// @param _job The address of the job of which liquidity will be withdrawn from\n /// @param _liquidity The address of the liquidity being withdrawn\n /// @param _receiver The receiver of the liquidity tokens\n /// @param _amount The amount of liquidity being withdrawn from the job\n event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n /// @param _periodCredits The credits of the job for the current period\n event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits);\n\n /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called\n /// @param _job The address of the job whose credits will be updated\n /// @param _rewardedAt The time at which the job was last rewarded\n /// @param _currentCredits The current credits of the job\n event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits);\n\n // Errors\n\n /// @notice Throws when the liquidity being approved has already been approved\n error LiquidityPairApproved();\n\n /// @notice Throws when the liquidity being removed has not been approved\n error LiquidityPairUnexistent();\n\n /// @notice Throws when trying to add liquidity to an unapproved pool\n error LiquidityPairUnapproved();\n\n /// @notice Throws when the job doesn't have the requested liquidity\n error JobLiquidityUnexistent();\n\n /// @notice Throws when trying to remove more liquidity than the job has\n error JobLiquidityInsufficient();\n\n /// @notice Throws when trying to add less liquidity than the minimum liquidity required\n error JobLiquidityLessThanMin();\n\n // Structs\n\n /// @notice Stores the tick information of the different liquidity pairs\n struct TickCache {\n int56 current; // Tracks the current tick\n int56 difference; // Stores the difference between the current tick and the last tick\n uint256 period; // Stores the period at which the last observation was made\n }\n\n // Variables\n\n /// @notice Lists liquidity pairs\n /// @return _list An array of addresses with all the approved liquidity pairs\n function approvedLiquidities() external view returns (address[] memory _list);\n\n /// @notice Amount of liquidity in a specified job\n /// @param _job The address of the job being checked\n /// @param _liquidity The address of the liquidity we are checking\n /// @return _amount Amount of liquidity in the specified job\n function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount);\n\n /// @notice Last time the job was rewarded liquidity credits\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits\n function rewardedAt(address _job) external view returns (uint256 _timestamp);\n\n /// @notice Last time the job was worked\n /// @param _job The address of the job being checked\n /// @return _timestamp Timestamp of the last time the job was worked\n function workedAt(address _job) external view returns (uint256 _timestamp);\n\n // Methods\n\n /// @notice Returns the liquidity credits of a given job\n /// @param _job The address of the job of which we want to know the liquidity credits\n /// @return _amount The liquidity credits of a given job\n function jobLiquidityCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Returns the credits of a given job for the current period\n /// @param _job The address of the job of which we want to know the period credits\n /// @return _amount The credits the given job has at the current period\n function jobPeriodCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates the total credits of a given job\n /// @param _job The address of the job of which we want to know the total credits\n /// @return _amount The total credits of the given job\n function totalJobCredits(address _job) external view returns (uint256 _amount);\n\n /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount\n /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod\n /// @param _liquidity The address of the liquidity to provide\n /// @param _amount The amount of liquidity to provide\n /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits);\n\n /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information\n /// @param _liquidity The address of the liquidity pair being observed\n /// @return _tickCache The updated TickCache\n function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache);\n\n /// @notice Gifts liquidity credits to the specified job\n /// @param _job The address of the job being credited\n /// @param _amount The amount of liquidity credits to gift\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;\n\n /// @notice Approve a liquidity pair for being accepted in future\n /// @param _liquidity The address of the liquidity accepted\n function approveLiquidity(address _liquidity) external;\n\n /// @notice Revoke a liquidity pair from being accepted in future\n /// @param _liquidity The liquidity no longer accepted\n function revokeLiquidity(address _liquidity) external;\n\n /// @notice Allows anyone to fund a job with liquidity\n /// @param _job The address of the job to assign liquidity to\n /// @param _liquidity The liquidity being added\n /// @param _amount The amount of liquidity tokens to add\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Unbond liquidity for a job\n /// @dev Can only be called by the job's owner\n /// @param _job The address of the job being unbonded from\n /// @param _liquidity The liquidity being unbonded\n /// @param _amount The amount of liquidity being removed\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n\n /// @notice Withdraw liquidity from a job\n /// @param _job The address of the job being withdrawn from\n /// @param _liquidity The liquidity being withdrawn\n /// @param _receiver The address that will receive the withdrawn liquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external;\n}\n\n/// @title Keep3rJobMigration contract\n/// @notice Handles the migration process of jobs to different addresses\ninterface IKeep3rJobMigration is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobMigration#migrateJob function is called\n /// @param _fromJob The address of the job that requests to migrate\n /// @param _toJob The address at which the job requests to migrate\n event JobMigrationRequested(address indexed _fromJob, address _toJob);\n\n /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address at which the job had requested to migrate\n event JobMigrationSuccessful(address _fromJob, address indexed _toJob);\n\n // Errors\n\n /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address\n error JobMigrationImpossible();\n\n /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping\n error JobMigrationUnavailable();\n\n /// @notice Throws when cooldown between migrations has not yet passed\n error JobMigrationLocked();\n\n // Variables\n\n /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to\n /// @return _toJob The address to which the job has requested to migrate to\n function pendingJobMigrations(address _fromJob) external view returns (address _toJob);\n\n // Methods\n\n /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping\n /// @param _fromJob The address of the job that is requesting to migrate\n /// @param _toJob The address at which the job is requesting to migrate\n function migrateJob(address _fromJob, address _toJob) external;\n\n /// @notice Completes the migration process for a job\n /// @dev Unbond/withdraw process doesn't get migrated\n /// @param _fromJob The address of the job that requested to migrate\n /// @param _toJob The address to which the job wants to migrate to\n function acceptJobMigration(address _fromJob, address _toJob) external;\n}\n\n/// @title Keep3rJobWorkable contract\n/// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs\ninterface IKeep3rJobWorkable is IKeep3rJobMigration {\n // Events\n\n /// @notice Emitted when a keeper is validated before a job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation\n event KeeperValidation(uint256 _gasLeft);\n\n /// @notice Emitted when a keeper works a job\n /// @param _credit The address of the asset in which the keeper is paid\n /// @param _job The address of the job the keeper has worked\n /// @param _keeper The address of the keeper that has worked the job\n /// @param _payment The amount that has been paid out to the keeper in exchange for working the job\n /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment\n event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _payment, uint256 _gasLeft);\n\n // Errors\n\n /// @notice Throws if work method was called without calling isKeeper or isBondedKeeper\n error GasNotInitialized();\n\n /// @notice Throws if the address claiming to be a job is not in the list of approved jobs\n error JobUnapproved();\n\n /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job\n error InsufficientFunds();\n\n // Methods\n\n /// @notice Confirms if the current keeper is registered\n /// @dev Can be used for general (non critical) functions\n /// @param _keeper The keeper being investigated\n /// @return _isKeeper Whether the address passed as a parameter is a keeper or not\n function isKeeper(address _keeper) external returns (bool _isKeeper);\n\n /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset.\n /// @dev Should be used for protected functions\n /// @param _keeper The keeper to check\n /// @param _bond The bond token being evaluated\n /// @param _minBond The minimum amount of bonded tokens\n /// @param _earned The minimum funds earned in the keepers lifetime\n /// @param _age The minimum keeper age required\n /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool _isBondedKeeper);\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n function worked(address _keeper) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _payment The reward that should be allocated for the job\n function bondedPayment(address _keeper, uint256 _payment) external;\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Pays the keeper that performs the work with a specific token\n /// @param _token The asset being awarded to the keeper\n /// @param _keeper Address of the keeper that performed the work\n /// @param _amount The reward that should be allocated\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external;\n}\n\n/// @title Keep3rJobDisputable contract\n/// @notice Handles the actions that can be taken on a disputed job\ninterface IKeep3rJobDisputable is IKeep3rDisputable, IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity {\n // Events\n\n /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token being slashed\n /// @param _slasher The user that slashes the token\n /// @param _amount The amount of the token being slashed\n event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called\n /// @param _job The address of the job from which the liquidity will be slashed\n /// @param _liquidity The address of the liquidity being slashed\n /// @param _slasher The user that slashes the liquidity\n /// @param _amount The amount of the liquidity being slashed\n event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the token trying to be slashed doesn't exist\n error JobTokenUnexistent();\n\n /// @notice Throws when someone tries to slash more tokens than the job has\n error JobTokenInsufficient();\n\n // Methods\n\n /// @notice Allows governor or slasher to slash a job specific token\n /// @param _job The address of the job from which the token will be slashed\n /// @param _token The address of the token that will be slashed\n /// @param _amount The amount of the token that will be slashed\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external;\n\n /// @notice Allows governor or slasher to slash liquidity from a job\n /// @param _job The address being slashed\n /// @param _liquidity The address of the liquidity that will be slashed\n /// @param _amount The amount of liquidity that will be slashed\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\ninterface IKeep3rJobs is IKeep3rJobWorkable, IKeep3rJobManager, IKeep3rJobDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rKeepers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rDisputable.sol';\n\n/// @title Keep3rKeeperFundable contract\n/// @notice Handles the actions required to become a keeper\ninterface IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperFundable#activate is called\n /// @param _keeper The keeper that has been activated\n /// @param _bond The asset the keeper has bonded\n /// @param _amount The amount of the asset the keeper has bonded\n event Activation(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperFundable#withdraw is called\n /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function\n /// @param _bond The asset to withdraw from the bonding pool\n /// @param _amount The amount of funds withdrawn\n event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount);\n\n // Errors\n\n /// @notice Throws when the address that is trying to register as a job is already a job\n error AlreadyAJob();\n\n // Methods\n\n /// @notice Beginning of the bonding process\n /// @param _bonding The asset being bonded\n /// @param _amount The amount of bonding asset being bonded\n function bond(address _bonding, uint256 _amount) external;\n\n /// @notice Beginning of the unbonding process\n /// @param _bonding The asset being unbonded\n /// @param _amount Allows for partial unbonding\n function unbond(address _bonding, uint256 _amount) external;\n\n /// @notice End of the bonding process after bonding time has passed\n /// @param _bonding The asset being activated as bond collateral\n function activate(address _bonding) external;\n\n /// @notice Withdraw funds after unbonding has finished\n /// @param _bonding The asset to withdraw from the bonding pool\n function withdraw(address _bonding) external;\n}\n\n/// @title Keep3rKeeperDisputable contract\n/// @notice Handles the actions that can be taken on a disputed keeper\ninterface IKeep3rKeeperDisputable is IKeep3rDisputable, IKeep3rKeeperFundable {\n // Events\n\n /// @notice Emitted when Keep3rKeeperDisputable#slash is called\n /// @param _keeper The address of the slashed keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#slash\n /// @param _amount The amount of credits slashed from the keeper\n event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount);\n\n /// @notice Emitted when Keep3rKeeperDisputable#revoke is called\n /// @param _keeper The address of the revoked keeper\n /// @param _slasher The user that called Keep3rKeeperDisputable#revoke\n event KeeperRevoke(address indexed _keeper, address indexed _slasher);\n\n // Methods\n\n /// @notice Allows governor to slash a keeper based on a dispute\n /// @param _keeper The address being slashed\n /// @param _bonded The asset being slashed\n /// @param _bondAmount The bonded amount being slashed\n /// @param _unbondAmount The pending unbond amount being slashed\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external;\n\n /// @notice Blacklists a keeper from participating in the network\n /// @param _keeper The address being slashed\n function revoke(address _keeper) external;\n}\n\n// solhint-disable-next-line no-empty-blocks\n\n/// @title Keep3rKeepers contract\ninterface IKeep3rKeepers is IKeep3rKeeperDisputable {\n\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rAccountance.sol';\n\n/// @title Keep3rParameters contract\n/// @notice Handles and sets all the required parameters for Keep3r\ninterface IKeep3rParameters is IKeep3rAccountance {\n // Events\n\n /// @notice Emitted when the Keep3rHelper address is changed\n /// @param _keep3rHelper The address of Keep3rHelper's contract\n event Keep3rHelperChange(address _keep3rHelper);\n\n /// @notice Emitted when the Keep3rV1 address is changed\n /// @param _keep3rV1 The address of Keep3rV1's contract\n event Keep3rV1Change(address _keep3rV1);\n\n /// @notice Emitted when the Keep3rV1Proxy address is changed\n /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n event Keep3rV1ProxyChange(address _keep3rV1Proxy);\n\n /// @notice Emitted when bondTime is changed\n /// @param _bondTime The new bondTime\n event BondTimeChange(uint256 _bondTime);\n\n /// @notice Emitted when _liquidityMinimum is changed\n /// @param _liquidityMinimum The new _liquidityMinimum\n event LiquidityMinimumChange(uint256 _liquidityMinimum);\n\n /// @notice Emitted when _unbondTime is changed\n /// @param _unbondTime The new _unbondTime\n event UnbondTimeChange(uint256 _unbondTime);\n\n /// @notice Emitted when _rewardPeriodTime is changed\n /// @param _rewardPeriodTime The new _rewardPeriodTime\n event RewardPeriodTimeChange(uint256 _rewardPeriodTime);\n\n /// @notice Emitted when the inflationPeriod is changed\n /// @param _inflationPeriod The new inflationPeriod\n event InflationPeriodChange(uint256 _inflationPeriod);\n\n /// @notice Emitted when the fee is changed\n /// @param _fee The new token credits fee\n event FeeChange(uint256 _fee);\n\n // Variables\n\n /// @notice Address of Keep3rHelper's contract\n /// @return _keep3rHelper The address of Keep3rHelper's contract\n function keep3rHelper() external view returns (address _keep3rHelper);\n\n /// @notice Address of Keep3rV1's contract\n /// @return _keep3rV1 The address of Keep3rV1's contract\n function keep3rV1() external view returns (address _keep3rV1);\n\n /// @notice Address of Keep3rV1Proxy's contract\n /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract\n function keep3rV1Proxy() external view returns (address _keep3rV1Proxy);\n\n /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate\n /// @return _days The required bondTime in days\n function bondTime() external view returns (uint256 _days);\n\n /// @notice The amount of time required to pass before a keeper can unbond what he has bonded\n /// @return _days The required unbondTime in days\n function unbondTime() external view returns (uint256 _days);\n\n /// @notice The minimum amount of liquidity required to fund a job per liquidity\n /// @return _amount The minimum amount of liquidity in KP3R\n function liquidityMinimum() external view returns (uint256 _amount);\n\n /// @notice The amount of time between each scheduled credits reward given to a job\n /// @return _days The reward period in days\n function rewardPeriodTime() external view returns (uint256 _days);\n\n /// @notice The inflation period is the denominator used to regulate the emission of KP3R\n /// @return _period The denominator used to regulate the emission of KP3R\n function inflationPeriod() external view returns (uint256 _period);\n\n /// @notice The fee to be sent to governor when a user adds liquidity to a job\n /// @return _amount The fee amount to be sent to governor when a user adds liquidity to a job\n function fee() external view returns (uint256 _amount);\n\n // Errors\n\n /// @notice Throws if the reward period is less than the minimum reward period time\n error MinRewardPeriod();\n\n /// @notice Throws if either a job or a keeper is disputed\n error Disputed();\n\n /// @notice Throws if there are no bonded assets\n error BondsUnexistent();\n\n /// @notice Throws if the time required to bond an asset has not passed yet\n error BondsLocked();\n\n /// @notice Throws if there are no bonds to withdraw\n error UnbondsUnexistent();\n\n /// @notice Throws if the time required to withdraw the bonds has not passed yet\n error UnbondsLocked();\n\n // Methods\n\n /// @notice Sets the Keep3rHelper address\n /// @param _keep3rHelper The Keep3rHelper address\n function setKeep3rHelper(address _keep3rHelper) external;\n\n /// @notice Sets the Keep3rV1 address\n /// @param _keep3rV1 The Keep3rV1 address\n function setKeep3rV1(address _keep3rV1) external;\n\n /// @notice Sets the Keep3rV1Proxy address\n /// @param _keep3rV1Proxy The Keep3rV1Proxy address\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external;\n\n /// @notice Sets the bond time required to activate as a keeper\n /// @param _bond The new bond time\n function setBondTime(uint256 _bond) external;\n\n /// @notice Sets the unbond time required unbond what has been bonded\n /// @param _unbond The new unbond time\n function setUnbondTime(uint256 _unbond) external;\n\n /// @notice Sets the minimum amount of liquidity required to fund a job\n /// @param _liquidityMinimum The new minimum amount of liquidity\n function setLiquidityMinimum(uint256 _liquidityMinimum) external;\n\n /// @notice Sets the time required to pass between rewards for jobs\n /// @param _rewardPeriodTime The new amount of time required to pass between rewards\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external;\n\n /// @notice Sets the new inflation period\n /// @param _inflationPeriod The new inflation period\n function setInflationPeriod(uint256 _inflationPeriod) external;\n\n /// @notice Sets the new fee\n /// @param _fee The new fee\n function setFee(uint256 _fee) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rDisputable contract\n/// @notice Creates/resolves disputes for jobs or keepers\n/// A disputed keeper is slashable and is not able to bond, activate, withdraw or receive direct payments\n/// A disputed job is slashable and is not able to pay the keepers, withdraw tokens or to migrate\ninterface IKeep3rDisputable {\n /// @notice Emitted when a keeper or a job is disputed\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _disputer The user that called the function and disputed the keeper\n event Dispute(address indexed _jobOrKeeper, address indexed _disputer);\n\n /// @notice Emitted when a dispute is resolved\n /// @param _jobOrKeeper The address of the disputed keeper/job\n /// @param _resolver The user that called the function and resolved the dispute\n event Resolve(address indexed _jobOrKeeper, address indexed _resolver);\n\n /// @notice Throws when a job or keeper is already disputed\n error AlreadyDisputed();\n\n /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute\n error NotDisputed();\n\n /// @notice Allows governor to create a dispute for a given keeper/job\n /// @param _jobOrKeeper The address in dispute\n function dispute(address _jobOrKeeper) external;\n\n /// @notice Allows governor to resolve a dispute on a keeper/job\n /// @param _jobOrKeeper The address cleared\n function resolve(address _jobOrKeeper) external;\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rRoles.sol';\n\n/// @title Keep3rDisputable contract\n/// @notice Disputes keepers, or if they're already disputed, it can resolve the case\n/// @dev Argument `bonding` can be the address of either a token or a liquidity\ninterface IKeep3rAccountance is IKeep3rRoles {\n // Events\n\n /// @notice Emitted when the bonding process of a new keeper begins\n /// @param _keeper The caller of Keep3rKeeperFundable#bond function\n /// @param _bonding The asset the keeper has bonded\n /// @param _amount The amount the keeper has bonded\n event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount);\n\n /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds\n /// @param _keeperOrJob The keeper or job that began the unbonding process\n /// @param _unbonding The liquidity pair or asset being unbonded\n /// @param _amount The amount being unbonded\n event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount);\n\n // Variables\n\n /// @notice Tracks the total amount of bonded KP3Rs in the contract\n /// @return _totalBonds The total amount of bonded KP3Rs in the contract\n function totalBonds() external view returns (uint256 _totalBonds);\n\n /// @notice Tracks the total KP3R earnings of a keeper since it started working\n /// @param _keeper The address of the keeper\n /// @return _workCompleted Total KP3R earnings of a keeper since it started working\n function workCompleted(address _keeper) external view returns (uint256 _workCompleted);\n\n /// @notice Tracks when a keeper was first registered\n /// @param _keeper The address of the keeper\n /// @return timestamp The time at which the keeper was first registered\n function firstSeen(address _keeper) external view returns (uint256 timestamp);\n\n /// @notice Tracks if a keeper or job has a pending dispute\n /// @param _keeperOrJob The address of the keeper or job\n /// @return _disputed Whether a keeper or job has a pending dispute\n function disputes(address _keeperOrJob) external view returns (bool _disputed);\n\n /// @notice Tracks how much a keeper has bonded of a certain token\n /// @param _keeper The address of the keeper\n /// @param _bond The address of the token being bonded\n /// @return _bonds Amount of a certain token that a keeper has bonded\n function bonds(address _keeper, address _bond) external view returns (uint256 _bonds);\n\n /// @notice The current token credits available for a job\n /// @param _job The address of the job\n /// @param _token The address of the token bonded\n /// @return _amount The amount of token credits available for a job\n function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);\n\n /// @notice Tracks the amount of assets deposited in pending bonds\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _pendingBonds Amount of a certain asset a keeper has unbonding\n function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds);\n\n /// @notice Tracks when a bonding for a keeper can be activated\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being bonded\n /// @return _timestamp Time at which the bonding for a keeper can be activated\n function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks when keeper bonds are ready to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn\n function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp);\n\n /// @notice Tracks how much keeper bonds are to be withdrawn\n /// @param _keeper The address of the keeper\n /// @param _bonding The address of the token being unbonded\n /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds);\n\n /// @notice Checks whether the address has ever bonded an asset\n /// @param _keeper The address of the keeper\n /// @return _hasBonded Whether the address has ever bonded an asset\n function hasBonded(address _keeper) external view returns (bool _hasBonded);\n\n // Methods\n\n /// @notice Lists all jobs\n /// @return _jobList Array with all the jobs in _jobs\n function jobs() external view returns (address[] memory _jobList);\n\n /// @notice Lists all keepers\n /// @return _keeperList Array with all the keepers in _keepers\n function keepers() external view returns (address[] memory _keeperList);\n\n // Errors\n\n /// @notice Throws when an address is passed as a job, but that address is not a job\n error JobUnavailable();\n\n /// @notice Throws when an action that requires an undisputed job is applied on a disputed job\n error JobDisputed();\n}\n" + }, + "solidity/interfaces/peripherals/IKeep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IDustCollector.sol';\n\n/// @title Keep3rRoles contract\n/// @notice Manages the Keep3r specific roles\ninterface IKeep3rRoles is IBaseErrors, IGovernable, IDustCollector {\n // Events\n\n /// @notice Emitted when a slasher is added\n /// @param _slasher Address of the added slasher\n event SlasherAdded(address _slasher);\n\n /// @notice Emitted when a slasher is removed\n /// @param _slasher Address of the removed slasher\n event SlasherRemoved(address _slasher);\n\n /// @notice Emitted when a disputer is added\n /// @param _disputer Address of the added disputer\n event DisputerAdded(address _disputer);\n\n /// @notice Emitted when a disputer is removed\n /// @param _disputer Address of the removed disputer\n event DisputerRemoved(address _disputer);\n\n // Variables\n\n /// @notice Tracks whether the address is a slasher or not\n /// @param _slasher Address being checked as a slasher\n /// @return _isSlasher Whether the address is a slasher or not\n function slashers(address _slasher) external view returns (bool _isSlasher);\n\n /// @notice Tracks whether the address is a disputer or not\n /// @param _disputer Address being checked as a disputer\n /// @return _isDisputer Whether the address is a disputer or not\n function disputers(address _disputer) external view returns (bool _isDisputer);\n\n // Errors\n\n /// @notice Throws if the address is already a registered slasher\n error SlasherExistent();\n\n /// @notice Throws if caller is not a registered slasher\n error SlasherUnexistent();\n\n /// @notice Throws if the address is already a registered disputer\n error DisputerExistent();\n\n /// @notice Throws if caller is not a registered disputer\n error DisputerUnexistent();\n\n /// @notice Throws if the msg.sender is not a slasher or is not a part of governance\n error OnlySlasher();\n\n /// @notice Throws if the msg.sender is not a disputer or is not a part of governance\n error OnlyDisputer();\n\n // Methods\n\n /// @notice Registers a slasher by updating the slashers mapping\n function addSlasher(address _slasher) external;\n\n /// @notice Removes a slasher by updating the slashers mapping\n function removeSlasher(address _slasher) external;\n\n /// @notice Registers a disputer by updating the disputers mapping\n function addDisputer(address _disputer) external;\n\n /// @notice Removes a disputer by updating the disputers mapping\n function removeDisputer(address _disputer) external;\n}\n" + }, + "@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\ninterface IBaseErrors {\n /// @notice Thrown if an address is invalid\n error InvalidAddress();\n\n /// @notice Thrown if an amount is invalid\n error InvalidAmount();\n\n /// @notice Thrown if the lengths of a set of lists mismatch\n error LengthMismatch();\n\n /// @notice Thrown if an address is the zero address\n error ZeroAddress();\n\n /// @notice Thrown if an amount is zero\n error ZeroAmount();\n}\n" + }, + "@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IBaseErrors} from './IBaseErrors.sol';\n\n/// @title Governable interface\ninterface IGovernable is IBaseErrors {\n // STATE VARIABLES\n\n /// @return _governor Address of the current governor\n function governor() external view returns (address _governor);\n\n /// @return _pendingGovernor Address of the current pending governor\n function pendingGovernor() external view returns (address _pendingGovernor);\n\n // EVENTS\n\n /// @notice Emitted when a new pending governor is set\n /// @param _governor Address of the current governor\n /// @param _pendingGovernor Address of the proposed next governor\n event PendingGovernorSet(address _governor, address _pendingGovernor);\n\n /// @notice Emitted when a new governor is set\n /// @param _newGovernor Address of the new governor\n event PendingGovernorAccepted(address _newGovernor);\n\n // ERRORS\n\n /// @notice Thrown if a non-governor user tries to call a OnlyGovernor function\n error OnlyGovernor();\n\n /// @notice Thrown if a non-pending-governor user tries to call a OnlyPendingGovernor function\n error OnlyPendingGovernor();\n\n // FUNCTIONS\n\n /// @notice Allows a governor to propose a new governor\n /// @param _pendingGovernor Address of the proposed new governor\n function setPendingGovernor(address _pendingGovernor) external;\n\n /// @notice Allows a proposed governor to accept the governance\n function acceptPendingGovernor() external;\n}\n" + }, + "@defi-wonderland/solidity-utils/solidity/interfaces/IDustCollector.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from './IGovernable.sol';\nimport {IBaseErrors} from './IBaseErrors.sol';\n\n/// @title DustCollector interface\ninterface IDustCollector is IBaseErrors, IGovernable {\n // STATE VARIABLES\n\n /// @return _ethAddress Address used to trigger a native token transfer\n // solhint-disable-next-line func-name-mixedcase\n function ETH_ADDRESS() external view returns (address _ethAddress);\n\n // EVENTS\n\n /// @notice Emitted when dust is sent\n /// @param _to The address which wil received the funds\n /// @param _token The token that will be transferred\n /// @param _amount The amount of the token that will be transferred\n event DustSent(address _token, uint256 _amount, address _to);\n\n // FUNCTIONS\n\n /// @notice Allows an authorized user to transfer the tokens or eth that may have been left in a contract\n /// @param _token The token that will be transferred\n /// @param _amount The amont of the token that will be transferred\n /// @param _to The address that will receive the idle funds\n function sendDust(address _token, uint256 _amount, address _to) external;\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobManager is IKeep3rJobManager, Keep3rJobOwnership, Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @inheritdoc IKeep3rJobManager\n function addJob(address _job) external override {\n if (_jobs.contains(_job)) revert JobAlreadyAdded();\n if (hasBonded[_job]) revert AlreadyAKeeper();\n _jobs.add(_job);\n jobOwner[_job] = msg.sender;\n emit JobAddition(_job, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobWorkable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobMigration.sol';\nimport '../../../interfaces/IKeep3rHelper.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rJobWorkable is IKeep3rJobWorkable, Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 internal _initialGas;\n\n /// @inheritdoc IKeep3rJobWorkable\n function isKeeper(address _keeper) external override returns (bool _isKeeper) {\n _initialGas = _getGasLeft();\n if (_keepers.contains(_keeper)) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external override returns (bool _isBondedKeeper) {\n _initialGas = _getGasLeft();\n if (\n _keepers.contains(_keeper) &&\n bonds[_keeper][_bond] >= _minBond &&\n workCompleted[_keeper] >= _earned &&\n block.timestamp - firstSeen[_keeper] >= _age\n ) {\n emit KeeperValidation(_initialGas);\n return true;\n }\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function worked(address _keeper) external virtual override {\n if (_initialGas == 0) revert GasNotInitialized();\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneEthQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _gasLeft = _getGasLeft();\n uint256 _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n _gasLeft = _getGasLeft();\n _payment = _calculatePayment(_gasLeft, _extraGas, _oneEthQuote, _boost);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _gasLeft);\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function bondedPayment(address _keeper, uint256 _payment) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n if (_payment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _payment);\n emit KeeperWork(keep3rV1, _job, _keeper, _payment, _getGasLeft());\n }\n\n /// @inheritdoc IKeep3rJobWorkable\n function directTokenPayment(\n address _token,\n address _keeper,\n uint256 _amount\n ) external override {\n address _job = msg.sender;\n\n if (disputes[_job]) revert JobDisputed();\n if (disputes[_keeper]) revert Disputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientFunds();\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_keeper, _amount);\n emit KeeperWork(_token, _job, _keeper, _amount, _getGasLeft());\n }\n\n function _bondedPayment(\n address _job,\n address _keeper,\n uint256 _payment\n ) internal {\n if (_payment > _jobLiquidityCredits[_job]) revert InsufficientFunds();\n\n workedAt[_job] = block.timestamp;\n _jobLiquidityCredits[_job] -= _payment;\n bonds[_keeper][keep3rV1] += _payment;\n workCompleted[_keeper] += _payment;\n totalBonds += _payment;\n }\n\n /// @notice Calculate amount to be payed in KP3R, taking into account multiple parameters\n /// @param _gasLeft Amount of gas left after working the job\n /// @param _extraGas Amount of expected unaccounted gas\n /// @param _oneEthQuote Amount of KP3R equivalent to 1 ETH\n /// @param _boost Reward given to the keeper for having bonded KP3R tokens\n /// @return _payment Amount to be payed in KP3R tokens\n function _calculatePayment(\n uint256 _gasLeft,\n uint256 _extraGas,\n uint256 _oneEthQuote,\n uint256 _boost\n ) internal view returns (uint256 _payment) {\n uint256 _accountedGas = _initialGas - _gasLeft + _extraGas;\n _payment = (((_accountedGas * _boost) / _BASE) * _oneEthQuote) / 1 ether;\n }\n\n /// @notice Return the gas left and add 1/64 in order to match real gas left at first level of depth (EIP-150)\n /// @return _gasLeft Amount of gas left recording taking into account EIP-150\n function _getGasLeft() internal view returns (uint256 _gasLeft) {\n _gasLeft = (gasleft() * 64) / 63;\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\nimport '../Keep3rDisputable.sol';\n\nabstract contract Keep3rJobDisputable is IKeep3rJobDisputable, Keep3rDisputable, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashTokenFromJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n if (!_jobTokens[_job].contains(_token)) revert JobTokenUnexistent();\n if (jobTokenCredits[_job][_token] < _amount) revert JobTokenInsufficient();\n\n try IERC20(_token).transfer(governor, _amount) {} catch {}\n jobTokenCredits[_job][_token] -= _amount;\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit JobSlashToken(_job, _token, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobDisputable\n function slashLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlySlasher {\n if (!disputes[_job]) revert NotDisputed();\n\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n try IERC20(_liquidity).transfer(governor, _amount) {} catch {}\n emit JobSlashLiquidity(_job, _liquidity, msg.sender, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobOwnership.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nabstract contract Keep3rJobOwnership is IKeep3rJobOwnership {\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n mapping(address => address) public override jobPendingOwner;\n\n /// @inheritdoc IKeep3rJobOwnership\n function changeJobOwnership(address _job, address _newOwner) external override onlyJobOwner(_job) {\n jobPendingOwner[_job] = _newOwner;\n emit JobOwnershipChange(_job, jobOwner[_job], _newOwner);\n }\n\n /// @inheritdoc IKeep3rJobOwnership\n function acceptJobOwnership(address _job) external override onlyPendingJobOwner(_job) {\n address _previousOwner = jobOwner[_job];\n\n jobOwner[_job] = jobPendingOwner[_job];\n delete jobPendingOwner[_job];\n\n emit JobOwnershipAssent(msg.sender, _job, _previousOwner);\n }\n\n modifier onlyJobOwner(address _job) {\n if (msg.sender != jobOwner[_job]) revert OnlyJobOwner();\n _;\n }\n\n modifier onlyPendingJobOwner(address _job) {\n if (msg.sender != jobPendingOwner[_job]) revert OnlyPendingJobOwner();\n _;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '../../interfaces/peripherals/IKeep3rAccountance.sol';\nimport './Keep3rRoles.sol';\n\nabstract contract Keep3rAccountance is IKeep3rAccountance, Keep3rRoles {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @notice List of all enabled keepers\n EnumerableSet.AddressSet internal _keepers;\n\n /// @inheritdoc IKeep3rAccountance\n uint256 public override totalBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override workCompleted;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => uint256) public override firstSeen;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override disputes;\n\n /// @inheritdoc IKeep3rAccountance\n /// @notice Mapping (job => bonding => amount)\n mapping(address => mapping(address => uint256)) public override bonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override jobTokenCredits;\n\n /// @notice The current liquidity credits available for a job\n mapping(address => uint256) internal _jobLiquidityCredits;\n\n /// @notice Map the address of a job to its correspondent periodCredits\n mapping(address => uint256) internal _jobPeriodCredits;\n\n /// @notice Enumerable array of Job Tokens for Credits\n mapping(address => EnumerableSet.AddressSet) internal _jobTokens;\n\n /// @notice List of liquidities that a job has (job => liquidities)\n mapping(address => EnumerableSet.AddressSet) internal _jobLiquidities;\n\n /// @notice Liquidity pool to observe\n mapping(address => address) internal _liquidityPool;\n\n /// @notice Tracks if a pool has KP3R as token0\n mapping(address => bool) internal _isKP3RToken0;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingBonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canActivateAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override canWithdrawAfter;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => mapping(address => uint256)) public override pendingUnbonds;\n\n /// @inheritdoc IKeep3rAccountance\n mapping(address => bool) public override hasBonded;\n\n /// @notice List of all enabled jobs\n EnumerableSet.AddressSet internal _jobs;\n\n /// @inheritdoc IKeep3rAccountance\n function jobs() external view override returns (address[] memory _list) {\n _list = _jobs.values();\n }\n\n /// @inheritdoc IKeep3rAccountance\n function keepers() external view override returns (address[] memory _list) {\n _list = _keepers.values();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rRoles.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IKeep3rRoles.sol';\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport '@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol';\nimport '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\n\ncontract Keep3rRoles is IKeep3rRoles, Governable, DustCollector {\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override slashers;\n\n /// @inheritdoc IKeep3rRoles\n mapping(address => bool) public override disputers;\n\n constructor(address _governor) Governable(_governor) DustCollector() {}\n\n /// @inheritdoc IKeep3rRoles\n function addSlasher(address _slasher) external override onlyGovernor {\n if (_slasher == address(0)) revert ZeroAddress();\n if (slashers[_slasher]) revert SlasherExistent();\n slashers[_slasher] = true;\n emit SlasherAdded(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeSlasher(address _slasher) external override onlyGovernor {\n if (!slashers[_slasher]) revert SlasherUnexistent();\n delete slashers[_slasher];\n emit SlasherRemoved(_slasher);\n }\n\n /// @inheritdoc IKeep3rRoles\n function addDisputer(address _disputer) external override onlyGovernor {\n if (_disputer == address(0)) revert ZeroAddress();\n if (disputers[_disputer]) revert DisputerExistent();\n disputers[_disputer] = true;\n emit DisputerAdded(_disputer);\n }\n\n /// @inheritdoc IKeep3rRoles\n function removeDisputer(address _disputer) external override onlyGovernor {\n if (!disputers[_disputer]) revert DisputerUnexistent();\n delete disputers[_disputer];\n emit DisputerRemoved(_disputer);\n }\n\n /// @notice Functions with this modifier can only be called by either a slasher or governance\n modifier onlySlasher {\n if (!slashers[msg.sender]) revert OnlySlasher();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by either a disputer or governance\n modifier onlyDisputer {\n if (!disputers[msg.sender]) revert OnlyDisputer();\n _;\n }\n}\n" + }, + "@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.8 <0.9.0;\n\nimport {IGovernable} from '../interfaces/IGovernable.sol';\n\n/// @title Governable contract\n/// @notice Manages the governor role\nabstract contract Governable is IGovernable {\n /// @inheritdoc IGovernable\n address public governor;\n\n /// @inheritdoc IGovernable\n address public pendingGovernor;\n\n constructor(address _governor) {\n if (_governor == address(0)) revert ZeroAddress();\n governor = _governor;\n }\n\n /// @inheritdoc IGovernable\n function setPendingGovernor(address _pendingGovernor) external onlyGovernor {\n _setPendingGovernor(_pendingGovernor);\n }\n\n /// @inheritdoc IGovernable\n function acceptPendingGovernor() external onlyPendingGovernor {\n _acceptPendingGovernor();\n }\n\n function _setPendingGovernor(address _pendingGovernor) internal {\n if (_pendingGovernor == address(0)) revert ZeroAddress();\n pendingGovernor = _pendingGovernor;\n emit PendingGovernorSet(governor, _pendingGovernor);\n }\n\n function _acceptPendingGovernor() internal {\n governor = pendingGovernor;\n delete pendingGovernor;\n emit PendingGovernorAccepted(governor);\n }\n\n /// @notice Functions with this modifier can only be called by governor\n modifier onlyGovernor() {\n if (msg.sender != governor) revert OnlyGovernor();\n _;\n }\n\n /// @notice Functions with this modifier can only be called by pendingGovernor\n modifier onlyPendingGovernor() {\n if (msg.sender != pendingGovernor) revert OnlyPendingGovernor();\n _;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobMigration.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\nimport './Keep3rJobFundableCredits.sol';\nimport './Keep3rJobFundableLiquidity.sol';\n\nabstract contract Keep3rJobMigration is IKeep3rJobMigration, Keep3rJobFundableCredits, Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 internal constant _MIGRATION_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobMigration\n mapping(address => address) public override pendingJobMigrations;\n mapping(address => mapping(address => uint256)) internal _migrationCreatedAt;\n\n /// @inheritdoc IKeep3rJobMigration\n function migrateJob(address _fromJob, address _toJob) external override onlyJobOwner(_fromJob) {\n if (_fromJob == _toJob) revert JobMigrationImpossible();\n\n pendingJobMigrations[_fromJob] = _toJob;\n _migrationCreatedAt[_fromJob][_toJob] = block.timestamp;\n\n emit JobMigrationRequested(_fromJob, _toJob);\n }\n\n /// @inheritdoc IKeep3rJobMigration\n function acceptJobMigration(address _fromJob, address _toJob) external override onlyJobOwner(_toJob) {\n if (disputes[_fromJob] || disputes[_toJob]) revert JobDisputed();\n if (pendingJobMigrations[_fromJob] != _toJob) revert JobMigrationUnavailable();\n if (block.timestamp < _migrationCreatedAt[_fromJob][_toJob] + _MIGRATION_COOLDOWN) revert JobMigrationLocked();\n\n // force job credits update for both jobs\n _settleJobAccountance(_fromJob);\n _settleJobAccountance(_toJob);\n\n // migrate tokens\n while (_jobTokens[_fromJob].length() > 0) {\n address _tokenToMigrate = _jobTokens[_fromJob].at(0);\n jobTokenCredits[_toJob][_tokenToMigrate] += jobTokenCredits[_fromJob][_tokenToMigrate];\n delete jobTokenCredits[_fromJob][_tokenToMigrate];\n _jobTokens[_fromJob].remove(_tokenToMigrate);\n _jobTokens[_toJob].add(_tokenToMigrate);\n }\n\n // migrate liquidities\n while (_jobLiquidities[_fromJob].length() > 0) {\n address _liquidity = _jobLiquidities[_fromJob].at(0);\n\n liquidityAmount[_toJob][_liquidity] += liquidityAmount[_fromJob][_liquidity];\n delete liquidityAmount[_fromJob][_liquidity];\n\n _jobLiquidities[_toJob].add(_liquidity);\n _jobLiquidities[_fromJob].remove(_liquidity);\n }\n\n // migrate job balances\n _jobPeriodCredits[_toJob] += _jobPeriodCredits[_fromJob];\n delete _jobPeriodCredits[_fromJob];\n\n _jobLiquidityCredits[_toJob] += _jobLiquidityCredits[_fromJob];\n delete _jobLiquidityCredits[_fromJob];\n\n // stop _fromJob from being a job\n delete rewardedAt[_fromJob];\n _jobs.remove(_fromJob);\n\n // delete unused data slots\n delete jobOwner[_fromJob];\n delete jobPendingOwner[_fromJob];\n delete _migrationCreatedAt[_fromJob][_toJob];\n delete pendingJobMigrations[_fromJob];\n\n emit JobMigrationSuccessful(_fromJob, _toJob);\n }\n}\n" + }, + "solidity/interfaces/IKeep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IKeep3rHelperParameters.sol';\n\n/// @title Keep3rHelper contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelper is IKeep3rHelperParameters {\n // Errors\n\n /// @notice Throws when none of the tokens in the liquidity pair is KP3R\n error LiquidityPairInvalid();\n\n // Methods\n // solhint-enable func-name-mixedcase\n\n /// @notice Calculates the amount of KP3R that corresponds to the ETH passed into the function\n /// @dev This function allows us to calculate how much KP3R we should pay to a keeper for things expressed in ETH, like gas\n /// @param _eth The amount of ETH\n /// @return _amountOut The amount of KP3R\n function quote(uint256 _eth) external view returns (uint256 _amountOut);\n\n /// @notice Returns the amount of KP3R the keeper has bonded\n /// @param _keeper The address of the keeper to check\n /// @return _amountBonded The amount of KP3R the keeper has bonded\n function bonds(address _keeper) external view returns (uint256 _amountBonded);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to a keeper for using gas\n /// @param _keeper The address of the keeper to check\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _kp3r The amount of KP3R that should be awarded to the keeper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) external view returns (uint256 _kp3r);\n\n /// @notice Calculates the boost in the reward given to a keeper based on the amount of KP3R that keeper has bonded\n /// @dev If the keeper has no bonds, boost should be +10% of gas cost, if keeper has max bonds, +20%\n /// @param _bonds The amount of KP3R tokens bonded by the keeper\n /// @return _rewardBoost The reward boost that corresponds to the keeper\n function getRewardBoostFor(uint256 _bonds) external view returns (uint256 _rewardBoost);\n\n /// @notice Calculates the reward (in KP3R) that corresponds to tx.origin for using gas\n /// @param _gasUsed The amount of gas used that will be rewarded\n /// @return _amount The amount of KP3R that should be awarded to tx.origin\n function getRewardAmount(uint256 _gasUsed) external view returns (uint256 _amount);\n\n /// @notice Given a pool address, returns the underlying tokens of the pair\n /// @param _pool Address of the correspondant pool\n /// @return _token0 Address of the first token of the pair\n /// @return _token1 Address of the second token of the pair\n function getPoolTokens(address _pool) external view returns (address _token0, address _token1);\n\n /// @notice Defines the order of the tokens in the pair for twap calculations\n /// @param _pool Address of the correspondant pool\n /// @return _isKP3RToken0 Boolean indicating the order of the tokens in the pair\n function isKP3RToken0(address _pool) external view returns (bool _isKP3RToken0);\n\n /// @notice Given an array of secondsAgo, returns UniswapV3 pool cumulatives at that moment\n /// @param _pool Address of the pool to observe\n /// @param _secondsAgo Array with time references to observe\n /// @return _tickCumulative1 Cumulative sum of ticks until first time reference\n /// @return _tickCumulative2 Cumulative sum of ticks until second time reference\n /// @return _success Boolean indicating if the observe call was succesfull\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n );\n\n /// @notice Get multiplier, quote, and extra, in order to calculate keeper payment\n /// @param _bonds Amount of bonded KP3R owned by the keeper\n /// @return _boost Multiplier per gas unit. Takes into account the base fee and the amount of bonded KP3R\n /// @return _oneEthQuote Amount of KP3R tokens equivalent to 1 ETH\n /// @return _extra Amount of extra gas that should be added to the gas spent\n function getPaymentParams(uint256 _bonds)\n external\n view\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n );\n\n /// @notice Given a tick and a liquidity amount, calculates the underlying KP3R tokens\n /// @param _liquidityAmount Amount of liquidity to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _kp3rAmount Amount of KP3R tokens underlying on the given liquidity\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _kp3rAmount);\n\n /// @notice Given a tick and a token amount, calculates the output in correspondant token\n /// @param _baseAmount Amount of token to be converted\n /// @param _tickDifference Tick value used to calculate the quote\n /// @param _timeInterval Time value used to calculate the quote\n /// @return _quoteAmount Amount of credits deserved for the baseAmount at the tick value\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure returns (uint256 _quoteAmount);\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableCredits.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableCredits is IKeep3rJobFundableCredits, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice Cooldown between withdrawals\n uint256 internal constant _WITHDRAW_TOKENS_COOLDOWN = 1 minutes;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n mapping(address => mapping(address => uint256)) public override jobTokenCreditsAddedAt;\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function addTokenCreditsToJob(\n address _job,\n address _token,\n uint256 _amount\n ) external override nonReentrant {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n // KP3R shouldn't be used for direct token payments\n if (_token == keep3rV1) revert TokenUnallowed();\n uint256 _before = IERC20(_token).balanceOf(address(this));\n IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);\n uint256 _received = IERC20(_token).balanceOf(address(this)) - _before;\n uint256 _tokenFee = (_received * fee) / _BASE;\n jobTokenCredits[_job][_token] += _received - _tokenFee;\n jobTokenCreditsAddedAt[_job][_token] = block.timestamp;\n IERC20(_token).safeTransfer(governor, _tokenFee);\n _jobTokens[_job].add(_token);\n\n emit TokenCreditAddition(_job, _token, msg.sender, _received);\n }\n\n /// @inheritdoc IKeep3rJobFundableCredits\n function withdrawTokenCreditsFromJob(\n address _job,\n address _token,\n uint256 _amount,\n address _receiver\n ) external override nonReentrant onlyJobOwner(_job) {\n if (block.timestamp <= jobTokenCreditsAddedAt[_job][_token] + _WITHDRAW_TOKENS_COOLDOWN) revert JobTokenCreditsLocked();\n if (jobTokenCredits[_job][_token] < _amount) revert InsufficientJobTokenCredits();\n if (disputes[_job]) revert JobDisputed();\n\n jobTokenCredits[_job][_token] -= _amount;\n IERC20(_token).safeTransfer(_receiver, _amount);\n\n if (jobTokenCredits[_job][_token] == 0) {\n _jobTokens[_job].remove(_token);\n }\n\n emit TokenCreditWithdrawal(_job, _token, _receiver, _amount);\n }\n}\n" + }, + "solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rJobOwnership.sol';\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/IPairManager.sol';\nimport '../../../interfaces/peripherals/IKeep3rJobs.sol';\n\nimport '../../libraries/FullMath.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport '@openzeppelin/contracts/utils/math/Math.sol';\n\nabstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @notice List of liquidities that are accepted in the system\n EnumerableSet.AddressSet internal _approvedLiquidities;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => mapping(address => uint256)) public override liquidityAmount;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override rewardedAt;\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n mapping(address => uint256) public override workedAt;\n\n /// @notice Tracks an address and returns its TickCache\n mapping(address => TickCache) internal _tick;\n\n // Views\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approvedLiquidities() external view override returns (address[] memory _list) {\n _list = _approvedLiquidities.values();\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobPeriodCredits(address _job) public view override returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n _periodCredits += _getReward(\n IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime)\n );\n }\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n\n // If the job was rewarded in the past 1 period time\n if ((block.timestamp - rewardedAt[_job]) < rewardPeriodTime) {\n // If the job has period credits, update minted job credits to new twap\n _liquidityCredits = _periodCredits > 0\n ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] // If the job has period credits, return remaining job credits updated to new twap\n : _jobLiquidityCredits[_job]; // If not, return remaining credits, forced credits should not be updated\n } else {\n // Else return a full period worth of credits if current credits have expired\n _liquidityCredits = _periodCredits;\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function totalJobCredits(address _job) external view override returns (uint256 _credits) {\n uint256 _periodCredits = jobPeriodCredits(_job);\n uint256 _cooldown = block.timestamp;\n\n if ((rewardedAt[_job] > _period(block.timestamp - rewardPeriodTime))) {\n // Will calculate cooldown if it outdated\n if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will calculate cooldown from last reward reference in this period\n _cooldown -= (rewardedAt[_job] + rewardPeriodTime);\n } else {\n // Will calculate cooldown from last reward timestamp\n _cooldown -= rewardedAt[_job];\n }\n } else {\n // Will calculate cooldown from period start if expired\n _cooldown -= _period(block.timestamp);\n }\n _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function quoteLiquidity(address _liquidity, uint256 _amount) external view override returns (uint256 _periodCredits) {\n if (_approvedLiquidities.contains(_liquidity)) {\n TickCache memory _tickCache = observeLiquidity(_liquidity);\n if (_tickCache.period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;\n return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));\n }\n }\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);\n\n if (_tick[_liquidity].period == lastPeriod) {\n // Will only ask for current period accumulator if liquidity is outdated\n uint32[] memory _secondsAgo = new uint32[](1);\n int56 previousTick = _tick[_liquidity].current;\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n\n (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - previousTick;\n } else if (_tick[_liquidity].period < lastPeriod) {\n // Will ask for 2 accumulators if liquidity is expired\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n }\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Methods\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernor {\n if (!_jobs.contains(_job)) revert JobUnavailable();\n _settleJobAccountance(_job);\n _jobLiquidityCredits[_job] += _amount;\n emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function approveLiquidity(address _liquidity) external virtual override onlyGovernor {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IPairManager(_liquidity).pool();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function revokeLiquidity(address _liquidity) external override onlyGovernor {\n if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();\n delete _liquidityPool[_liquidity];\n delete _isKP3RToken0[_liquidity];\n delete _tick[_liquidity];\n\n emit LiquidityRevocation(_liquidity);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function addLiquidityToJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override nonReentrant {\n if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();\n if (!_jobs.contains(_job)) revert JobUnavailable();\n\n _jobLiquidities[_job].add(_liquidity);\n\n _settleJobAccountance(_job);\n\n if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n\n IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount);\n liquidityAmount[_job][_liquidity] += _amount;\n _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity));\n emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) external override onlyJobOwner(_job) {\n canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime;\n pendingUnbonds[_job][_liquidity] += _amount;\n _unbondLiquidityFromJob(_job, _liquidity, _amount);\n\n uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];\n if (_remainingLiquidity > 0 && _quoteLiquidity(_remainingLiquidity, _liquidity) < liquidityMinimum) revert JobLiquidityLessThanMin();\n\n emit Unbonding(_job, _liquidity, _amount);\n }\n\n /// @inheritdoc IKeep3rJobFundableLiquidity\n function withdrawLiquidityFromJob(\n address _job,\n address _liquidity,\n address _receiver\n ) external override onlyJobOwner(_job) {\n if (_receiver == address(0)) revert ZeroAddress();\n if (pendingUnbonds[_job][_liquidity] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[_job][_liquidity] >= block.timestamp) revert UnbondsLocked();\n if (disputes[_job]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[_job][_liquidity];\n\n delete pendingUnbonds[_job][_liquidity];\n delete canWithdrawAfter[_job][_liquidity];\n\n IERC20(_liquidity).safeTransfer(_receiver, _amount);\n emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);\n }\n\n // Internal functions\n\n /// @notice Updates or rewards job liquidity credits depending on time since last job reward\n function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {\n if (rewardedAt[_job] < _period(block.timestamp)) {\n // Will exit function if job has been rewarded in current period\n if (rewardedAt[_job] <= _period(block.timestamp - rewardPeriodTime)) {\n // Will reset job to period syncronicity if a full period passed without rewards\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] = _period(block.timestamp);\n _rewarded = true;\n } else if ((block.timestamp - rewardedAt[_job]) >= rewardPeriodTime) {\n // Will reset job's syncronicity if last reward was more than epoch ago\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = _jobPeriodCredits[_job];\n rewardedAt[_job] += rewardPeriodTime;\n _rewarded = true;\n } else if (workedAt[_job] < _period(block.timestamp)) {\n // First keeper on period has to update job accountance to current twaps\n uint256 previousPeriodCredits = _jobPeriodCredits[_job];\n _updateJobPeriod(_job);\n _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits;\n // Updating job accountance does not reward job\n }\n }\n }\n\n /// @notice Only called if _jobLiquidityCredits < payment\n function _rewardJobCredits(address _job) internal {\n /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work)\n /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */\n _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job]);\n rewardedAt[_job] = block.timestamp;\n }\n\n /// @notice Updates accountance for _jobPeriodCredits\n function _updateJobPeriod(address _job) internal {\n _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job);\n }\n\n /// @notice Quotes the outdated job liquidities and calculates _periodCredits\n /// @dev This function is also responsible for keeping the KP3R/WETH quote updated\n function _calculateJobPeriodCredits(address _job) internal returns (uint256 _periodCredits) {\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n address _liquidity = _jobLiquidities[_job].at(i);\n if (_approvedLiquidities.contains(_liquidity)) {\n if (_tick[_liquidity].period != _period(block.timestamp)) {\n // Updates liquidity cache only if needed\n _tick[_liquidity] = observeLiquidity(_liquidity);\n }\n _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity));\n }\n }\n }\n\n /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount\n function _unbondLiquidityFromJob(\n address _job,\n address _liquidity,\n uint256 _amount\n ) internal nonReentrant {\n if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();\n if (liquidityAmount[_job][_liquidity] < _amount) revert JobLiquidityInsufficient();\n\n // Ensures current twaps in job liquidities\n _updateJobPeriod(_job);\n uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));\n\n // A liquidity can be revoked causing a job to have 0 periodCredits\n if (_jobPeriodCredits[_job] > 0) {\n // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities\n _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job];\n _jobPeriodCredits[_job] -= _periodCreditsToRemove;\n }\n\n liquidityAmount[_job][_liquidity] -= _amount;\n if (liquidityAmount[_job][_liquidity] == 0) {\n _jobLiquidities[_job].remove(_liquidity);\n }\n }\n\n /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed\n function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {\n if (_timePassed < rewardPeriodTime) {\n _result = (_timePassed * _multiplier) / rewardPeriodTime;\n } else _result = _multiplier;\n }\n\n /// @notice Returns the start of the period of the provided timestamp\n function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {\n return _timestamp - (_timestamp % rewardPeriodTime);\n }\n\n /// @notice Calculates relation between rewardPeriod and inflationPeriod\n function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {\n return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);\n }\n\n /// @notice Returns underlying KP3R amount for a given liquidity amount\n function _quoteLiquidity(uint256 _amount, address _liquidity) internal view returns (uint256 _quote) {\n if (_tick[_liquidity].period != 0) {\n int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;\n _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime);\n }\n }\n\n /// @notice Updates job credits to current quotes and rewards job's pending minted credits\n /// @dev Ensures a maximum of 1 period of credits\n function _settleJobAccountance(address _job) internal virtual {\n _updateJobCreditsIfNeeded(_job);\n _rewardJobCredits(_job);\n _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n}\n" + }, + "solidity/contracts/peripherals/Keep3rParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/IKeep3rHelper.sol';\nimport '../../interfaces/peripherals/IKeep3rParameters.sol';\nimport '../../interfaces/external/IKeep3rV1Proxy.sol';\nimport './Keep3rAccountance.sol';\n\nabstract contract Keep3rParameters is IKeep3rParameters, Keep3rAccountance {\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rV1Proxy;\n\n /// @inheritdoc IKeep3rParameters\n address public override keep3rHelper;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override bondTime = 3 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override unbondTime = 14 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override liquidityMinimum = 3 ether;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override rewardPeriodTime = 5 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override inflationPeriod = 34 days;\n\n /// @inheritdoc IKeep3rParameters\n uint256 public override fee = 30;\n\n /// @notice The base that will be used to calculate the fee\n uint256 internal constant _BASE = 10_000;\n\n /// @notice The minimum reward period\n uint256 internal constant _MIN_REWARD_PERIOD_TIME = 1 days;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) {\n keep3rHelper = _keep3rHelper;\n keep3rV1 = _keep3rV1;\n keep3rV1Proxy = _keep3rV1Proxy;\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rHelper(address _keep3rHelper) external override onlyGovernor {\n if (_keep3rHelper == address(0)) revert ZeroAddress();\n keep3rHelper = _keep3rHelper;\n emit Keep3rHelperChange(_keep3rHelper);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1(address _keep3rV1) public virtual override onlyGovernor {\n if (_keep3rV1 == address(0)) revert ZeroAddress();\n _mint(totalBonds);\n\n keep3rV1 = _keep3rV1;\n emit Keep3rV1Change(_keep3rV1);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setKeep3rV1Proxy(address _keep3rV1Proxy) external override onlyGovernor {\n if (_keep3rV1Proxy == address(0)) revert ZeroAddress();\n keep3rV1Proxy = _keep3rV1Proxy;\n emit Keep3rV1ProxyChange(_keep3rV1Proxy);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setBondTime(uint256 _bondTime) external override onlyGovernor {\n bondTime = _bondTime;\n emit BondTimeChange(_bondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setUnbondTime(uint256 _unbondTime) external override onlyGovernor {\n unbondTime = _unbondTime;\n emit UnbondTimeChange(_unbondTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setLiquidityMinimum(uint256 _liquidityMinimum) external override onlyGovernor {\n liquidityMinimum = _liquidityMinimum;\n emit LiquidityMinimumChange(_liquidityMinimum);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setRewardPeriodTime(uint256 _rewardPeriodTime) external override onlyGovernor {\n if (_rewardPeriodTime < _MIN_REWARD_PERIOD_TIME) revert MinRewardPeriod();\n rewardPeriodTime = _rewardPeriodTime;\n emit RewardPeriodTimeChange(_rewardPeriodTime);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setInflationPeriod(uint256 _inflationPeriod) external override onlyGovernor {\n inflationPeriod = _inflationPeriod;\n emit InflationPeriodChange(_inflationPeriod);\n }\n\n /// @inheritdoc IKeep3rParameters\n function setFee(uint256 _fee) external override onlyGovernor {\n fee = _fee;\n emit FeeChange(_fee);\n }\n\n function _mint(uint256 _amount) internal {\n totalBonds -= _amount;\n IKeep3rV1Proxy(keep3rV1Proxy).mint(_amount);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\n\ninterface IKeep3rV1Proxy is IBaseErrors {\n // Structs\n struct Recipient {\n address recipient;\n uint256 caps;\n }\n\n // Variables\n function keep3rV1() external view returns (address);\n\n function governance() external view returns (address);\n\n function pendingGovernance() external view returns (address);\n\n function minter() external view returns (address);\n\n function next(address) external view returns (uint256);\n\n function caps(address) external view returns (uint256);\n\n function recipients() external view returns (address[] memory);\n\n function recipientsCaps() external view returns (Recipient[] memory);\n\n // Errors\n error Cooldown();\n error NoDrawableAmount();\n error OnlyMinter();\n error OnlyGovernance();\n error OnlyPendingGovernance();\n\n // Methods\n function addRecipient(address recipient, uint256 amount) external;\n\n function removeRecipient(address recipient) external;\n\n function draw() external returns (uint256 _amount);\n\n function setKeep3rV1(address _keep3rV1) external;\n\n function setMinter(address _minter) external;\n\n function mint(uint256 _amount) external;\n\n function mint(address _account, uint256 _amount) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function setKeep3rV1Governance(address _governance) external;\n\n function acceptKeep3rV1Governance() external;\n\n function dispute(address _keeper) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function addJob(address _job) external;\n\n function removeJob(address _job) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n}\n" + }, + "solidity/interfaces/IKeep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Keep3rHelperParameters contract\n/// @notice Contains all the helper functions used throughout the different files.\ninterface IKeep3rHelperParameters {\n // Structs\n\n /// @dev KP3R-WETH Pool address and isKP3RToken0\n /// @dev Created in order to save gas by avoiding calls to pool's token0 method\n struct Kp3rWethOraclePool {\n address poolAddress;\n bool isKP3RToken0;\n }\n\n // Errors\n\n /// @notice Throws when pool does not have KP3R as token0 nor token1\n error InvalidOraclePool();\n\n // Events\n\n /// @notice Emitted when the kp3r weth pool is changed\n /// @param _address Address of the new kp3r weth pool\n /// @param _isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n event Kp3rWethPoolChange(address _address, bool _isKP3RToken0);\n\n /// @notice Emitted when the minimum boost multiplier is changed\n /// @param _minBoost The minimum boost multiplier\n event MinBoostChange(uint256 _minBoost);\n\n /// @notice Emitted when the maximum boost multiplier is changed\n /// @param _maxBoost The maximum boost multiplier\n event MaxBoostChange(uint256 _maxBoost);\n\n /// @notice Emitted when the target bond amount is changed\n /// @param _targetBond The target bond amount\n event TargetBondChange(uint256 _targetBond);\n\n /// @notice Emitted when the Keep3r V2 address is changed\n /// @param _keep3rV2 The address of Keep3r V2\n event Keep3rV2Change(address _keep3rV2);\n\n /// @notice Emitted when the work extra gas amount is changed\n /// @param _workExtraGas The work extra gas\n event WorkExtraGasChange(uint256 _workExtraGas);\n\n /// @notice Emitted when the quote twap time is changed\n /// @param _quoteTwapTime The twap time for quoting\n event QuoteTwapTimeChange(uint32 _quoteTwapTime);\n\n /// @notice Emitted when minimum rewarded gas fee is changed\n /// @param _minBaseFee The minimum rewarded gas fee\n event MinBaseFeeChange(uint256 _minBaseFee);\n\n /// @notice Emitted when minimum rewarded priority fee is changed\n /// @param _minPriorityFee The minimum expected fee that the keeper should pay\n event MinPriorityFeeChange(uint256 _minPriorityFee);\n\n // Variables\n\n /// @notice Address of KP3R token\n /// @return _kp3r Address of KP3R token\n // solhint-disable func-name-mixedcase\n function KP3R() external view returns (address _kp3r);\n\n /// @notice The boost base used to calculate the boost rewards for the keeper\n /// @return _base The boost base number\n function BOOST_BASE() external view returns (uint256 _base);\n\n /// @notice KP3R-WETH pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isKP3RToken0 True if calling the token0 method of the pool returns the KP3R token address\n function kp3rWethPool() external view returns (address poolAddress, bool isKP3RToken0);\n\n /// @notice The minimum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the minimum amount to be paid will be 1000 * minBoost / BOOST_BASE\n /// @return _multiplier The minimum boost multiplier\n function minBoost() external view returns (uint256 _multiplier);\n\n /// @notice The maximum multiplier used to calculate the amount of gas paid to the Keeper for the gas used to perform a job\n /// For example: if the quoted gas used is 1000, then the maximum amount to be paid will be 1000 * maxBoost / BOOST_BASE\n /// @return _multiplier The maximum boost multiplier\n function maxBoost() external view returns (uint256 _multiplier);\n\n /// @notice The targeted amount of bonded KP3Rs to max-up reward multiplier\n /// For example: if the amount of KP3R the keeper has bonded is targetBond or more, then the keeper will get\n /// the maximum boost possible in his rewards, if it's less, the reward boost will be proportional\n /// @return _target The amount of KP3R that comforms the targetBond\n function targetBond() external view returns (uint256 _target);\n\n /// @notice The amount of unaccounted gas that is going to be added to keeper payments\n /// @return _workExtraGas The work unaccounted gas amount\n function workExtraGas() external view returns (uint256 _workExtraGas);\n\n /// @notice The twap time for quoting\n /// @return _quoteTwapTime The twap time\n function quoteTwapTime() external view returns (uint32 _quoteTwapTime);\n\n /// @notice The minimum base fee that is used to calculate keeper rewards\n /// @return _minBaseFee The minimum rewarded gas fee\n function minBaseFee() external view returns (uint256 _minBaseFee);\n\n /// @notice The minimum priority fee that is also rewarded for keepers\n /// @return _minPriorityFee The minimum rewarded priority fee\n function minPriorityFee() external view returns (uint256 _minPriorityFee);\n\n /// @notice Address of Keep3r V2\n /// @return _keep3rV2 Address of Keep3r V2\n function keep3rV2() external view returns (address _keep3rV2);\n\n // Methods\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function setKp3rWethPool(address _poolAddress) external;\n\n /// @notice Sets the minimum boost multiplier\n /// @param _minBoost The minimum boost multiplier\n function setMinBoost(uint256 _minBoost) external;\n\n /// @notice Sets the maximum boost multiplier\n /// @param _maxBoost The maximum boost multiplier\n function setMaxBoost(uint256 _maxBoost) external;\n\n /// @notice Sets the target bond amount\n /// @param _targetBond The target bond amount\n function setTargetBond(uint256 _targetBond) external;\n\n /// @notice Sets the Keep3r V2 address\n /// @param _keep3rV2 The address of Keep3r V2\n function setKeep3rV2(address _keep3rV2) external;\n\n /// @notice Sets the work extra gas amount\n /// @param _workExtraGas The work extra gas\n function setWorkExtraGas(uint256 _workExtraGas) external;\n\n /// @notice Sets the quote twap time\n /// @param _quoteTwapTime The twap time for quoting\n function setQuoteTwapTime(uint32 _quoteTwapTime) external;\n\n /// @notice Sets the minimum rewarded gas fee\n /// @param _minBaseFee The minimum rewarded gas fee\n function setMinBaseFee(uint256 _minBaseFee) external;\n\n /// @notice Sets the minimum rewarded gas priority fee\n /// @param _minPriorityFee The minimum rewarded priority fee\n function setMinPriorityFee(uint256 _minPriorityFee) external;\n}\n" + }, + "solidity/interfaces/IPairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n/// @title Pair Manager interface\n/// @notice Generic interface for Keep3r liquidity pools (kLP)\ninterface IPairManager is IERC20Metadata {\n /// @notice Address of the factory from which the pair manager was created\n /// @return _factory The address of the PairManager Factory\n function factory() external view returns (address _factory);\n\n /// @notice Address of the pool from which the Keep3r pair manager will interact with\n /// @return _pool The address of the pool\n function pool() external view returns (address _pool);\n\n /// @notice Token0 of the pool\n /// @return _token0 The address of token0\n function token0() external view returns (address _token0);\n\n /// @notice Token1 of the pool\n /// @return _token1 The address of token1\n function token1() external view returns (address _token1);\n}\n" + }, + "solidity/contracts/libraries/FullMath.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n uint256 twos = (~denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct bits in each step.\n inv *= 2 - denominator * inv; // inverse mod 2**8\n inv *= 2 - denominator * inv; // inverse mod 2**16\n inv *= 2 - denominator * inv; // inverse mod 2**32\n inv *= 2 - denominator * inv; // inverse mod 2**64\n inv *= 2 - denominator * inv; // inverse mod 2**128\n inv *= 2 - denominator * inv; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying\n // with the modular inverse of denominator. This will give us the\n // correct result modulo 2**256. Since the precoditions guarantee\n // that the outcome is less than 2**256, this is the final result.\n // We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inv;\n return result;\n }\n }\n\n /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n function mulDivRoundingUp(\n uint256 a,\n uint256 b,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n result = mulDiv(a, b, denominator);\n if (mulmod(a, b, denominator) > 0) {\n require(result < type(uint256).max);\n result++;\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "solidity/contracts/peripherals/Keep3rDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rParameters.sol';\nimport '../../interfaces/peripherals/IKeep3rDisputable.sol';\n\nabstract contract Keep3rDisputable is IKeep3rDisputable, Keep3rParameters {\n /// @inheritdoc IKeep3rDisputable\n function dispute(address _jobOrKeeper) external override onlyDisputer {\n if (disputes[_jobOrKeeper]) revert AlreadyDisputed();\n disputes[_jobOrKeeper] = true;\n emit Dispute(_jobOrKeeper, msg.sender);\n }\n\n /// @inheritdoc IKeep3rDisputable\n function resolve(address _jobOrKeeper) external override onlyDisputer {\n if (!disputes[_jobOrKeeper]) revert NotDisputed();\n disputes[_jobOrKeeper] = false;\n emit Resolve(_jobOrKeeper, msg.sender);\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperDisputable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './Keep3rKeeperFundable.sol';\nimport '../Keep3rDisputable.sol';\nimport '../../../interfaces/external/IKeep3rV1.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nabstract contract Keep3rKeeperDisputable is IKeep3rKeeperDisputable, Keep3rDisputable, Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _slash(_keeper, _bonded, _bondAmount, _unbondAmount);\n emit KeeperSlash(_keeper, msg.sender, _bondAmount + _unbondAmount);\n }\n\n /// @inheritdoc IKeep3rKeeperDisputable\n function revoke(address _keeper) external override onlySlasher {\n if (!disputes[_keeper]) revert NotDisputed();\n _keepers.remove(_keeper);\n _slash(_keeper, keep3rV1, bonds[_keeper][keep3rV1], pendingUnbonds[_keeper][keep3rV1]);\n emit KeeperRevoke(_keeper, msg.sender);\n }\n\n function _slash(\n address _keeper,\n address _bonded,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) internal {\n if (_bonded != keep3rV1) {\n try IERC20(_bonded).transfer(governor, _bondAmount + _unbondAmount) returns (bool) {} catch (bytes memory) {}\n }\n bonds[_keeper][_bonded] -= _bondAmount;\n pendingUnbonds[_keeper][_bonded] -= _unbondAmount;\n }\n}\n" + }, + "solidity/contracts/peripherals/keepers/Keep3rKeeperFundable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rAccountance.sol';\nimport '../Keep3rParameters.sol';\nimport '../../../interfaces/peripherals/IKeep3rKeepers.sol';\n\nimport '../../../interfaces/external/IKeep3rV1.sol';\n\nimport '@openzeppelin/contracts/security/ReentrancyGuard.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\nabstract contract Keep3rKeeperFundable is IKeep3rKeeperFundable, ReentrancyGuard, Keep3rParameters {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rKeeperFundable\n function bond(address _bonding, uint256 _amount) external override nonReentrant {\n if (disputes[msg.sender]) revert Disputed();\n if (_jobs.contains(msg.sender)) revert AlreadyAJob();\n canActivateAfter[msg.sender][_bonding] = block.timestamp + bondTime;\n\n uint256 _before = IERC20(_bonding).balanceOf(address(this));\n IERC20(_bonding).safeTransferFrom(msg.sender, address(this), _amount);\n _amount = IERC20(_bonding).balanceOf(address(this)) - _before;\n\n hasBonded[msg.sender] = true;\n pendingBonds[msg.sender][_bonding] += _amount;\n\n emit Bonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function activate(address _bonding) external override {\n address _keeper = msg.sender;\n if (disputes[_keeper]) revert Disputed();\n uint256 _canActivateAfter = canActivateAfter[_keeper][_bonding];\n if (_canActivateAfter == 0) revert BondsUnexistent();\n if (_canActivateAfter >= block.timestamp) revert BondsLocked();\n\n if (firstSeen[_keeper] == 0) {\n firstSeen[_keeper] = block.timestamp;\n }\n _keepers.add(_keeper);\n\n uint256 _amount = pendingBonds[_keeper][_bonding];\n delete pendingBonds[_keeper][_bonding];\n\n // bond provided tokens\n bonds[_keeper][_bonding] += _amount;\n if (_bonding == keep3rV1) {\n totalBonds += _amount;\n _depositBonds(_amount);\n }\n\n emit Activation(_keeper, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function unbond(address _bonding, uint256 _amount) external override {\n canWithdrawAfter[msg.sender][_bonding] = block.timestamp + unbondTime;\n bonds[msg.sender][_bonding] -= _amount;\n pendingUnbonds[msg.sender][_bonding] += _amount;\n\n emit Unbonding(msg.sender, _bonding, _amount);\n }\n\n /// @inheritdoc IKeep3rKeeperFundable\n function withdraw(address _bonding) external override nonReentrant {\n if (pendingUnbonds[msg.sender][_bonding] == 0) revert UnbondsUnexistent();\n if (canWithdrawAfter[msg.sender][_bonding] >= block.timestamp) revert UnbondsLocked();\n if (disputes[msg.sender]) revert Disputed();\n\n uint256 _amount = pendingUnbonds[msg.sender][_bonding];\n\n delete pendingUnbonds[msg.sender][_bonding];\n delete canWithdrawAfter[msg.sender][_bonding];\n\n if (_bonding == keep3rV1) _mint(_amount);\n IERC20(_bonding).safeTransfer(msg.sender, _amount);\n\n emit Withdrawal(msg.sender, _bonding, _amount);\n }\n\n function _depositBonds(uint256 _amount) internal virtual {\n IKeep3rV1(keep3rV1).burn(_amount);\n }\n}\n" + }, + "solidity/interfaces/external/IKeep3rV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\n// solhint-disable func-name-mixedcase\ninterface IKeep3rV1 is IERC20, IERC20Metadata {\n // Structs\n struct Checkpoint {\n uint32 fromBlock;\n uint256 votes;\n }\n\n // Events\n event DelegateChanged(address indexed _delegator, address indexed _fromDelegate, address indexed _toDelegate);\n event DelegateVotesChanged(address indexed _delegate, uint256 _previousBalance, uint256 _newBalance);\n event SubmitJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event ApplyCredit(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event RemoveJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event UnbondJob(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _block, uint256 _credit);\n event JobAdded(address indexed _job, uint256 _block, address _governance);\n event JobRemoved(address indexed _job, uint256 _block, address _governance);\n event KeeperWorked(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _block, uint256 _amount);\n event KeeperBonding(address indexed _keeper, uint256 _block, uint256 _active, uint256 _bond);\n event KeeperBonded(address indexed _keeper, uint256 _block, uint256 _activated, uint256 _bond);\n event KeeperUnbonding(address indexed _keeper, uint256 _block, uint256 _deactive, uint256 _bond);\n event KeeperUnbound(address indexed _keeper, uint256 _block, uint256 _deactivated, uint256 _bond);\n event KeeperSlashed(address indexed _keeper, address indexed _slasher, uint256 _block, uint256 _slash);\n event KeeperDispute(address indexed _keeper, uint256 _block);\n event KeeperResolved(address indexed _keeper, uint256 _block);\n event TokenCreditAddition(address indexed _credit, address indexed _job, address indexed _creditor, uint256 _block, uint256 _amount);\n\n // Variables\n function KPRH() external returns (address);\n\n function delegates(address _delegator) external view returns (address);\n\n function checkpoints(address _account, uint32 _checkpoint) external view returns (Checkpoint memory);\n\n function numCheckpoints(address _account) external view returns (uint32);\n\n function DOMAIN_TYPEHASH() external returns (bytes32);\n\n function DOMAINSEPARATOR() external returns (bytes32);\n\n function DELEGATION_TYPEHASH() external returns (bytes32);\n\n function PERMIT_TYPEHASH() external returns (bytes32);\n\n function nonces(address _user) external view returns (uint256);\n\n function BOND() external returns (uint256);\n\n function UNBOND() external returns (uint256);\n\n function LIQUIDITYBOND() external returns (uint256);\n\n function FEE() external returns (uint256);\n\n function BASE() external returns (uint256);\n\n function ETH() external returns (address);\n\n function bondings(address _user, address _bonding) external view returns (uint256);\n\n function canWithdrawAfter(address _user, address _bonding) external view returns (uint256);\n\n function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function pendingbonds(address _keeper, address _bonding) external view returns (uint256);\n\n function bonds(address _keeper, address _bonding) external view returns (uint256);\n\n function votes(address _delegator) external view returns (uint256);\n\n function firstSeen(address _keeper) external view returns (uint256);\n\n function disputes(address _keeper) external view returns (bool);\n\n function lastJob(address _keeper) external view returns (uint256);\n\n function workCompleted(address _keeper) external view returns (uint256);\n\n function jobs(address _job) external view returns (bool);\n\n function credits(address _job, address _credit) external view returns (uint256);\n\n function liquidityProvided(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmountsUnbonding(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function jobProposalDelay(address _job) external view returns (uint256);\n\n function liquidityApplied(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function liquidityAmount(\n address _provider,\n address _liquidity,\n address _job\n ) external view returns (uint256);\n\n function keepers(address _keeper) external view returns (bool);\n\n function blacklist(address _keeper) external view returns (bool);\n\n function keeperList(uint256 _index) external view returns (address);\n\n function jobList(uint256 _index) external view returns (address);\n\n function governance() external returns (address);\n\n function pendingGovernance() external returns (address);\n\n function liquidityAccepted(address _liquidity) external view returns (bool);\n\n function liquidityPairs(uint256 _index) external view returns (address);\n\n // Methods\n function getCurrentVotes(address _account) external view returns (uint256);\n\n function addCreditETH(address _job) external payable;\n\n function addCredit(\n address _credit,\n address _job,\n uint256 _amount\n ) external;\n\n function addVotes(address _voter, uint256 _amount) external;\n\n function removeVotes(address _voter, uint256 _amount) external;\n\n function addKPRCredit(address _job, uint256 _amount) external;\n\n function approveLiquidity(address _liquidity) external;\n\n function revokeLiquidity(address _liquidity) external;\n\n function pairs() external view returns (address[] memory);\n\n function addLiquidityToJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function applyCreditToJob(\n address _provider,\n address _liquidity,\n address _job\n ) external;\n\n function unbondLiquidityFromJob(\n address _liquidity,\n address _job,\n uint256 _amount\n ) external;\n\n function removeLiquidityFromJob(address _liquidity, address _job) external;\n\n function mint(uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n\n function worked(address _keeper) external;\n\n function receipt(\n address _credit,\n address _keeper,\n uint256 _amount\n ) external;\n\n function receiptETH(address _keeper, uint256 _amount) external;\n\n function addJob(address _job) external;\n\n function getJobs() external view returns (address[] memory);\n\n function removeJob(address _job) external;\n\n function setKeep3rHelper(address _keep3rHelper) external;\n\n function setGovernance(address _governance) external;\n\n function acceptGovernance() external;\n\n function isKeeper(address _keeper) external returns (bool);\n\n function isMinKeeper(\n address _keeper,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function isBondedKeeper(\n address _keeper,\n address _bond,\n uint256 _minBond,\n uint256 _earned,\n uint256 _age\n ) external returns (bool);\n\n function bond(address _bonding, uint256 _amount) external;\n\n function getKeepers() external view returns (address[] memory);\n\n function activate(address _bonding) external;\n\n function unbond(address _bonding, uint256 _amount) external;\n\n function slash(\n address _bonded,\n address _keeper,\n uint256 _amount\n ) external;\n\n function withdraw(address _bonding) external;\n\n function dispute(address _keeper) external;\n\n function revoke(address _keeper) external;\n\n function resolve(address _keeper) external;\n\n function permit(\n address _owner,\n address _spender,\n uint256 _amount,\n uint256 _deadline,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3r.sol';\n\ncontract Keep3rForTestnet is Keep3r {\n constructor(\n address _governor,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governor, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3r.sol';\n\ncontract Keep3rForTest is Keep3r {\n constructor(\n address _governor,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3r(_governor, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3r.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\nimport '../../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\nimport '../../interfaces/sidechain/IKeep3rSidechainAccountance.sol';\n\ncontract Keep3rSidechain is Keep3r, IKeep3rJobWorkableRated, IKeep3rSidechainAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @param _governor Address of governor\n /// @param _keep3rHelperSidechain Address of sidechain Keep3rHelper\n /// @param _wrappedKP3R Address of wrapped KP3R implementation\n /// @param _keep3rEscrow Address of sidechain Keep3rEscrow\n constructor(\n address _governor, // governor\n address _keep3rHelperSidechain, // helper\n address _wrappedKP3R, // keep3rV1\n address _keep3rEscrow // keep3rV1Proxy\n ) Keep3r(_governor, _keep3rHelperSidechain, _wrappedKP3R, _keep3rEscrow) {}\n\n // Keep3rSidechainAccountance\n\n /// @inheritdoc IKeep3rSidechainAccountance\n function virtualReserves() external view override returns (int256 _virtualReserves) {\n // Queries wKP3R balanceOf escrow contract minus the totalBonds\n return int256(IERC20(keep3rV1).balanceOf(keep3rV1Proxy)) - int256(totalBonds);\n }\n\n // Keep3rJobFundableLiquidity\n\n /// @notice Sidechain implementation asks the Helper for an oracle, instead of reading it from the ERC-20\n /// @dev Function should be called after setting an oracle in Keep3rHelperSidechain\n /// @param _liquidity Address of the liquidity token being approved\n function approveLiquidity(address _liquidity) external virtual override onlyGovernor {\n if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();\n _liquidityPool[_liquidity] = IKeep3rHelperSidechain(keep3rHelper).oracle(_liquidity);\n if (_liquidityPool[_liquidity] == address(0)) revert ZeroAddress();\n _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity]);\n _tick[_liquidity] = observeLiquidity(_liquidity);\n emit LiquidityApproval(_liquidity);\n }\n\n /// @notice Sidechain implementation will always ask for 2 tickCumulatives instead of cacheing\n /// @param _liquidity Address of the liquidity token being observed\n function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {\n if (_tick[_liquidity].period == _period(block.timestamp)) {\n // Will return cached twaps if liquidity is updated\n _tickCache = _tick[_liquidity];\n } else {\n bool success;\n\n // Will always ask for 2 accumulators in sidechain\n uint32[] memory _secondsAgo = new uint32[](2);\n\n _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp));\n _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime);\n\n int56 _tickCumulative2;\n (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo);\n\n _tickCache.difference = _tickCache.current - _tickCumulative2;\n\n if (success) {\n _tickCache.period = _period(block.timestamp);\n } else {\n delete _tickCache.period;\n }\n }\n }\n\n // Keep3rJobsWorkable\n\n /// @dev Sidechain implementation deprecates worked(address) as it should come with a usdPerGasUnit parameter\n function worked(address) external pure override {\n revert Deprecated();\n }\n\n /// @notice Implemented by jobs to show that a keeper performed work\n /// @dev Uses a USD per gas unit payment mechanism\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Units of USD (in wei) per gas unit that should be rewarded to the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external override {\n if (_initialGas == 0) revert GasNotInitialized();\n // Gas used for quote calculations & payment is not rewarded\n uint256 _gasLeft = _getGasLeft();\n\n address _job = msg.sender;\n if (disputes[_job]) revert JobDisputed();\n if (!_jobs.contains(_job)) revert JobUnapproved();\n\n if (_updateJobCreditsIfNeeded(_job)) {\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n (uint256 _boost, uint256 _oneUsdQuote, uint256 _extraGas) = IKeep3rHelper(keep3rHelper).getPaymentParams(bonds[_keeper][keep3rV1]);\n\n uint256 _kp3rPayment = _calculatePayment(_gasLeft, _extraGas, _oneUsdQuote * _usdPerGasUnit, _boost);\n\n if (_kp3rPayment > _jobLiquidityCredits[_job]) {\n _rewardJobCredits(_job);\n emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);\n }\n\n _bondedPayment(_job, _keeper, _kp3rPayment);\n delete _initialGas;\n\n emit KeeperWork(keep3rV1, _job, _keeper, _kp3rPayment, _gasLeft);\n }\n\n // Keep3rKeeperFundable\n\n /// @dev Sidechain implementation doesn't burn tokens, but deposit them in Keep3rEscrow\n function _depositBonds(uint256 _amount) internal virtual override {\n IKeep3rV1(keep3rV1).approve(keep3rV1Proxy, _amount);\n IKeep3rEscrow(keep3rV1Proxy).deposit(_amount);\n }\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// solhint-disable-next-line no-empty-blocks\n\nimport '../peripherals/IMintable.sol';\n\n/// @title Keep3rEscrow contract\n/// @notice This contract acts as an escrow contract for wKP3R tokens on sidechains and L2s\n/// @dev Can be used as a replacement for keep3rV1Proxy in keep3r sidechain implementations\ninterface IKeep3rEscrow is IMintable {\n /// @notice Emitted when Keep3rEscrow#deposit function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _sender The address that called the function\n /// @param _amount The amount of wKP3R the user deposited\n event wKP3RDeposited(address _wKP3R, address _sender, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#mint function is called\n /// @param _wKP3R The addess of the wrapped KP3R token\n /// @param _recipient The address that will received the newly minted wKP3R\n /// @param _amount The amount of wKP3R minted to the recipient\n event wKP3RMinted(address _wKP3R, address _recipient, uint256 _amount);\n\n /// @notice Emitted when Keep3rEscrow#setWKP3R function is called\n /// @param _newWKP3R The address of the wKP3R contract\n event wKP3RSet(address _newWKP3R);\n\n /// @notice Throws when minter attempts to withdraw more wKP3R than the escrow has in its balance\n error InsufficientBalance();\n\n /// @notice Lists the address of the wKP3R contract\n /// @return _wKP3RAddress The address of wKP3R\n function wKP3R() external view returns (address _wKP3RAddress);\n\n /// @notice Deposits wKP3R into the contract\n /// @param _amount The amount of wKP3R to deposit\n function deposit(uint256 _amount) external;\n\n /// @notice mints wKP3R to the recipient\n /// @param _amount The amount of wKP3R to mint\n function mint(uint256 _amount) external;\n\n /// @notice sets the wKP3R address\n /// @param _wKP3R the wKP3R address\n function setWKP3R(address _wKP3R) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../IKeep3rHelper.sol';\n\n/// @title Keep3rHelperSidechain contract\n/// @notice Contains all the helper functions for sidechain keep3r implementations\ninterface IKeep3rHelperSidechain is IKeep3rHelper {\n // Structs\n\n /// @dev WETH-USD Pool address, isWETHToken0 and usdDecimals\n /// @dev Created in order to quote any kind of USD tokens\n struct WethUsdOraclePool {\n address poolAddress;\n bool isWETHToken0;\n uint8 usdDecimals;\n }\n\n // Events\n\n /// @notice The oracle for a liquidity has been saved\n /// @param _liquidity The address of the given liquidity\n /// @param _oraclePool The address of the oracle pool\n event OracleSet(address _liquidity, address _oraclePool);\n\n /// @notice Emitted when the WETH USD pool is changed\n /// @param _address Address of the new WETH USD pool\n /// @param _isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n /// @param _usdDecimals The amount of decimals of the USD token paired with ETH\n event WethUSDPoolChange(address _address, bool _isWETHToken0, uint8 _usdDecimals);\n\n /// Variables\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n /// @return _weth Address of WETH token\n // solhint-disable func-name-mixedcase\n function WETH() external view returns (address _weth);\n\n /// @return _oracle The address of the observable pool for given liquidity\n function oracle(address _liquidity) external view returns (address _oracle);\n\n /// @notice WETH-USD pool that is being used as oracle\n /// @return poolAddress Address of the pool\n /// @return isWETHToken0 True if calling the token0 method of the pool returns the WETH token address\n /// @return usdDecimals The amount of decimals of the USD token paired with ETH\n function wethUSDPool()\n external\n view\n returns (\n address poolAddress,\n bool isWETHToken0,\n uint8 usdDecimals\n );\n\n /// @notice Quotes USD to ETH\n /// @dev Used to know how much ETH should be paid to keepers before converting it from ETH to KP3R\n /// @param _usd The amount of USD to quote to ETH\n /// @return _eth The resulting amount of ETH after quoting the USD\n function quoteUsdToEth(uint256 _usd) external returns (uint256 _eth);\n\n /// Methods\n\n /// @notice Sets an oracle for a given liquidity\n /// @param _liquidity The address of the liquidity\n /// @param _oracle The address of the pool used to quote the liquidity from\n /// @dev The oracle must contain KP3R as either token0 or token1\n function setOracle(address _liquidity, address _oracle) external;\n\n /// @notice Sets an oracle for querying WETH/USD quote\n /// @param _poolAddress The address of the pool used as oracle\n /// @param _usdDecimals The amount of decimals of the USD token paired with ETH\n /// @dev The oracle must contain WETH as either token0 or token1\n function setWethUsdPool(address _poolAddress, uint8 _usdDecimals) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rJobWorkableRated.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/IKeep3rJobs.sol';\n\n/// @title Keep3rJobWorkableRated contract\n/// @notice Implements a quoting in USD per gas unit for Keep3r jobs\ninterface IKeep3rJobWorkableRated is IKeep3rJobs {\n /// @notice Throws when job contract calls deprecated worked(address) function\n error Deprecated();\n\n /// @notice Implemented by jobs to show that a keeper performed work and reward in stable USD quote\n /// @dev Automatically calculates the payment for the keeper and pays the keeper with bonded KP3R\n /// @param _keeper Address of the keeper that performed the work\n /// @param _usdPerGasUnit Amount of USD in wei rewarded for gas unit worked by the keeper\n function worked(address _keeper, uint256 _usdPerGasUnit) external;\n}\n" + }, + "solidity/interfaces/sidechain/IKeep3rSidechainAccountance.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title IKeep3rSidechainAccountance interface\n/// @notice Implements a view to get the amount of credits that can be withdrawn\ninterface IKeep3rSidechainAccountance {\n /// @notice The surplus amount of wKP3Rs in escrow contract\n /// @return _virtualReserves The surplus amount of wKP3Rs in escrow contract\n function virtualReserves() external view returns (int256 _virtualReserves);\n}\n" + }, + "solidity/interfaces/peripherals/IMintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\n\n/// @title Mintable contract\n/// @notice Manages the minter role\ninterface IMintable is IBaseErrors, IGovernable {\n // Events\n\n /// @notice Emitted when governor sets a new minter\n /// @param _minter Address of the new minter\n event MinterSet(address _minter);\n\n // Errors\n\n /// @notice Throws if the caller of the function is not the minter\n error OnlyMinter();\n\n // Variables\n\n /// @notice Stores the minter address\n /// @return _minter The minter addresss\n function minter() external view returns (address _minter);\n\n // Methods\n\n /// @notice Sets a new address to be the minter\n /// @param _minter The address set as the minter\n function setMinter(address _minter) external;\n}\n" + }, + "solidity/for-test/testnet/Keep3rSidechainForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTestnet is Keep3rSidechain {\n constructor(\n address _governor,\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rSidechain(_governor, _keep3rHelper, _keep3rV1, _keep3rV1Proxy) {\n bondTime = 0; // allows keepers to instantly register\n unbondTime = 0; // allows keepers & jobOwners to instantly withdraw funds\n liquidityMinimum = 1; // allows job providers to add low liquidity\n rewardPeriodTime = 1 days; // reduces twap calculation period\n inflationPeriod = 5 days; // increases credit minting\n }\n}\n" + }, + "solidity/for-test/Keep3rSidechainForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/sidechain/Keep3rSidechain.sol';\n\ncontract Keep3rSidechainForTest is Keep3rSidechain {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _governor,\n address _keep3rHelper,\n address _wrappedKP3R,\n address _keep3rEscrow\n ) Keep3rSidechain(_governor, _keep3rHelper, _wrappedKP3R, _keep3rEscrow) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n}\n" + }, + "solidity/for-test/JobRatedForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/sidechain/IKeep3rJobWorkableRated.sol';\n\ncontract JobRatedForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n uint256 public usdPerGasUnit = 1;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i = 0; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3rJobWorkableRated(keep3r).worked(msg.sender, usdPerGasUnit);\n }\n}\n" + }, + "solidity/for-test/JobForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract JobForTest {\n error InvalidKeeper();\n address public keep3r;\n uint256 public nonce;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n\n function workHard(uint256 _factor) external {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert InvalidKeeper();\n\n for (uint256 i; i < 1000 * _factor; i++) {\n nonce++;\n }\n\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/for-test/BasicJob.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IKeep3r.sol';\n\ncontract BasicJob {\n error KeeperNotValid();\n\n address public keep3r;\n uint256 public nonce;\n uint256[] public array;\n\n constructor(address _keep3r) {\n keep3r = _keep3r;\n }\n\n function work() external upkeep {}\n\n function workHard(uint256 _howHard) external upkeep {\n for (uint256 i = nonce; i < _howHard; i++) {\n nonce++;\n }\n }\n\n function workRefund(uint256 _howHard) external upkeep {\n for (uint256 i; i < _howHard; i++) {\n array.push(i);\n }\n\n while (array.length > 0) {\n array.pop();\n }\n }\n\n modifier upkeep() {\n if (!IKeep3r(keep3r).isKeeper(msg.sender)) revert KeeperNotValid();\n _;\n IKeep3r(keep3r).worked(msg.sender);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelperParameters.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/external/IKeep3rV1.sol';\nimport '../interfaces/IKeep3rHelperParameters.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IBaseErrors.sol';\nimport '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\n\ncontract Keep3rHelperParameters is IKeep3rHelperParameters, IBaseErrors, Governable {\n /// @inheritdoc IKeep3rHelperParameters\n address public immutable override KP3R;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public constant override BOOST_BASE = 10_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBoost = 11_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override maxBoost = 12_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override targetBond = 200 ether;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override workExtraGas = 34_000;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint32 public override quoteTwapTime = 10 minutes;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minBaseFee = 15e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n uint256 public override minPriorityFee = 2e9;\n\n /// @inheritdoc IKeep3rHelperParameters\n address public override keep3rV2;\n\n /// @inheritdoc IKeep3rHelperParameters\n IKeep3rHelperParameters.Kp3rWethOraclePool public override kp3rWethPool;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governor,\n address _kp3rWethPool\n ) Governable(_governor) {\n KP3R = _kp3r;\n keep3rV2 = _keep3rV2;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n bool _isKP3RToken0 = _validateOraclePool(_kp3rWethPool, KP3R);\n kp3rWethPool = Kp3rWethOraclePool(_kp3rWethPool, _isKP3RToken0);\n emit Kp3rWethPoolChange(_kp3rWethPool, _isKP3RToken0);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKp3rWethPool(address _poolAddress) external override onlyGovernor {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setKp3rWethPool(_poolAddress);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBoost(uint256 _minBoost) external override onlyGovernor {\n minBoost = _minBoost;\n emit MinBoostChange(minBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMaxBoost(uint256 _maxBoost) external override onlyGovernor {\n maxBoost = _maxBoost;\n emit MaxBoostChange(maxBoost);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setTargetBond(uint256 _targetBond) external override onlyGovernor {\n targetBond = _targetBond;\n emit TargetBondChange(targetBond);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setKeep3rV2(address _keep3rV2) external override onlyGovernor {\n if (_keep3rV2 == address(0)) revert ZeroAddress();\n keep3rV2 = _keep3rV2;\n emit Keep3rV2Change(keep3rV2);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setWorkExtraGas(uint256 _workExtraGas) external override onlyGovernor {\n workExtraGas = _workExtraGas;\n emit WorkExtraGasChange(workExtraGas);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setQuoteTwapTime(uint32 _quoteTwapTime) external override onlyGovernor {\n _setQuoteTwapTime(_quoteTwapTime);\n }\n\n function _setQuoteTwapTime(uint32 _quoteTwapTime) internal {\n quoteTwapTime = _quoteTwapTime;\n emit QuoteTwapTimeChange(quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinBaseFee(uint256 _minBaseFee) external override onlyGovernor {\n minBaseFee = _minBaseFee;\n emit MinBaseFeeChange(minBaseFee);\n }\n\n /// @inheritdoc IKeep3rHelperParameters\n function setMinPriorityFee(uint256 _minPriorityFee) external override onlyGovernor {\n minPriorityFee = _minPriorityFee;\n emit MinPriorityFeeChange(minPriorityFee);\n }\n\n /// @notice Sets KP3R-WETH pool\n /// @param _poolAddress The address of the KP3R-WETH pool\n function _setKp3rWethPool(address _poolAddress) internal {\n bool _isKP3RToken0 = _validateOraclePool(_poolAddress, KP3R);\n kp3rWethPool = Kp3rWethOraclePool(_poolAddress, _isKP3RToken0);\n emit Kp3rWethPoolChange(_poolAddress, _isKP3RToken0);\n }\n\n function _validateOraclePool(address _poolAddress, address _token) internal view virtual returns (bool _isTKNToken0) {\n _isTKNToken0 = IUniswapV3Pool(_poolAddress).token0() == _token;\n if (!_isTKNToken0 && IUniswapV3Pool(_poolAddress).token1() != _token) revert InvalidOraclePool();\n }\n}\n" + }, + "solidity/contracts/libraries/TickMath.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n// solhint-disable\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n require(absTick <= uint256(int256(MAX_TICK)), 'T');\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // Divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n }\n\n /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may ever return.\n /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n // Second inequality must be < because the price can never reach the price at the max tick\n require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');\n uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n uint256 r = ratio;\n uint256 msb = 0;\n\n assembly {\n let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(5, gt(r, 0xFFFFFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(4, gt(r, 0xFFFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(3, gt(r, 0xFF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(2, gt(r, 0xF))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := shl(1, gt(r, 0x3))\n msb := or(msb, f)\n r := shr(f, r)\n }\n assembly {\n let f := gt(r, 0x1)\n msb := or(msb, f)\n }\n\n if (msb >= 128) r = ratio >> (msb - 127);\n else r = ratio << (127 - msb);\n\n int256 log_2 = (int256(msb) - 128) << 64;\n\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(63, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(62, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(61, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(60, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(59, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(58, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(57, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(56, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(55, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(54, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(53, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(52, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(51, f))\n r := shr(f, r)\n }\n assembly {\n r := shr(127, mul(r, r))\n let f := shr(128, r)\n log_2 := or(log_2, shl(50, f))\n }\n\n int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\nimport './pool/IUniswapV3PoolImmutables.sol';\nimport './pool/IUniswapV3PoolState.sol';\nimport './pool/IUniswapV3PoolDerivedState.sol';\nimport './pool/IUniswapV3PoolActions.sol';\nimport './pool/IUniswapV3PoolOwnerActions.sol';\nimport './pool/IUniswapV3PoolEvents.sol';\n\n/// @title The interface for a Uniswap V3 Pool\n/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform\n/// to the ERC20 specification\n/// @dev The pool interface is broken up into many smaller pieces\ninterface IUniswapV3Pool is\n IUniswapV3PoolImmutables,\n IUniswapV3PoolState,\n IUniswapV3PoolDerivedState,\n IUniswapV3PoolActions,\n IUniswapV3PoolOwnerActions,\n IUniswapV3PoolEvents\n{\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas\n /// when accessed externally.\n /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value\n /// tick The current tick of the pool, i.e. according to the last tick transition that was run.\n /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick\n /// boundary.\n /// observationIndex The index of the last oracle observation that was written,\n /// observationCardinality The current maximum number of observations stored in the pool,\n /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.\n /// feeProtocol The protocol fee for both tokens of the pool.\n /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0\n /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.\n /// unlocked Whether the pool is currently locked to reentrancy\n function slot0()\n external\n view\n returns (\n uint160 sqrtPriceX96,\n int24 tick,\n uint16 observationIndex,\n uint16 observationCardinality,\n uint16 observationCardinalityNext,\n uint8 feeProtocol,\n bool unlocked\n );\n\n /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal0X128() external view returns (uint256);\n\n /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool\n /// @dev This value can overflow the uint256\n function feeGrowthGlobal1X128() external view returns (uint256);\n\n /// @notice The amounts of token0 and token1 that are owed to the protocol\n /// @dev Protocol fees will never exceed uint128 max in either token\n function protocolFees() external view returns (uint128 token0, uint128 token1);\n\n /// @notice The currently in range liquidity available to the pool\n /// @dev This value has no relationship to the total liquidity across all ticks\n function liquidity() external view returns (uint128);\n\n /// @notice Look up information about a specific tick in the pool\n /// @param tick The tick to look up\n /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or\n /// tick upper,\n /// liquidityNet how much liquidity changes when the pool price crosses the tick,\n /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0,\n /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1,\n /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick\n /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick,\n /// secondsOutside the seconds spent on the other side of the tick from the current tick,\n /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false.\n /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0.\n /// In addition, these values are only relative and must be used only in comparison to previous snapshots for\n /// a specific position.\n function ticks(int24 tick)\n external\n view\n returns (\n uint128 liquidityGross,\n int128 liquidityNet,\n uint256 feeGrowthOutside0X128,\n uint256 feeGrowthOutside1X128,\n int56 tickCumulativeOutside,\n uint160 secondsPerLiquidityOutsideX128,\n uint32 secondsOutside,\n bool initialized\n );\n\n /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n /// @notice Returns the information about a position by the position's key\n /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper\n /// @return _liquidity The amount of liquidity in the position,\n /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke,\n /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke,\n /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke,\n /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke\n function positions(bytes32 key)\n external\n view\n returns (\n uint128 _liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Returns data about a specific observation index\n /// @param index The element of the observations array to fetch\n /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time\n /// ago, rather than at a specific index in the array.\n /// @return blockTimestamp The timestamp of the observation,\n /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp,\n /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp,\n /// Returns initialized whether the observation has been initialized and the values are safe to use\n function observations(uint256 index)\n external\n view\n returns (\n uint32 blockTimestamp,\n int56 tickCumulative,\n uint160 secondsPerLiquidityCumulativeX128,\n bool initialized\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(uint32[] calldata secondsAgos)\n external\n view\n returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range\n /// @return secondsInside The snapshot of seconds per liquidity for the range\n function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)\n external\n view\n returns (\n int56 tickCumulativeInside,\n uint160 secondsPerLiquidityInsideX128,\n uint32 secondsInside\n );\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissionless pool actions\n/// @notice Contains pool methods that can be called by anyone\ninterface IUniswapV3PoolActions {\n /// @notice Sets the initial price for the pool\n /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value\n /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96\n function initialize(uint160 sqrtPriceX96) external;\n\n /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position\n /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback\n /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends\n /// on tickLower, tickUpper, the amount of liquidity, and the current price.\n /// @param recipient The address for which the liquidity will be created\n /// @param tickLower The lower tick of the position in which to add liquidity\n /// @param tickUpper The upper tick of the position in which to add liquidity\n /// @param amount The amount of liquidity to mint\n /// @param data Any data that should be passed through to the callback\n /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback\n /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback\n function mint(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount,\n bytes calldata data\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Collects tokens owed to a position\n /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity.\n /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or\n /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the\n /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity.\n /// @param recipient The address which should receive the fees collected\n /// @param tickLower The lower tick of the position for which to collect fees\n /// @param tickUpper The upper tick of the position for which to collect fees\n /// @param amount0Requested How much token0 should be withdrawn from the fees owed\n /// @param amount1Requested How much token1 should be withdrawn from the fees owed\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect(\n address recipient,\n int24 tickLower,\n int24 tickUpper,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n\n /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position\n /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0\n /// @dev Fees must be collected separately via a call to #collect\n /// @param tickLower The lower tick of the position for which to burn liquidity\n /// @param tickUpper The upper tick of the position for which to burn liquidity\n /// @param amount How much liquidity to burn\n /// @return amount0 The amount of token0 sent to the recipient\n /// @return amount1 The amount of token1 sent to the recipient\n function burn(\n int24 tickLower,\n int24 tickUpper,\n uint128 amount\n ) external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Swap token0 for token1, or token1 for token0\n /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback\n /// @param recipient The address to receive the output of the swap\n /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0\n /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)\n /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this\n /// value after the swap. If one for zero, the price cannot be greater than this value after the swap\n /// @param data Any data to be passed through to the callback\n /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive\n /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback\n /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback\n /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling\n /// with 0 amount{0,1} and sending the donation amount(s) from the callback\n /// @param recipient The address which will receive the token0 and token1 amounts\n /// @param amount0 The amount of token0 to send\n /// @param amount1 The amount of token1 to send\n /// @param data Any data to be passed through to the callback\n function flash(\n address recipient,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n\n /// @notice Increase the maximum number of price and liquidity observations that this pool will store\n /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to\n /// the input observationCardinalityNext.\n /// @param observationCardinalityNext The desired minimum number of observations for the pool to store\n function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Permissioned pool actions\n/// @notice Contains pool methods that may only be called by the factory owner\ninterface IUniswapV3PoolOwnerActions {\n /// @notice Set the denominator of the protocol's % share of the fees\n /// @param feeProtocol0 new protocol fee for token0 of the pool\n /// @param feeProtocol1 new protocol fee for token1 of the pool\n function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;\n\n /// @notice Collect the protocol fee accrued to the pool\n /// @param recipient The address to which collected protocol fees should be sent\n /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1\n /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0\n /// @return amount0 The protocol fee collected in token0\n /// @return amount1 The protocol fee collected in token1\n function collectProtocol(\n address recipient,\n uint128 amount0Requested,\n uint128 amount1Requested\n ) external returns (uint128 amount0, uint128 amount1);\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Events emitted by a pool\n/// @notice Contains all events emitted by the pool\ninterface IUniswapV3PoolEvents {\n /// @notice Emitted exactly once by a pool when #initialize is first called on the pool\n /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize\n /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96\n /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool\n event Initialize(uint160 sqrtPriceX96, int24 tick);\n\n /// @notice Emitted when liquidity is minted for a given position\n /// @param sender The address that minted the liquidity\n /// @param owner The owner of the position and recipient of any minted liquidity\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity minted to the position range\n /// @param amount0 How much token0 was required for the minted liquidity\n /// @param amount1 How much token1 was required for the minted liquidity\n event Mint(\n address sender,\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted when fees are collected by the owner of a position\n /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees\n /// @param owner The owner of the position for which fees are collected\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount0 The amount of token0 fees collected\n /// @param amount1 The amount of token1 fees collected\n event Collect(\n address indexed owner,\n address recipient,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount0,\n uint128 amount1\n );\n\n /// @notice Emitted when a position's liquidity is removed\n /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect\n /// @param owner The owner of the position for which liquidity is removed\n /// @param tickLower The lower tick of the position\n /// @param tickUpper The upper tick of the position\n /// @param amount The amount of liquidity to remove\n /// @param amount0 The amount of token0 withdrawn\n /// @param amount1 The amount of token1 withdrawn\n event Burn(\n address indexed owner,\n int24 indexed tickLower,\n int24 indexed tickUpper,\n uint128 amount,\n uint256 amount0,\n uint256 amount1\n );\n\n /// @notice Emitted by the pool for any swaps between token0 and token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the output of the swap\n /// @param amount0 The delta of the token0 balance of the pool\n /// @param amount1 The delta of the token1 balance of the pool\n /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96\n /// @param liquidity The liquidity of the pool after the swap\n /// @param tick The log base 1.0001 of price of the pool after the swap\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n\n /// @notice Emitted by the pool for any flashes of token0/token1\n /// @param sender The address that initiated the swap call, and that received the callback\n /// @param recipient The address that received the tokens from flash\n /// @param amount0 The amount of token0 that was flashed\n /// @param amount1 The amount of token1 that was flashed\n /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee\n /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee\n event Flash(\n address indexed sender,\n address indexed recipient,\n uint256 amount0,\n uint256 amount1,\n uint256 paid0,\n uint256 paid1\n );\n\n /// @notice Emitted by the pool for increases to the number of observations that can be stored\n /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index\n /// just before a mint/swap/burn.\n /// @param observationCardinalityNextOld The previous value of the next observation cardinality\n /// @param observationCardinalityNextNew The updated value of the next observation cardinality\n event IncreaseObservationCardinalityNext(\n uint16 observationCardinalityNextOld,\n uint16 observationCardinalityNextNew\n );\n\n /// @notice Emitted when the protocol fee is changed by the pool\n /// @param feeProtocol0Old The previous value of the token0 protocol fee\n /// @param feeProtocol1Old The previous value of the token1 protocol fee\n /// @param feeProtocol0New The updated value of the token0 protocol fee\n /// @param feeProtocol1New The updated value of the token1 protocol fee\n event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);\n\n /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner\n /// @param sender The address that collects the protocol fees\n /// @param recipient The address that receives the collected protocol fees\n /// @param amount0 The amount of token0 protocol fees that is withdrawn\n /// @param amount0 The amount of token1 protocol fees that is withdrawn\n event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1);\n}\n" + }, + "solidity/contracts/UniV3PairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../interfaces/IPairManagerFactory.sol';\nimport './UniV3PairManager.sol';\nimport '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ncontract UniV3PairManagerFactory is IPairManagerFactory, Governable {\n mapping(address => address) public override pairManagers;\n\n constructor(address _governor) Governable(_governor) {}\n\n ///@inheritdoc IPairManagerFactory\n function createPairManager(address _pool) external override returns (address _pairManager) {\n if (pairManagers[_pool] != address(0)) revert AlreadyInitialized();\n _pairManager = address(new UniV3PairManager(_pool, governor));\n pairManagers[_pool] = _pairManager;\n emit PairCreated(_pool, _pairManager);\n }\n}\n" + }, + "solidity/interfaces/IPairManagerFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\n\n/// @title Factory of Pair Managers\n/// @notice This contract creates new pair managers\ninterface IPairManagerFactory is IGovernable {\n // Variables\n\n /// @notice Maps the address of a Uniswap pool, to the address of the corresponding PairManager\n /// For example, the uniswap address of DAI-WETH, will return the Keep3r/DAI-WETH pair manager address\n /// @param _pool The address of the Uniswap pool\n /// @return _pairManager The address of the corresponding pair manager\n function pairManagers(address _pool) external view returns (address _pairManager);\n\n // Events\n\n /// @notice Emitted when a new pair manager is created\n /// @param _pool The address of the corresponding Uniswap pool\n /// @param _pairManager The address of the just-created pair manager\n event PairCreated(address _pool, address _pairManager);\n\n // Errors\n\n /// @notice Throws an error if the pair manager is already initialized\n error AlreadyInitialized();\n\n /// @notice Throws an error if the caller is not the owner\n error OnlyOwner();\n\n // Methods\n\n /// @notice Creates a new pair manager based on the address of a Uniswap pool\n /// For example, the uniswap address of DAI-WETH, will create the Keep3r/DAI-WETH pool\n /// @param _pool The address of the Uniswap pool the pair manager will be based of\n /// @return _pairManager The address of the just-created pair manager\n function createPairManager(address _pool) external returns (address _pairManager);\n}\n" + }, + "solidity/contracts/UniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport './libraries/LiquidityAmounts.sol';\nimport './libraries/FixedPoint96.sol';\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\n\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManager is IUniV3PairManager, Governable {\n /// @inheritdoc IERC20Metadata\n string public override name;\n\n /// @inheritdoc IERC20Metadata\n string public override symbol;\n\n /// @inheritdoc IERC20\n uint256 public override totalSupply;\n\n /// @inheritdoc IPairManager\n address public immutable override factory;\n\n /// @inheritdoc IPairManager\n address public immutable override token0;\n\n /// @inheritdoc IPairManager\n address public immutable override token1;\n\n /// @inheritdoc IPairManager\n address public immutable override pool;\n\n /// @inheritdoc IUniV3PairManager\n uint24 public immutable override fee;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioAX96;\n\n /// @inheritdoc IUniV3PairManager\n uint160 public immutable override sqrtRatioBX96;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickLower;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickUpper;\n\n /// @inheritdoc IUniV3PairManager\n int24 public immutable override tickSpacing;\n\n /// @notice Uniswap's maximum tick\n /// @dev Due to tick spacing, pools with different fees may have differences between _MAX_TICK and tickUpper. Use tickUpper to find the max tick of the pool.\n int24 private constant _MAX_TICK = 887272;\n\n /// @inheritdoc IERC20Metadata\n //solhint-disable-next-line const-name-snakecase\n uint8 public constant override decimals = 18;\n\n /// @inheritdoc IERC20\n mapping(address => mapping(address => uint256)) public override allowance;\n\n /// @inheritdoc IERC20\n mapping(address => uint256) public override balanceOf;\n\n /// @notice Struct that contains token0, token1, and fee of the Uniswap pool\n PoolKey private _poolKey;\n\n constructor(address _pool, address _governor) Governable(_governor) {\n uint24 _fee = IUniswapV3Pool(_pool).fee();\n address _token0 = IUniswapV3Pool(_pool).token0();\n address _token1 = IUniswapV3Pool(_pool).token1();\n int24 _tickSpacing = IUniswapV3Pool(_pool).tickSpacing();\n int24 _tickUpper = _MAX_TICK - (_MAX_TICK % _tickSpacing);\n int24 _tickLower = -_tickUpper;\n\n factory = msg.sender;\n pool = _pool;\n fee = _fee;\n tickSpacing = _tickSpacing;\n tickUpper = _tickUpper;\n tickLower = _tickLower;\n token0 = _token0;\n token1 = _token1;\n name = string(abi.encodePacked('Keep3rLP - ', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n symbol = string(abi.encodePacked('kLP-', ERC20(_token0).symbol(), '/', ERC20(_token1).symbol()));\n\n sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(_tickLower);\n sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(_tickUpper);\n _poolKey = PoolKey({token0: _token0, token1: _token1, fee: _fee});\n }\n\n // This low-level function should be called from a contract which performs important safety checks\n /// @inheritdoc IUniV3PairManager\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint128 liquidity) {\n (liquidity, , ) = _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n _mint(to, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external override {\n MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));\n if (msg.sender != pool) revert OnlyPool();\n if (amount0Owed > 0) _pay(decoded._poolKey.token0, decoded.payer, pool, amount0Owed);\n if (amount1Owed > 0) _pay(decoded._poolKey.token1, decoded.payer, pool, amount1Owed);\n }\n\n /// @inheritdoc IUniV3PairManager\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external override returns (uint256 amount0, uint256 amount1) {\n (amount0, amount1) = IUniswapV3Pool(pool).burn(tickLower, tickUpper, liquidity);\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n\n IUniswapV3Pool(pool).collect(to, tickLower, tickUpper, uint128(amount0), uint128(amount1));\n _burn(msg.sender, liquidity);\n }\n\n /// @inheritdoc IUniV3PairManager\n function collect() external override onlyGovernor returns (uint256 amount0, uint256 amount1) {\n (, , , uint128 tokensOwed0, uint128 tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n (amount0, amount1) = IUniswapV3Pool(pool).collect(governor, tickLower, tickUpper, tokensOwed0, tokensOwed1);\n }\n\n /// @inheritdoc IUniV3PairManager\n function position()\n external\n view\n override\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n )\n {\n (liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128, tokensOwed0, tokensOwed1) = IUniswapV3Pool(pool).positions(\n keccak256(abi.encodePacked(address(this), tickLower, tickUpper))\n );\n }\n\n /// @inheritdoc IERC20\n function approve(address spender, uint256 amount) external override returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transfer(address to, uint256 amount) external override returns (bool) {\n _transferTokens(msg.sender, to, amount);\n return true;\n }\n\n /// @inheritdoc IERC20\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external override returns (bool) {\n address spender = msg.sender;\n uint256 spenderAllowance = allowance[from][spender];\n\n if (spender != from && spenderAllowance != type(uint256).max) {\n uint256 newAllowance = spenderAllowance - amount;\n allowance[from][spender] = newAllowance;\n\n emit Approval(from, spender, newAllowance);\n }\n\n _transferTokens(from, to, amount);\n return true;\n }\n\n /// @notice Adds liquidity to an initialized pool\n /// @dev Reverts if the returned amount0 is less than amount0Min or if amount1 is less than amount1Min\n /// @dev This function calls the mint function of the corresponding Uniswap pool, which in turn calls UniswapV3Callback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @return liquidity The calculated liquidity we get for the token amounts we provided\n /// @return amount0 The amount of token0 we ended up providing\n /// @return amount1 The amount of token1 we ended up providing\n function _addLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n internal\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3Pool(pool).slot0();\n\n liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, amount0Desired, amount1Desired);\n\n (amount0, amount1) = IUniswapV3Pool(pool).mint(\n address(this),\n tickLower,\n tickUpper,\n liquidity,\n abi.encode(MintCallbackData({_poolKey: _poolKey, payer: msg.sender}))\n );\n\n if (amount0 < amount0Min || amount1 < amount1Min) revert ExcessiveSlippage();\n }\n\n /// @notice Transfers the passed-in token from the payer to the recipient for the corresponding value\n /// @param token The token to be transferred to the recipient\n /// @param from The address of the payer\n /// @param to The address of the passed-in tokens recipient\n /// @param value How much of that token to be transferred from payer to the recipient\n function _pay(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n _safeTransferFrom(token, from, to, value);\n }\n\n /// @notice Mints Keep3r credits to the passed-in address of recipient and increases total supply of Keep3r credits by the corresponding amount\n /// @param to The recipient of the Keep3r credits\n /// @param amount The amount Keep3r credits to be minted to the recipient\n function _mint(address to, uint256 amount) internal {\n totalSupply += amount;\n balanceOf[to] += amount;\n emit Transfer(address(0), to, amount);\n }\n\n /// @notice Burns Keep3r credits to the passed-in address of recipient and reduces total supply of Keep3r credits by the corresponding amount\n /// @param to The address that will get its Keep3r credits burned\n /// @param amount The amount Keep3r credits to be burned from the recipient/recipient\n function _burn(address to, uint256 amount) internal {\n totalSupply -= amount;\n balanceOf[to] -= amount;\n emit Transfer(to, address(0), amount);\n }\n\n /// @notice Transfers amount of Keep3r credits between two addresses\n /// @param from The user that transfers the Keep3r credits\n /// @param to The user that receives the Keep3r credits\n /// @param amount The amount of Keep3r credits to be transferred\n function _transferTokens(\n address from,\n address to,\n uint256 amount\n ) internal {\n balanceOf[from] -= amount;\n balanceOf[to] += amount;\n\n emit Transfer(from, to, amount);\n }\n\n /// @notice Transfers the passed-in token from the specified \"from\" to the specified \"to\" for the corresponding value\n /// @dev Reverts with IUniV3PairManager#UnsuccessfulTransfer if the transfer was not successful,\n /// or if the passed data length is different than 0 and the decoded data is not a boolean\n /// @param token The token to be transferred to the specified \"to\"\n /// @param from The address which is going to transfer the tokens\n /// @param value How much of that token to be transferred from \"from\" to \"to\"\n function _safeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) internal {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert UnsuccessfulTransfer();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "solidity/contracts/libraries/LiquidityAmounts.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport './FullMath.sol';\nimport './FixedPoint96.sol';\n\n// solhint-disable\nlibrary LiquidityAmounts {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) internal pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) internal pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + }, + "solidity/contracts/libraries/FixedPoint96.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nlibrary FixedPoint96 {\n // solhint-disable\n uint8 internal constant RESOLUTION = 96;\n uint256 internal constant Q96 = 0x1000000000000000000000000;\n}\n" + }, + "solidity/interfaces/external/IWeth9.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IWeth9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256) external;\n}\n" + }, + "solidity/interfaces/IUniV3PairManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport './IPairManager.sol';\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\nimport '@defi-wonderland/solidity-utils/solidity/interfaces/IGovernable.sol';\n\n/// @title Pair Manager contract\n/// @notice Creates a UniswapV3 position, and tokenizes in an ERC20 manner\n/// so that the user can use it as liquidity for a Keep3rJob\ninterface IUniV3PairManager is IGovernable, IPairManager {\n // Structs\n struct PoolKey {\n address token0;\n address token1;\n uint24 fee;\n }\n\n /// @notice The data to be decoded by the UniswapV3MintCallback function\n struct MintCallbackData {\n PoolKey _poolKey; // Struct that contains token0, token1, and fee of the pool passed into the constructor\n address payer; // The address of the payer, which will be the msg.sender of the mint function\n }\n\n // Variables\n\n /// @notice The fee of the Uniswap pool passed into the constructor\n /// @return _fee The fee of the Uniswap pool passed into the constructor\n function fee() external view returns (uint24 _fee);\n\n /// @notice Highest tick in the Uniswap's curve\n /// @return _tickUpper The highest tick in the Uniswap's curve\n function tickUpper() external view returns (int24 _tickUpper);\n\n /// @notice Lowest tick in the Uniswap's curve\n /// @return _tickLower The lower tick in the Uniswap's curve\n function tickLower() external view returns (int24 _tickLower);\n\n /// @notice The pair tick spacing\n /// @return _tickSpacing The pair tick spacing\n function tickSpacing() external view returns (int24 _tickSpacing);\n\n /// @notice The sqrtRatioAX96 at the lowest tick (-887200) of the Uniswap pool\n /// @return _sqrtPriceA96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the lowest tick\n function sqrtRatioAX96() external view returns (uint160 _sqrtPriceA96);\n\n /// @notice The sqrtRatioBX96 at the highest tick (887200) of the Uniswap pool\n /// @return _sqrtPriceBX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the highest tick\n function sqrtRatioBX96() external view returns (uint160 _sqrtPriceBX96);\n\n // Errors\n\n /// @notice Throws when the caller of the function is not the pool\n error OnlyPool();\n\n /// @notice Throws when the slippage exceeds what the user is comfortable with\n error ExcessiveSlippage();\n\n /// @notice Throws when a transfer is unsuccessful\n error UnsuccessfulTransfer();\n\n // Methods\n\n /// @notice This function is called after a user calls IUniV3PairManager#mint function\n /// It ensures that any tokens owed to the pool are paid by the msg.sender of IUniV3PairManager#mint function\n /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity\n /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity\n /// @param data The encoded token0, token1, fee (_poolKey) and the payer (msg.sender) of the IUniV3PairManager#mint function\n function uniswapV3MintCallback(\n uint256 amount0Owed,\n uint256 amount1Owed,\n bytes calldata data\n ) external;\n\n /// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool\n /// @dev Triggers UniV3PairManager#uniswapV3MintCallback\n /// @param amount0Desired The amount of token0 we would like to provide\n /// @param amount1Desired The amount of token1 we would like to provide\n /// @param amount0Min The minimum amount of token0 we want to provide\n /// @param amount1Min The minimum amount of token1 we want to provide\n /// @param to The address to which the kLP tokens are going to be minted to\n /// @return liquidity kLP tokens sent in exchange for the provision of tokens\n function mint(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint128 liquidity);\n\n /// @notice Returns the pair manager's position in the corresponding UniswapV3 pool\n /// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager\n /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position\n /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position\n /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation\n /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation\n function position()\n external\n view\n returns (\n uint128 liquidity,\n uint256 feeGrowthInside0LastX128,\n uint256 feeGrowthInside1LastX128,\n uint128 tokensOwed0,\n uint128 tokensOwed1\n );\n\n /// @notice Calls the UniswapV3 pool's collect function, which collects up to a maximum amount of fees\n // owed to a specific position to the recipient, in this case, that recipient is the pair manager\n /// @dev The collected fees will be sent to governor\n /// @return amount0 The amount of fees collected in token0\n /// @return amount1 The amount of fees collected in token1\n function collect() external returns (uint256 amount0, uint256 amount1);\n\n /// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity\n // in the entire range\n /// @param liquidity The amount of liquidity to be burned\n /// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)\n /// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)\n /// @param to The address that will receive the due fees\n /// @return amount0 The calculated amount of token0 that will be sent to the recipient\n /// @return amount1 The calculated amount of token1 that will be sent to the recipient\n function burn(\n uint128 liquidity,\n uint256 amount0Min,\n uint256 amount1Min,\n address to\n ) external returns (uint256 amount0, uint256 amount1);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "solidity/for-test/UniV3PairManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\nimport '../contracts/libraries/LiquidityAmounts.sol';\nimport '../contracts/libraries/FixedPoint96.sol';\nimport '../contracts/libraries/FullMath.sol';\nimport '../contracts/libraries/TickMath.sol';\nimport '../contracts/UniV3PairManager.sol';\nimport '../interfaces/external/IWeth9.sol';\nimport '../interfaces/IUniV3PairManager.sol';\n\ncontract UniV3PairManagerForTest is UniV3PairManager {\n constructor(address _pool, address _governor) UniV3PairManager(_pool, _governor) {}\n\n function internalAddLiquidity(\n uint256 amount0Desired,\n uint256 amount1Desired,\n uint256 amount0Min,\n uint256 amount1Min\n )\n external\n returns (\n uint128 liquidity,\n uint256 amount0,\n uint256 amount1\n )\n {\n return _addLiquidity(amount0Desired, amount1Desired, amount0Min, amount1Min);\n }\n\n function internalPay(\n address token,\n address payer,\n address recipient,\n uint256 value\n ) external {\n return _pay(token, payer, recipient, value);\n }\n\n function internalMint(address dst, uint256 amount) external {\n return _mint(dst, amount);\n }\n\n function internalBurn(address dst, uint256 amount) external {\n return _burn(dst, amount);\n }\n\n function internalTransferTokens(\n address src,\n address dst,\n uint256 amount\n ) external {\n _transferTokens(src, dst, amount);\n }\n\n function internalSafeTransferFrom(\n address token,\n address from,\n address to,\n uint256 value\n ) external {\n _safeTransferFrom(token, from, to, value);\n }\n\n receive() external payable {}\n}\n" + }, + "solidity/contracts/sidechain/Keep3rEscrow.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../peripherals/Mintable.sol';\nimport '../../interfaces/sidechain/IKeep3rEscrow.sol';\nimport '@defi-wonderland/solidity-utils/solidity/contracts/DustCollector.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\n\ncontract Keep3rEscrow is Mintable, DustCollector, IKeep3rEscrow {\n using SafeERC20 for IERC20;\n\n /// @inheritdoc IKeep3rEscrow\n address public override wKP3R;\n\n /// @param _governor Address of governor\n /// @param _wKP3R Address of wrapped KP3R implementation\n constructor(address _governor, address _wKP3R) Mintable(_governor) {\n wKP3R = _wKP3R;\n }\n\n /// @inheritdoc IKeep3rEscrow\n function deposit(uint256 _amount) external override {\n IERC20(wKP3R).safeTransferFrom(msg.sender, address(this), _amount);\n emit wKP3RDeposited(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function mint(uint256 _amount) external override onlyMinter {\n IERC20(wKP3R).safeTransfer(msg.sender, _amount);\n emit wKP3RMinted(wKP3R, msg.sender, _amount);\n }\n\n /// @inheritdoc IKeep3rEscrow\n function setWKP3R(address _wKP3R) external override onlyGovernor {\n if (_wKP3R == address(0)) revert ZeroAddress();\n wKP3R = _wKP3R;\n emit wKP3RSet(wKP3R);\n }\n}\n" + }, + "solidity/contracts/peripherals/Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../interfaces/peripherals/IMintable.sol';\nimport '@defi-wonderland/solidity-utils/solidity/contracts/Governable.sol';\n\nabstract contract Mintable is Governable, IMintable {\n /// @inheritdoc IMintable\n address public override minter;\n\n constructor(address _governor) Governable(_governor) {}\n\n /// @inheritdoc IMintable\n function setMinter(address _minter) external override onlyGovernor {\n if (_minter == address(0)) revert ZeroAddress();\n minter = _minter;\n emit MinterSet(_minter);\n }\n\n /// @notice Functions with this modifier can only be called by the minter;\n modifier onlyMinter() {\n if (msg.sender != minter) revert OnlyMinter();\n _;\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperFundableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperFundable.sol';\n\ncontract Keep3rKeeperFundableForTest is Keep3rKeeperFundable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function isKeeper(address _keeper) external view returns (bool) {\n return _keepers.contains(_keeper);\n }\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n}\n" + }, + "solidity/for-test/BridgeForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ncontract BridgeForTest is ERC20 {\n address public immutable kp3r;\n\n constructor(address _kp3r) ERC20('Wrapped KP3R', 'wKP3R') {\n kp3r = _kp3r;\n }\n\n function bridge(uint256 _amount) external {\n IERC20(kp3r).transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n }\n\n function bridgeBack(uint256 _amount) external {\n _burn(msg.sender, _amount);\n IERC20(kp3r).transfer(msg.sender, _amount);\n }\n}\n" + }, + "solidity/for-test/ERC20ForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@openzeppelin/contracts/token/ERC20/ERC20.sol';\n\ncontract ERC20ForTest is ERC20 {\n constructor(\n string memory _name,\n string memory _symbol,\n address _initialAccount,\n uint256 _initialBalance\n ) ERC20(_name, _symbol) {\n _mint(_initialAccount, _initialBalance);\n }\n\n function mint(uint256 _amount) public {\n _mint(msg.sender, _amount);\n }\n\n function mint(address _account, uint256 _amount) public {\n _mint(_account, _amount);\n }\n\n function burn(uint256 _amount) public {\n _burn(msg.sender, _amount);\n }\n\n function burn(address _account, uint256 _amount) public {\n _burn(_account, _amount);\n }\n\n function transferInternal(\n address _from,\n address _to,\n uint256 _value\n ) public {\n _transfer(_from, _to, _value);\n }\n\n function approveInternal(\n address _owner,\n address _spender,\n uint256 _value\n ) public {\n _approve(_owner, _spender, _value);\n }\n\n function deposit() external payable {\n // Function added for compatibility with WETH\n }\n}\n" + }, + "solidity/for-test/peripherals/keepers/Keep3rKeeperDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/keepers/Keep3rKeeperDisputable.sol';\n\ncontract Keep3rKeeperDisputableForTest is Keep3rKeeperDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function internalSlash(\n address _bonded,\n address _keeper,\n uint256 _bondAmount,\n uint256 _unbondAmount\n ) external {\n _slash(_bonded, _keeper, _bondAmount, _unbondAmount);\n }\n\n function isKeeper(address _address) external view returns (bool _isKeeper) {\n _isKeeper = _keepers.contains(_address);\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rDisputable.sol';\n\ncontract Keep3rDisputableForTest is Keep3rDisputable {\n constructor() Keep3rParameters(address(0), address(0), address(0)) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/Keep3rParametersForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rParameters.sol';\n\ncontract Keep3rParametersForTest is Keep3rParameters {\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableLiquidityForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol';\n\ncontract Keep3rJobFundableLiquidityForTest is Keep3rJobFundableLiquidity {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external returns (bool) {\n return _jobLiquidities[_job].add(_liquidity);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewTickOrder(address _liquidity) external view returns (bool) {\n return _isKP3RToken0[_liquidity];\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function internalSettleJobAccountance(address _job) external {\n _settleJobAccountance(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobDisputableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobDisputable.sol';\n\ncontract Keep3rJobDisputableForTest is Keep3rJobDisputable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setRevokedLiquidity(address _liquidity) external {\n _approvedLiquidities.remove(_liquidity);\n }\n\n function internalJobLiquidityCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobLiquidityCredits[_job];\n }\n\n function internalJobPeriodCredits(address _job) external view returns (uint256 _credits) {\n _credits = _jobPeriodCredits[_job];\n }\n\n function internalJobTokens(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobTokens[_job].length());\n for (uint256 i; i < _jobTokens[_job].length(); i++) {\n _tokens[i] = _jobTokens[_job].at(i);\n }\n }\n\n function internalJobLiquidities(address _job) external view returns (address[] memory _tokens) {\n _tokens = new address[](_jobLiquidities[_job].length());\n for (uint256 i; i < _jobLiquidities[_job].length(); i++) {\n _tokens[i] = _jobLiquidities[_job].at(i);\n }\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobFundableCreditsForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobFundableCredits.sol';\n\ncontract Keep3rJobFundableCreditsForTest is Keep3rJobFundableCredits {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job, address _jobOwner) external {\n _jobs.add(_job);\n jobOwner[_job] = _jobOwner;\n }\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function isJobToken(address _job, address _token) external view returns (bool _contains) {\n _contains = _jobTokens[_job].contains(_token);\n }\n}\n" + }, + "solidity/contracts/Keep3rHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗  ░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║  ░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║  ░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║  ░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║  ░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝  ░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\n*/\n\npragma solidity >=0.8.7 <0.9.0;\n\nimport './libraries/FullMath.sol';\nimport './libraries/TickMath.sol';\nimport '../interfaces/IKeep3r.sol';\nimport '../interfaces/IKeep3rHelper.sol';\nimport './Keep3rHelperParameters.sol';\n\nimport '@openzeppelin/contracts/utils/math/Math.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\ncontract Keep3rHelper is IKeep3rHelper, Keep3rHelperParameters {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governor,\n address _kp3rWethPool\n ) Keep3rHelperParameters(_kp3r, _keep3rV2, _governor, _kp3rWethPool) {}\n\n /// @inheritdoc IKeep3rHelper\n function quote(uint256 _eth) public view override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(kp3rWethPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_eth), kp3rWethPool.isKP3RToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelper\n function bonds(address _keeper) public view virtual override returns (uint256 _amountBonded) {\n return IKeep3r(keep3rV2).bonds(_keeper, KP3R);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmountFor(address _keeper, uint256 _gasUsed) public view override returns (uint256 _kp3r) {\n uint256 _boost = getRewardBoostFor(bonds(_keeper));\n _kp3r = quote((_gasUsed * _boost) / BOOST_BASE);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardAmount(uint256 _gasUsed) external view override returns (uint256 _amount) {\n // solhint-disable-next-line avoid-tx-origin\n return getRewardAmountFor(tx.origin, _gasUsed);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getRewardBoostFor(uint256 _bonds) public view override returns (uint256 _rewardBoost) {\n _bonds = Math.min(_bonds, targetBond);\n uint256 _cap = minBoost + ((maxBoost - minBoost) * _bonds) / targetBond;\n _rewardBoost = _cap * _getBasefee();\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPoolTokens(address _pool) public view override returns (address _token0, address _token1) {\n return (IUniswapV3Pool(_pool).token0(), IUniswapV3Pool(_pool).token1());\n }\n\n /// @inheritdoc IKeep3rHelper\n function isKP3RToken0(address _pool) external view virtual override returns (bool _isKP3RToken0) {\n address _token0;\n address _token1;\n (_token0, _token1) = getPoolTokens(_pool);\n if (_token0 == KP3R) {\n return true;\n } else if (_token1 != KP3R) {\n revert LiquidityPairInvalid();\n }\n }\n\n /// @inheritdoc IKeep3rHelper\n function observe(address _pool, uint32[] memory _secondsAgo)\n external\n view\n override\n returns (\n int56 _tickCumulative1,\n int56 _tickCumulative2,\n bool _success\n )\n {\n try IUniswapV3Pool(_pool).observe(_secondsAgo) returns (int56[] memory _uniswapResponse, uint160[] memory) {\n _tickCumulative1 = _uniswapResponse[0];\n if (_uniswapResponse.length > 1) {\n _tickCumulative2 = _uniswapResponse[1];\n }\n _success = true;\n } catch (bytes memory) {}\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override\n returns (\n uint256 _boost,\n uint256 _oneEthQuote,\n uint256 _extra\n )\n {\n _oneEthQuote = quote(1 ether);\n _boost = getRewardBoostFor(_bonds);\n _extra = workExtraGas;\n }\n\n /// @inheritdoc IKeep3rHelper\n function getKP3RsAtTick(\n uint256 _liquidityAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) external pure override returns (uint256 _kp3rAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n _kp3rAmount = FullMath.mulDiv(1 << 96, _liquidityAmount, sqrtRatioX96);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getQuoteAtTick(\n uint128 _baseAmount,\n int56 _tickDifference,\n uint256 _timeInterval\n ) public pure override returns (uint256 _quoteAmount) {\n uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(int24(_tickDifference / int256(_timeInterval)));\n\n if (sqrtRatioX96 <= type(uint128).max) {\n uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;\n _quoteAmount = FullMath.mulDiv(1 << 192, _baseAmount, ratioX192);\n } else {\n uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);\n _quoteAmount = FullMath.mulDiv(1 << 128, _baseAmount, ratioX128);\n }\n }\n\n /// @notice Gets the gas basefee cost to calculate keeper rewards\n /// @dev Keepers are required to pay a priority fee to be included, this function recognizes a minimum priority fee\n /// @return _baseFee The block's basefee + a minimum priority fee, or a preset minimum gas fee\n function _getBasefee() internal view virtual returns (uint256 _baseFee) {\n return Math.max(minBaseFee, block.basefee + minPriorityFee);\n }\n}\n" + }, + "solidity/for-test/testnet/Keep3rHelperForTestnet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTestnet is Keep3rHelper {\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governor,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governor, _kp3rWethPool) {}\n\n function _getBasefee() internal pure override returns (uint256) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/Keep3rHelperForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../contracts/Keep3rHelper.sol';\n\ncontract Keep3rHelperForTest is Keep3rHelper {\n uint256 public basefee;\n\n constructor(\n address _kp3r,\n address _keep3rV2,\n address _governor,\n address _kp3rWethPool\n ) Keep3rHelper(_kp3r, _keep3rV2, _governor, _kp3rWethPool) {}\n\n function _getBasefee() internal view override returns (uint256) {\n return basefee != 0 ? (basefee + minPriorityFee) : super._getBasefee();\n }\n\n function setBaseFee(uint256 _baseFee) external {\n basefee = _baseFee;\n }\n}\n" + }, + "solidity/contracts/sidechain/Keep3rHelperSidechain.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/*\n\nCoded for The Keep3r Network with ♥ by\n\n██████╗░███████╗███████╗██╗░░░██╗░░░░░░░██╗░█████╗░███╗░░██╗██████╗░███████╗██████╗░██╗░░░░░░█████╗░███╗░░██╗██████╗░\n██╔══██╗██╔════╝██╔════╝██║░░░██║░░██╗░░██║██╔══██╗████╗░██║██╔══██╗██╔════╝██╔══██╗██║░░░░░██╔══██╗████╗░██║██╔══██╗\n██║░░██║█████╗░░█████╗░░██║░░░╚██╗████╗██╔╝██║░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██║░░░░░███████║██╔██╗██║██║░░██║\n██║░░██║██╔══╝░░██╔══╝░░██║░░░░████╔═████║░██║░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██║░░░░░██╔══██║██║╚████║██║░░██║\n██████╔╝███████╗██║░░░░░██║░░░░╚██╔╝░╚██╔╝░╚█████╔╝██║░╚███║██████╔╝███████╗██║░░██║███████╗██║░░██║██║░╚███║██████╔╝\n╚═════╝░╚══════╝╚═╝░░░░░╚═╝░░░░░╚═╝░░░╚═╝░░░╚════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░\n\nhttps://defi.sucks\n\nCommit hash: ead559c8dc4361349b7222741c2399447e255d8e\n\n*/\n\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../Keep3rHelper.sol';\nimport '../../interfaces/sidechain/IKeep3rHelperSidechain.sol';\n\ncontract Keep3rHelperSidechain is IKeep3rHelperSidechain, Keep3rHelper {\n /// @inheritdoc IKeep3rHelperSidechain\n mapping(address => address) public override oracle;\n /// @inheritdoc IKeep3rHelperSidechain\n IKeep3rHelperSidechain.WethUsdOraclePool public override wethUSDPool;\n\n /// @notice Ethereum mainnet WETH address used for quoting references\n address public immutable override WETH;\n\n /// @dev Amount of decimals in which USD is quoted within the contract\n uint256 constant _USD_BASE_DECIMALS = 18;\n\n /// @param _keep3rV2 Address of sidechain Keep3r implementation\n /// @param _governor Address of governor\n /// @param _kp3rWethOracle Address of oracle used for KP3R/WETH quote\n /// @param _wethUsdOracle Address of oracle used for WETH/USD quote\n /// @dev Oracle pools should use 18 decimals tokens\n constructor(\n address _keep3rV2,\n address _governor,\n address _kp3r,\n address _weth,\n address _kp3rWethOracle,\n address _wethUsdOracle,\n uint8 _usdDecimals\n ) Keep3rHelper(_kp3r, _keep3rV2, _governor, _kp3rWethOracle) {\n WETH = _weth;\n\n // Immutable variables [KP3R] cannot be read during contract creation time [_setKp3rWethPool]\n bool _isWETHToken0 = _validateOraclePool(_wethUsdOracle, WETH);\n wethUSDPool = WethUsdOraclePool(_wethUsdOracle, _isWETHToken0, _usdDecimals);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isWETHToken0, _usdDecimals);\n\n _setQuoteTwapTime(1 days);\n workExtraGas = 0;\n }\n\n /// @inheritdoc IKeep3rHelper\n /// @notice Uses valid wKP3R address from Keep3rSidechain to query keeper bonds\n function bonds(address _keeper) public view override(Keep3rHelper, IKeep3rHelper) returns (uint256 _amountBonded) {\n address wKP3R = IKeep3r(keep3rV2).keep3rV1();\n return IKeep3r(keep3rV2).bonds(_keeper, wKP3R);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setOracle(address _liquidity, address _oracle) external override onlyGovernor {\n if (_liquidity == address(0) || _oracle == address(0)) revert ZeroAddress();\n oracle[_liquidity] = _oracle;\n emit OracleSet(_liquidity, _oracle);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function quoteUsdToEth(uint256 _usd) public view virtual override returns (uint256 _amountOut) {\n uint32[] memory _secondsAgos = new uint32[](2);\n _secondsAgos[1] = quoteTwapTime;\n _usd = _usd / 10**(_USD_BASE_DECIMALS - wethUSDPool.usdDecimals);\n\n /// @dev Oracle is compatible with IUniswapV3Pool\n (int56[] memory _tickCumulatives, ) = IUniswapV3Pool(wethUSDPool.poolAddress).observe(_secondsAgos);\n int56 _difference = _tickCumulatives[0] - _tickCumulatives[1];\n _amountOut = getQuoteAtTick(uint128(_usd), wethUSDPool.isWETHToken0 ? _difference : -_difference, quoteTwapTime);\n }\n\n /// @inheritdoc IKeep3rHelperSidechain\n function setWethUsdPool(address _poolAddress, uint8 _usdDecimals) external override onlyGovernor {\n if (_poolAddress == address(0)) revert ZeroAddress();\n _setWethUsdPool(_poolAddress, _usdDecimals);\n }\n\n /// @inheritdoc IKeep3rHelper\n function getPaymentParams(uint256 _bonds)\n external\n view\n virtual\n override(Keep3rHelper, IKeep3rHelper)\n returns (\n uint256 _boost,\n uint256 _oneUsdQuote,\n uint256 _extraGas\n )\n {\n _oneUsdQuote = quote(quoteUsdToEth(1 ether));\n _boost = getRewardBoostFor(_bonds);\n _extraGas = workExtraGas;\n }\n\n function _setWethUsdPool(address _poolAddress, uint8 _usdDecimals) internal {\n bool _isWETHToken0 = _validateOraclePool(_poolAddress, WETH);\n wethUSDPool = WethUsdOraclePool(_poolAddress, _isWETHToken0, _usdDecimals);\n emit WethUSDPoolChange(wethUSDPool.poolAddress, wethUSDPool.isWETHToken0, _usdDecimals);\n }\n\n /// @dev Sidechain jobs are quoted by USD/gasUnit, baseFee is set to 1\n function _getBasefee() internal view virtual override returns (uint256 _baseFee) {\n return 1;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobWorkableForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobWorkable.sol';\n\ncontract Keep3rJobWorkableForTest is Keep3rJobWorkable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_keep3rHelper, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJob(address _job) external {\n _jobs.add(_job);\n }\n\n function setKeeper(address _keeper) external {\n _keepers.add(_keeper);\n }\n\n function setApprovedLiquidity(address _liquidity) external {\n _approvedLiquidities.add(_liquidity);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewTickCache(address _liquidity) external view returns (TickCache memory _tickCache) {\n _tickCache = _tick[_liquidity];\n }\n\n function viewGas() external view returns (uint256) {\n return _initialGas;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobMigrationForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobMigration.sol';\n\ncontract Keep3rJobMigrationForTest is Keep3rJobMigration {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(address => uint256) public settleJobAccountanceCallCount;\n\n constructor(\n address _kph,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rParameters(_kph, _keep3rV1, _keep3rV1Proxy) Keep3rRoles(msg.sender) {}\n\n function setJobToken(address _job, address _token) external {\n _jobTokens[_job].add(_token);\n }\n\n function setJobLiquidity(address _job, address _liquidity) external {\n _jobLiquidities[_job].add(_liquidity);\n }\n\n function viewJobTokenListLength(address _job) external view returns (uint256) {\n return _jobTokens[_job].length();\n }\n\n function viewJobLiquidityList(address _job) external view returns (address[] memory _list) {\n _list = _jobLiquidities[_job].values();\n }\n\n function viewJobPeriodCredits(address _job) external view returns (uint256) {\n return _jobPeriodCredits[_job];\n }\n\n function viewJobLiquidityCredits(address _job) external view returns (uint256) {\n return _jobLiquidityCredits[_job];\n }\n\n function viewMigrationCreatedAt(address _fromJob, address _toJob) external view returns (uint256) {\n return _migrationCreatedAt[_fromJob][_toJob];\n }\n\n function isJob(address _job) external view returns (bool) {\n return _jobs.contains(_job);\n }\n\n function _settleJobAccountance(address _job) internal override {\n settleJobAccountanceCallCount[_job]++;\n }\n}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobOwnershipForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobOwnership.sol';\n\ncontract Keep3rJobOwnershipForTest is Keep3rJobOwnership {}\n" + }, + "solidity/for-test/peripherals/jobs/Keep3rJobManagerForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../../contracts/peripherals/jobs/Keep3rJobManager.sol';\n\ncontract Keep3rJobManagerForTest is Keep3rJobManager {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor(\n address _keep3rHelper,\n address _keep3rV1,\n address _keep3rV1Proxy\n ) Keep3rRoles(msg.sender) {}\n\n function isJob(address _job) external view returns (bool _isJob) {\n _isJob = _jobs.contains(_job);\n }\n}\n" + }, + "solidity/for-test/peripherals/Keep3rAccountanceForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/peripherals/Keep3rAccountance.sol';\n\ncontract Keep3rAccountanceForTest is Keep3rAccountance {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n constructor() Keep3rRoles(msg.sender) {}\n\n function setJob(address job) external {\n _jobs.add(job);\n }\n\n function setKeeper(address keeper) external {\n _keepers.add(keeper);\n }\n}\n" + }, + "solidity/for-test/IUniswapV3PoolForTest.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';\nimport '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';\n\n// solhint-disable-next-line no-empty-blocks\ninterface IUniswapV3PoolForTest is IERC20Minimal, IUniswapV3Pool {\n\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Minimal ERC20 interface for Uniswap\n/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3\ninterface IERC20Minimal {\n /// @notice Returns the balance of a token\n /// @param account The account for which to look up the number of tokens it has, i.e. its balance\n /// @return The number of tokens held by the account\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Transfers the amount of token from the `msg.sender` to the recipient\n /// @param recipient The account that will receive the amount transferred\n /// @param amount The number of tokens to send from the sender to the recipient\n /// @return Returns true for a successful transfer, false for an unsuccessful transfer\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /// @notice Returns the current allowance given to a spender by an owner\n /// @param owner The account of the token owner\n /// @param spender The account of the token spender\n /// @return The current allowance granted by `owner` to `spender`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`\n /// @param spender The account which will be allowed to spend a given amount of the owners tokens\n /// @param amount The amount of tokens allowed to be used by `spender`\n /// @return Returns true for a successful approval, false for unsuccessful\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`\n /// @param sender The account from which the transfer will be initiated\n /// @param recipient The recipient of the transfer\n /// @param amount The amount of the transfer\n /// @return Returns true for a successful transfer, false for unsuccessful\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.\n /// @param from The account from which the tokens were sent, i.e. the balance decreased\n /// @param to The account to which the tokens were sent, i.e. the balance increased\n /// @param value The amount of tokens that were transferred\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.\n /// @param owner The account that approved spending of its tokens\n /// @param spender The account for which the spending allowance was modified\n /// @param value The new allowance from the owner to the spender\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "solidity/for-test/libraries/LiquidityAmountsForTest.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.8.4 <0.9.0;\n\nimport '../../contracts/libraries/FullMath.sol';\nimport '../../contracts/libraries/FixedPoint96.sol';\n\n/// @dev Made this library into a contract to be able to calculate liquidity more precisely for tests\n\n// solhint-disable\ncontract LiquidityAmountsForTest {\n function toUint128(uint256 x) private pure returns (uint128 y) {\n require((y = uint128(x)) == x);\n }\n\n function getLiquidityForAmount0(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);\n return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmount1(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount1\n ) public pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));\n }\n\n function getLiquidityForAmounts(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint256 amount0,\n uint256 amount1\n ) external pure returns (uint128 liquidity) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);\n uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);\n\n liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;\n } else {\n liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);\n }\n }\n\n function getAmount0ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount0) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96) / sqrtRatioAX96;\n }\n\n function getAmount1ForLiquidity(\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) public pure returns (uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);\n }\n\n function getAmountsForLiquidity(\n uint160 sqrtRatioX96,\n uint160 sqrtRatioAX96,\n uint160 sqrtRatioBX96,\n uint128 liquidity\n ) external pure returns (uint256 amount0, uint256 amount1) {\n if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);\n\n if (sqrtRatioX96 <= sqrtRatioAX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n } else if (sqrtRatioX96 < sqrtRatioBX96) {\n amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);\n } else {\n amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "libraries": { + "": { + "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" + } + } + } +} \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts index 97ad22c..dd5cad3 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -43,6 +43,13 @@ const config: HardhatUserConfig = { mainnet: 'mainnet', }, }, + polygon: { + url: process.env.POLYGON_HTTPS_URL, + accounts: [process.env.POLYGON_PRIVATE_KEY as string], + companionNetworks: { + mainnet: 'mainnet', + }, + }, goerli: { url: process.env.GOERLI_HTTPS_URL, accounts: [process.env.GOERLI_PRIVATE_KEY as string], @@ -85,6 +92,7 @@ const config: HardhatUserConfig = { apiKey: { mainnet: process.env.ETHERSCAN_API_KEY as string, optimisticEthereum: process.env.OPTIMISTIC_ETHERSCAN_API_KEY as string, + polygon: process.env.POLYGON_ETHERSCAN_API_KEY as string, goerli: process.env.GOERLI_ETHERSCAN_API_KEY as string, optimisticGoerli: process.env.OP_GOERLI_ETHERSCAN_API_KEY as string, }, diff --git a/solidity/contracts/sidechain/Keep3rEscrow.sol b/solidity/contracts/sidechain/Keep3rEscrow.sol index b8de01a..c3d45a3 100644 --- a/solidity/contracts/sidechain/Keep3rEscrow.sol +++ b/solidity/contracts/sidechain/Keep3rEscrow.sol @@ -13,7 +13,7 @@ Coded for The Keep3r Network with ♥ by https://defi.sucks -Commit hash: ead559c8dc4361349b7222741c2399447e255d8e +Commit hash: b18e2940310077e04ec08b3026dc92e441fb08ef */ diff --git a/solidity/contracts/sidechain/Keep3rHelperSidechain.sol b/solidity/contracts/sidechain/Keep3rHelperSidechain.sol index c60bf03..d1018ef 100644 --- a/solidity/contracts/sidechain/Keep3rHelperSidechain.sol +++ b/solidity/contracts/sidechain/Keep3rHelperSidechain.sol @@ -13,7 +13,7 @@ Coded for The Keep3r Network with ♥ by https://defi.sucks -Commit hash: ead559c8dc4361349b7222741c2399447e255d8e +Commit hash: b18e2940310077e04ec08b3026dc92e441fb08ef */ diff --git a/solidity/contracts/sidechain/Keep3rSidechain.sol b/solidity/contracts/sidechain/Keep3rSidechain.sol index 2b4930c..5226e4e 100644 --- a/solidity/contracts/sidechain/Keep3rSidechain.sol +++ b/solidity/contracts/sidechain/Keep3rSidechain.sol @@ -13,7 +13,7 @@ Coded for The Keep3r Network with ♥ by https://defi.sucks -Commit hash: ead559c8dc4361349b7222741c2399447e255d8e +Commit hash: b18e2940310077e04ec08b3026dc92e441fb08ef */ diff --git a/utils/constants.ts b/utils/constants.ts index 4fc178c..378f5a2 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -2,7 +2,8 @@ export const addressRegistry = { // TOKENS kp3rV1: { 1: '0x1ceb5cb57c4d4e2b2433641b95dd330a33185a44', // Keep3rV1 - 10: '0x3975e0292bEF3Fca8feF414f01E120652Ac60A69', // nextKP3R + 10: '0xca87472DBfB041c2e5a2672d319eA6184Ad9755e', // nextKP3R + 137: '0x4a2bE2075588BcE6A7E072574698a7DbbAc39b08', // nextKP3R 5: '0x16F63C5036d3F48A239358656a8f123eCE85789C', // KP3RforTest 420: '0x3Db593146464816F10d4eBA4743C76A5A4D08425', // wKP3RforTest 31337: '0x1ceb5cb57c4d4e2b2433641b95dd330a33185a44', @@ -10,6 +11,7 @@ export const addressRegistry = { weth: { 1: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', 10: '0x4200000000000000000000000000000000000006', + 137: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', 5: '0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6', 420: '0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6', 31337: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', @@ -20,7 +22,8 @@ export const addressRegistry = { 31337: '0x976b01c02c636Dd5901444B941442FD70b86dcd5', }, wkLP: { - 10: '0xAfe2Bbc98AF9fcFf73596Ebe1327B27d8A16d06b', // nextKLP + 10: '0xf232D1Afbed9Df3880143d4FAD095f3698c4d1c6', // nextKLP + 137: '0x7cf93c434260519537184631A347eE8AD0Bc68Cb', // nextKLP 420: '0xA437aC90d360c7645f25f30ddE201a94fe137Af5', // wkLP 31337: '0x1ceb5cb57c4d4e2b2433641b95dd330a33185a44', // kLP }, @@ -28,6 +31,7 @@ export const addressRegistry = { governor: { 1: '0x0D5Dc686d0a2ABBfDaFDFb4D0533E886517d4E83', 10: '0x7d6daDb31dBeBc68c8A0b2cCfE5C1f26F24bD41d', + 137: '0x9A040a31bc38919D50FD740973dBB6F8fdee1426', 5: 0, // deployer 420: 0, 31337: 0, @@ -35,18 +39,21 @@ export const addressRegistry = { // ORACLES kp3rWethOracle: { 1: '0x11b7a6bc0259ed6cf9db8f499988f9ecc7167bf5', // UniV3Pool - 10: '0x4Ab2c969C64302e5d931e5cEf4755392DC005604', // SidechainOracle + 10: '0x6A060BF6579318c15138160Ee1f1d225fcC9D409', // SidechainOracle + 137: '0x6A060BF6579318c15138160Ee1f1d225fcC9D409', // SidechainOracle 5: '0x317ceCd3eB02158f97DF0B67B788edCda4E066e5', // UniV3Pool 420: '0x4ECFF2c532d47D7be3D957E4a332AB134cad1fd9', // SidechainOracle 31337: '0x11b7a6bc0259ed6cf9db8f499988f9ecc7167bf5', }, wethUsdOracle: { 10: '0x03af20bdaaffb4cc0a521796a223f7d85e2aac31', // WETH-DAI 0.3% + 137: '0x45dda9cb7c25131df268515131f647d726f50608', // WETH-USDC 0.05% 420: '0x4ECFF2c532d47D7be3D957E4a332AB134cad1fd9', // SidechainOracle 31337: '0x60594a405d53811d3bc4766596efd80fd545a270', // UniV3Pool }, usdDecimals: { 10: '0x0000000000000000000000000000000000000012', // 18 + 137: '0x0000000000000000000000000000000000000006', // USDC uses 6 decimals 420: '0x0000000000000000000000000000000000000012', // 18 31337: '0x0000000000000000000000000000000000000012', // 18 },