{"id":13722381,"url":"https://github.com/yearn/strategies-keep3r","last_synced_at":"2025-05-07T15:30:35.921Z","repository":{"id":46166319,"uuid":"409247128","full_name":"yearn/strategies-keep3r","owner":"yearn","description":null,"archived":true,"fork":false,"pushed_at":"2021-11-09T19:35:14.000Z","size":3016,"stargazers_count":9,"open_issues_count":0,"forks_count":8,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-11-14T11:40:02.038Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yearn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-22T14:57:47.000Z","updated_at":"2024-04-22T11:03:06.000Z","dependencies_parsed_at":"2022-08-27T11:01:23.960Z","dependency_job_id":null,"html_url":"https://github.com/yearn/strategies-keep3r","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yearn%2Fstrategies-keep3r","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yearn%2Fstrategies-keep3r/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yearn%2Fstrategies-keep3r/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yearn%2Fstrategies-keep3r/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yearn","download_url":"https://codeload.github.com/yearn/strategies-keep3r/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252905516,"owners_count":21822819,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T01:01:28.039Z","updated_at":"2025-05-07T15:30:34.779Z","avatar_url":"https://github.com/yearn.png","language":"Solidity","funding_links":[],"categories":["Contracts"],"sub_categories":[],"readme":"# [DEPRECATED] Strategies Keep3r\n\nTHIS REPOSITORY HAS BEEN MOVED [HERE](https://github.com/yearn/hardhat-monorepo/tree/main/packages/strategies-keep3r)\n\n## Wishlist\n\n### Strategies\n\n- [x] [`CRV`](./contracts/keep3r/CrvStrategyKeep3r.sol) (`ycrv, busd, sbtc, 3pool, comp`)\n- [x] [`DForce`](./contracts/keep3r/DforceStrategyKeep3r.sol) (`usdt, usdc`)\n- [ ] (define next strats to keep3rfy)\n\n### Vaults\n\n- [x] [`yearn`](./contracts/keep3r/VaultKeep3r.sol) (`yCrv, busdCrv, sbtcCrv, 3poolCrv, compCrv`)\n- [ ] (add more vautls to yearn vault keep3r)\n- [ ] (define next vaults types to keep3rfy)\n\n## Scripts\n\n### Get available rewards and workable for CRV (ycrv, busd, sbtc, 3pool, comp) strategies.\n\n`npx hardhat run scripts/crv/01-crv-keep3r-calculate-harvest.js`\n\n### Get available rewards and workable for DForce (sdt, usdc) strategies.\n\n`npx hardhat run scripts/dforce/01-dforce-keep3r-calculate-harvest.js`\n\n### Get available earn and workable for yearn (yCrv, busdCrv, sbtcCrv, 3poolCrv, compCrv) vaults.\n\n`npx hardhat run scripts/vault/01-vault-keep3r-calculate-earn`\n\n## Contracts\n\n---\n\n\u003e keep3r\n\n### [`Keep3rAbstract.sol`](https://github.com/lbertenasco/contract-utils/blob/main/contracts/keep3r/Keep3rAbstract.sol)\n\nAbstract contract that should be used to extend from when creating StrategyKeep3rs (see [`CrvStrategyKeep3r.sol`](./contracts/keep3r/CrvStrategyKeep3r.sol))\n\n```sol\n  IKeep3rV1 public keep3r;\n  address public bond;\n  uint256 public minBond;\n  uint256 public earned;\n  uint256 public age;\n  constructor(address _keep3r) public\n  function _setKeep3r(address _keep3r) internal\n  function _setKeep3rRequirements(address _bond, uint256 _minBond, uint256 _earned, uint256 _age, bool _onlyEOA) internal\n  function _isKeeper() internal\n  modifier onlyKeeper()\n  modifier paysKeeper()\n  modifier paysKeeperAmount(uint256 _amount)\n  modifier paysKeeperCredit(address _credit, uint256 _amount)\n  modifier paysKeeperEth(uint256 _amount)\n```\n\n### [`MetaKeep3r.sol`](./contracts/keep3r/MetaKeep3r.sol)\n\n\u003e TODO\n\n### [`CrvStrategyKeep3r.sol`](./contracts/keep3r/CrvStrategyKeep3r.sol)\n\n\u003e [verified on etherscan](https://etherscan.io/address/0xd0aC37E3524F295D141d3839d5ed5F26A40b589D#code)\n\nYearn v1 CrvStrategies Keep3r for `ycrv`, `busd`, `sbtc`, `3pool` and `comp` vaults/strats.\n\n```sol\nmapping(address =\u003e uint256) public requiredHarvest;\nfunction isCrvStrategyKeep3r() external pure override returns (bool) { return true; }\n```\n\nGovernor (strategist) functions:\n\n```sol\nfunction addStrategy(address _strategy, uint256 _requiredHarvest) external override onlyGovernor;\nfunction updateRequiredHarvestAmount(address _strategy, uint256 _requiredHarvest) external override onlyGovernor;\nfunction removeStrategy(address _strategy) external override onlyGovernor;\nfunction setKeep3r(address _keep3r) external override onlyGovernor;\nfunction setKeep3rRequirements(address _bond, uint256 _minBond, uint256 _earned, uint256 _age, bool _onlyEOA) external override onlyGovernor;\n# safeguard that allows governor(strategist) to call harvest directly, not having to go through keep3r network.\nfunction forceHarvest(address _strategy) external override onlyGovernor;\n```\n\nKeep3r functions\n\n```sol\n# Called externally to get available strategies to do work for\nfunction strategies(address _strategy) public view override returns (address[] memory _strategies);\n# Called externally to get available harvest in CRV by strategy\nfunction calculateHarvest(address _strategy) public override returns (uint256 _amount);\n# returns true if available harvest is greater or equal than required harvest\nfunction workable(address _strategy) public override returns (bool);\n# pays keep3rs to call havest on crv strategies\nfunction harvest(address _strategy) external override onlyKeeper paysKeeper;\n```\n\n\u003e call `calculateHarvest` and `workable` functions with `callStatic` to avoid spending gas. (they can be pretty slow too)\n\n### [`DforceStrategyKeep3r.sol`](./contracts/keep3r/DforceStrategyKeep3r.sol)\n\n\u003e [verified on etherscan](https://etherscan.io/address/0x30084324619D9645019C3f2cb3a94611601a3078#code)\n\n\u003e Almost the same functions as `CrvStrategyKeep3r`.\n\n```sol\nEnumerableSet.AddressSet internal availableStrategies;\nmapping(address =\u003e uint256) public requiredHarvest;\nfunction isDforceStrategyKeep3r() external pure override returns (bool) { return true; }\n```\n\nKeep3r functions\n\n```sol\n# Called externally to get available strategies to do work for\nfunction strategies(address _strategy) public view override returns (address[] memory _strategies);\n# Called externally to get available harvest in DForce rewards by strategy\nfunction calculateHarvest(address _strategy) public view override returns (uint256 _amount);\n# returns true if available harvest is greater or equal than required harvest\nfunction workable(address _strategy) public view override returns (bool);\n# pays keep3rs to call havest on crv strategies\nfunction harvest(address _strategy) external override onlyKeeper paysKeeper;\n```\n\n### [`VaultKeep3r.sol`](./contracts/keep3r/VaultKeep3r.sol)\n\n\u003e [verified on etherscan](https://etherscan.io/address/0x054A87DdFdE3ccb5DDB03739375329BcC1b03203#code)\n\n```sol\nmapping(address =\u003e uint256) public requiredEarn;\nmapping(address =\u003e uint256) public lastEarnAt;\nuint256 earnCooldown;\nEnumerableSet.AddressSet internal availableVaults;\nfunction isVaultKeep3r() external pure override returns (bool) { return true; }\n```\n\nGovernor (strategist) functions:\n\n```sol\nfunction addVault(address _vault, uint256 _requiredEarn)\n  external\n  override\n  onlyGovernor;\n\nfunction updateRequiredEarnAmount(address _vault, uint256 _requiredEarn)\n  external\n  override\n  onlyGovernor;\n\nfunction removeVault(address _vault) external override onlyGovernor;\n\nfunction setEarnCooldown(uint256 _earnCooldown) external override onlyGovernor;\n\n```\n\nKeep3r functions\n\n```sol\n# Called externally to get available vaults to do work for\nfunction vaults(address _vault) public view override returns (address[] memory _vaults);\n# Called externally to get available earn in yearn by vault\nfunction calculateEarn(address _vault) public view override returns (uint256 _amount);\n# returns true if available earn is greater or equal than required earn and earnCooldown has elapsed\nfunction workable(address _vault) public view override returns (bool);\n# pays keep3rs to call havest on crv vaults\nfunction earn(address _vault) external override onlyKeeper paysKeeper;\n```\n\n---\n\n\u003e mock\n\n### [`MockStrategy.sol`](./contracts/mock/MockStrategy.sol)\n\n\u003e TODO\n\n### [`StrategyCurveYVoterProxyAbstract.sol`](./contracts/mock/StrategyCurveYVoterProxyAbstract.sol)\n\n\u003e TODO\n\n## Adding new StrategyKeep3rs\n\n- you can use [`CrvStrategyKeep3r.sol`](./contracts/keep3r/CrvStrategyKeep3r.sol) as a template\n\n- adapt neccesarry functionality fo fit strategy requirements\n\n- modify `calculateHarvest` function to get your strategy pending rewards correctly\n\n  - it's better to have both `workable` and `calculateHarvest` as `view` functions, `CrvStrategyKeep3r` is not a good example for this.\n    - \u003e it's not a view function since it has to call a crv state-modifiyng function to calculate rewards.\n    - \u003e check [`CrvStrategyKeep3r-test.js`](./test/CrvStrategyKeep3r-test.js) for details on how to handle calls to non-view `workable` functions.\n\n- make sure you have a `harvest` function that has the `paysKeeper` modifier.\n- make sure you have a `forceHarvest` function that has the `onlyGovernor` modifier.\n\n- also take into account that any `onlyStrategist` functions on the strategy will need an `onlyGovernor` proxy function on your keep3r\n  - i.e. if the strategy contract has a `configureStrategy(...) onlyStrategist || msg.sender == strategist` you'll need to create a ` configureStrategy(...) onlyGovernor` on your `StrategyKeep3r` contract to keep having access to that method.\n\n## Useful tips for Keep3r Scripts :)\n\n- call `strategies()` function with `callStatic` to get all available strategies, loop through them to check for work.\n- always call `workable(address _strategy)` function with `callStatic` to avoid spending gas. (they can be pretty slow too)\n- always call `harvest(address _strategy)` function with `callStatic` before sending the real TX to make sure you wont get a revert. (they can be pretty slow too)\n- on `VaultKeep3r` use `vaults()` and `earn(address _vault)`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyearn%2Fstrategies-keep3r","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyearn%2Fstrategies-keep3r","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyearn%2Fstrategies-keep3r/lists"}