UNPKG

@defi-wonderland/keep3r-v2

Version:

The Keep3r Network is a decentralized network for projects that need external devops, and for external teams to find keeper jobs

1,143 lines (1,142 loc) 47.6 kB
<!doctype html> <html lang="en"> <head> <title>Code coverage report for contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol</title> <meta charset="utf-8" /> <link rel="stylesheet" href="../../../prettify.css" /> <link rel="stylesheet" href="../../../base.css" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <style type='text/css'> .coverage-summary .sorter { background-image: url(../../../sort-arrow-sprite.png); } </style> </head> <body> <div class='wrapper'> <div class='pad1'> <h1> <a href="../../../index.html">all files</a> / <a href="index.html">contracts/peripherals/jobs/</a> Keep3rJobFundableLiquidity.sol </h1> <div class='clearfix'> <div class='fl pad1y space-right2'> <span class="strong">0% </span> <span class="quiet">Statements</span> <span class='fraction'>0/131</span> </div> <div class='fl pad1y space-right2'> <span class="strong">0% </span> <span class="quiet">Branches</span> <span class='fraction'>0/72</span> </div> <div class='fl pad1y space-right2'> <span class="strong">0% </span> <span class="quiet">Functions</span> <span class='fraction'>0/23</span> </div> <div class='fl pad1y space-right2'> <span class="strong">0% </span> <span class="quiet">Lines</span> <span class='fraction'>0/127</span> </div> </div> </div> <div class='status-line low'></div> <pre><table class="coverage"> <tr><td class="line-count quiet">1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360</td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">// SPDX-License-Identifier: MIT pragma solidity &gt;=0.8.4 &lt;0.9.0; &nbsp; import './Keep3rJobOwnership.sol'; import '../Keep3rAccountance.sol'; import '../Keep3rParameters.sol'; import '../../../interfaces/IPairManager.sol'; import '../../../interfaces/peripherals/IKeep3rJobs.sol'; &nbsp; import '../../libraries/FullMath.sol'; &nbsp; import '@openzeppelin/contracts/security/ReentrancyGuard.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import '@openzeppelin/contracts/utils/math/Math.sol'; &nbsp; abstract contract Keep3rJobFundableLiquidity is IKeep3rJobFundableLiquidity, ReentrancyGuard, Keep3rJobOwnership, Keep3rParameters { using EnumerableSet for EnumerableSet.AddressSet; using SafeERC20 for IERC20; &nbsp; /// @notice List of liquidities that are accepted in the system EnumerableSet.AddressSet internal _approvedLiquidities; &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity mapping(address =&gt; mapping(address =&gt; uint256)) public override liquidityAmount; &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity mapping(address =&gt; uint256) public override rewardedAt; &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity mapping(address =&gt; uint256) public override workedAt; &nbsp; /// @notice Tracks an address and returns its TickCache mapping(address =&gt; TickCache) internal _tick; &nbsp; // Views &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function approvedLiquidities() external view override returns (address[] memory _list) {</span> <span class="cstat-no" title="statement not covered" > _list = _approvedLiquidities.values()</span>; } &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function jobPeriodCredits(address _job) public view virtual override returns (uint256 _periodCredits) {</span> <span class="cstat-no" title="statement not covered" > for (uint256 i; i &lt; _jobLiquidities[_job].length(); i++) {</span> <span class="cstat-no" title="statement not covered" > address _liquidity = _jobLiquidities[_job].at(i);</span> <span class="cstat-no" title="statement not covered" > if (_approvedLiquidities.contains(_liquidity)) {</span> <span class="cstat-no" title="statement not covered" > TickCache memory _tickCache = observeLiquidity(_liquidity);</span> <span class="cstat-no" title="statement not covered" > if (_tickCache.period != 0) {</span> <span class="cstat-no" title="statement not covered" > int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;</span> <span class="cstat-no" title="statement not covered" > _periodCredits += _getReward(</span> IKeep3rHelper(keep3rHelper).getKP3RsAtTick(liquidityAmount[_job][_liquidity], _tickDifference, rewardPeriodTime) ); } } } } &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function jobLiquidityCredits(address _job) public view override returns (uint256 _liquidityCredits) {</span> <span class="cstat-no" title="statement not covered" > uint256 _periodCredits = jobPeriodCredits(_job);</span> &nbsp; // A job can have liquidityCredits without periodCredits (forced by Governance) <span class="cstat-no" title="statement not covered" > if (rewardedAt[_job] &gt; _period(block.timestamp - rewardPeriodTime)) {</span> // Will calculate job credits only if it was rewarded later than last period <span class="cstat-no" title="statement not covered" > if ((block.timestamp - rewardedAt[_job]) &gt;= rewardPeriodTime) {</span> // Will return a full period if job was rewarded more than a period ago <span class="cstat-no" title="statement not covered" > _liquidityCredits = _periodCredits</span>; } else { // Will update minted job credits (not forced) to new twaps if credits are outdated <span class="cstat-no" title="statement not covered" > _liquidityCredits = _periodCredits &gt; 0</span> ? (_jobLiquidityCredits[_job] * _periodCredits) / _jobPeriodCredits[_job] : _jobLiquidityCredits[_job]; } } else { // Will return a full period if job credits are expired <span class="cstat-no" title="statement not covered" > _liquidityCredits = _periodCredits</span>; } } &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function totalJobCredits(address _job) external view override returns (uint256 _credits) {</span> <span class="cstat-no" title="statement not covered" > uint256 _periodCredits = jobPeriodCredits(_job);</span> <span class="cstat-no" title="statement not covered" > uint256 _cooldown;</span> &nbsp; <span class="cstat-no" title="statement not covered" > if ((rewardedAt[_job] &gt; _period(block.timestamp - rewardPeriodTime))) {</span> // Will calculate cooldown if it outdated <span class="cstat-no" title="statement not covered" > if ((block.timestamp - rewardedAt[_job]) &gt;= rewardPeriodTime) {</span> // Will calculate cooldown from last reward reference in this period <span class="cstat-no" title="statement not covered" > _cooldown = block.timestamp - (rewardedAt[_job] + rewardPeriodTime)</span>; } else { // Will calculate cooldown from last reward timestamp <span class="cstat-no" title="statement not covered" > _cooldown = block.timestamp - rewardedAt[_job]</span>; } } else { // Will calculate cooldown from period start if expired <span class="cstat-no" title="statement not covered" > _cooldown = block.timestamp - _period(block.timestamp)</span>; } <span class="cstat-no" title="statement not covered" > _credits = jobLiquidityCredits(_job) + _phase(_cooldown, _periodCredits)</span>; } &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function quoteLiquidity(address _liquidity, uint256 _amount) external view virtual override returns (uint256 _periodCredits) {</span> <span class="cstat-no" title="statement not covered" > if (_approvedLiquidities.contains(_liquidity)) {</span> <span class="cstat-no" title="statement not covered" > TickCache memory _tickCache = observeLiquidity(_liquidity);</span> <span class="cstat-no" title="statement not covered" > if (_tickCache.period != 0) {</span> <span class="cstat-no" title="statement not covered" > int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tickCache.difference : -_tickCache.difference;</span> <span class="cstat-no" title="statement not covered" > return _getReward(IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime));</span> } } } &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function observeLiquidity(address _liquidity) public view virtual override returns (TickCache memory _tickCache) {</span> <span class="cstat-no" title="statement not covered" > if (_tick[_liquidity].period == _period(block.timestamp)) {</span> // Will return cached twaps if liquidity is updated <span class="cstat-no" title="statement not covered" > _tickCache = _tick[_liquidity]</span>; } else { <span class="cstat-no" title="statement not covered" > bool success;</span> <span class="cstat-no" title="statement not covered" > uint256 lastPeriod = _period(block.timestamp - rewardPeriodTime);</span> &nbsp; <span class="cstat-no" title="statement not covered" > if (_tick[_liquidity].period == lastPeriod) {</span> // Will only ask for current period accumulator if liquidity is outdated <span class="cstat-no" title="statement not covered" > uint32[] memory _secondsAgo = new uint32[](1);</span> <span class="cstat-no" title="statement not covered" > int56 previousTick = _tick[_liquidity].current;</span> &nbsp; <span class="cstat-no" title="statement not covered" > _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp))</span>; &nbsp; <span class="cstat-no" title="statement not covered" > (_tickCache.current, , success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo)</span>; &nbsp; <span class="cstat-no" title="statement not covered" > _tickCache.difference = _tickCache.current - previousTick</span>; } else <span class="cstat-no" title="statement not covered" >if (_tick[_liquidity].period &lt; lastPeriod) {</span> // Will ask for 2 accumulators if liquidity is expired <span class="cstat-no" title="statement not covered" > uint32[] memory _secondsAgo = new uint32[](2);</span> &nbsp; <span class="cstat-no" title="statement not covered" > _secondsAgo[0] = uint32(block.timestamp - _period(block.timestamp))</span>; <span class="cstat-no" title="statement not covered" > _secondsAgo[1] = uint32(block.timestamp - _period(block.timestamp) + rewardPeriodTime)</span>; &nbsp; <span class="cstat-no" title="statement not covered" > int56 _tickCumulative2;</span> <span class="cstat-no" title="statement not covered" > (_tickCache.current, _tickCumulative2, success) = IKeep3rHelper(keep3rHelper).observe(_liquidityPool[_liquidity], _secondsAgo)</span>; &nbsp; <span class="cstat-no" title="statement not covered" > _tickCache.difference = _tickCache.current - _tickCumulative2</span>; } <span class="cstat-no" title="statement not covered" > if (success) {</span> <span class="cstat-no" title="statement not covered" > _tickCache.period = _period(block.timestamp)</span>; } else { <span class="cstat-no" title="statement not covered" > _tickCache.period = 0</span>; } } } &nbsp; // Methods &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function forceLiquidityCreditsToJob(address _job, uint256 _amount) external override onlyGovernance {</span> <span class="cstat-no" title="statement not covered" > if (!_jobs.contains(_job)) revert JobUnavailable();</span> <span class="cstat-no" title="statement not covered" > _settleJobAccountance(_job)</span>; <span class="cstat-no" title="statement not covered" > _jobLiquidityCredits[_job] += _amount</span>; <span class="cstat-no" title="statement not covered" > emit LiquidityCreditsForced(_job, rewardedAt[_job], _jobLiquidityCredits[_job]);</span> } &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function approveLiquidity(address _liquidity) external virtual override onlyGovernance {</span> <span class="cstat-no" title="statement not covered" > if (!_approvedLiquidities.add(_liquidity)) revert LiquidityPairApproved();</span> <span class="cstat-no" title="statement not covered" > _liquidityPool[_liquidity] = IPairManager(_liquidity).pool()</span>; <span class="cstat-no" title="statement not covered" > _isKP3RToken0[_liquidity] = IKeep3rHelper(keep3rHelper).isKP3RToken0(_liquidityPool[_liquidity])</span>; <span class="cstat-no" title="statement not covered" > _tick[_liquidity] = observeLiquidity(_liquidity)</span>; <span class="cstat-no" title="statement not covered" > emit LiquidityApproval(_liquidity);</span> } &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function revokeLiquidity(address _liquidity) external override onlyGovernance {</span> <span class="cstat-no" title="statement not covered" > if (!_approvedLiquidities.remove(_liquidity)) revert LiquidityPairUnexistent();</span> <span class="cstat-no" title="statement not covered" > emit LiquidityRevocation(_liquidity);</span> } &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function addLiquidityToJob(</span> address _job, address _liquidity, uint256 _amount ) external override nonReentrant { <span class="cstat-no" title="statement not covered" > if (!_approvedLiquidities.contains(_liquidity)) revert LiquidityPairUnapproved();</span> <span class="cstat-no" title="statement not covered" > if (!_jobs.contains(_job)) revert JobUnavailable();</span> &nbsp; <span class="cstat-no" title="statement not covered" > _jobLiquidities[_job].add(_liquidity)</span>; &nbsp; <span class="cstat-no" title="statement not covered" > _settleJobAccountance(_job)</span>; &nbsp; <span class="cstat-no" title="statement not covered" > if (_quoteLiquidity(liquidityAmount[_job][_liquidity] + _amount, _liquidity) &lt; liquidityMinimum) revert JobLiquidityLessThanMin();</span> &nbsp; <span class="cstat-no" title="statement not covered" > emit LiquidityCreditsReward(_job, rewardedAt[_job], _jobLiquidityCredits[_job], _jobPeriodCredits[_job]);</span> &nbsp; <span class="cstat-no" title="statement not covered" > IERC20(_liquidity).safeTransferFrom(msg.sender, address(this), _amount)</span>; <span class="cstat-no" title="statement not covered" > liquidityAmount[_job][_liquidity] += _amount</span>; <span class="cstat-no" title="statement not covered" > _jobPeriodCredits[_job] += _getReward(_quoteLiquidity(_amount, _liquidity))</span>; <span class="cstat-no" title="statement not covered" > emit LiquidityAddition(_job, _liquidity, msg.sender, _amount);</span> } &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function unbondLiquidityFromJob(</span> address _job, address _liquidity, uint256 _amount ) external override onlyJobOwner(_job) { <span class="cstat-no" title="statement not covered" > canWithdrawAfter[_job][_liquidity] = block.timestamp + unbondTime</span>; <span class="cstat-no" title="statement not covered" > pendingUnbonds[_job][_liquidity] += _amount</span>; <span class="cstat-no" title="statement not covered" > _unbondLiquidityFromJob(_job, _liquidity, _amount)</span>; &nbsp; <span class="cstat-no" title="statement not covered" > uint256 _remainingLiquidity = liquidityAmount[_job][_liquidity];</span> <span class="cstat-no" title="statement not covered" > if (_remainingLiquidity &gt; 0 &amp;&amp; _quoteLiquidity(_remainingLiquidity, _liquidity) &lt; liquidityMinimum) revert JobLiquidityLessThanMin();</span> &nbsp; <span class="cstat-no" title="statement not covered" > emit Unbonding(_job, _liquidity, _amount);</span> } &nbsp; /// @inheritdoc IKeep3rJobFundableLiquidity <span class="fstat-no" title="function not covered" > function withdrawLiquidityFromJob(</span> address _job, address _liquidity, address _receiver ) external override onlyJobOwner(_job) { <span class="cstat-no" title="statement not covered" > if (_receiver == address(0)) revert ZeroAddress();</span> <span class="cstat-no" title="statement not covered" > if (canWithdrawAfter[_job][_liquidity] == 0) revert UnbondsUnexistent();</span> <span class="cstat-no" title="statement not covered" > if (canWithdrawAfter[_job][_liquidity] &gt;= block.timestamp) revert UnbondsLocked();</span> <span class="cstat-no" title="statement not covered" > if (disputes[_job]) revert Disputed();</span> &nbsp; <span class="cstat-no" title="statement not covered" > uint256 _amount = pendingUnbonds[_job][_liquidity];</span> <span class="cstat-no" title="statement not covered" > IERC20(_liquidity).safeTransfer(_receiver, _amount)</span>; <span class="cstat-no" title="statement not covered" > emit LiquidityWithdrawal(_job, _liquidity, _receiver, _amount);</span> &nbsp; <span class="cstat-no" title="statement not covered" > pendingUnbonds[_job][_liquidity] = 0</span>; } &nbsp; // Internal functions &nbsp; /// @notice Updates or rewards job liquidity credits depending on time since last job reward <span class="fstat-no" title="function not covered" > function _updateJobCreditsIfNeeded(address _job) internal returns (bool _rewarded) {</span> <span class="cstat-no" title="statement not covered" > if (rewardedAt[_job] &lt; _period(block.timestamp)) {</span> // Will exit function if job has been rewarded in current period <span class="cstat-no" title="statement not covered" > if (rewardedAt[_job] &lt;= _period(block.timestamp - rewardPeriodTime)) {</span> // Will reset job to period syncronicity if a full period passed without rewards <span class="cstat-no" title="statement not covered" > _updateJobPeriod(_job)</span>; <span class="cstat-no" title="statement not covered" > _jobLiquidityCredits[_job] = _jobPeriodCredits[_job]</span>; <span class="cstat-no" title="statement not covered" > rewardedAt[_job] = _period(block.timestamp)</span>; <span class="cstat-no" title="statement not covered" > _rewarded = true</span>; } else <span class="cstat-no" title="statement not covered" >if ((block.timestamp - rewardedAt[_job]) &gt;= rewardPeriodTime) {</span> // Will reset job's syncronicity if last reward was more than epoch ago <span class="cstat-no" title="statement not covered" > _updateJobPeriod(_job)</span>; <span class="cstat-no" title="statement not covered" > _jobLiquidityCredits[_job] = _jobPeriodCredits[_job]</span>; <span class="cstat-no" title="statement not covered" > rewardedAt[_job] += rewardPeriodTime</span>; <span class="cstat-no" title="statement not covered" > _rewarded = true</span>; } else <span class="cstat-no" title="statement not covered" >if (workedAt[_job] &lt; _period(block.timestamp)) {</span> // First keeper on period has to update job accountance to current twaps <span class="cstat-no" title="statement not covered" > uint256 previousPeriodCredits = _jobPeriodCredits[_job];</span> <span class="cstat-no" title="statement not covered" > _updateJobPeriod(_job)</span>; <span class="cstat-no" title="statement not covered" > _jobLiquidityCredits[_job] = (_jobLiquidityCredits[_job] * _jobPeriodCredits[_job]) / previousPeriodCredits</span>; // Updating job accountance does not reward job } } } &nbsp; /// @notice Only called if _jobLiquidityCredits &lt; payment <span class="fstat-no" title="function not covered" > function _rewardJobCredits(address _job) internal {</span> /// @notice Only way to += jobLiquidityCredits is when keeper rewarding (cannot pay work) /* WARNING: this allows to top up _jobLiquidityCredits to a max of 1.99 but have to spend at least 1 */ <span class="cstat-no" title="statement not covered" > _jobLiquidityCredits[_job] += _phase(block.timestamp - rewardedAt[_job], _jobPeriodCredits[_job])</span>; <span class="cstat-no" title="statement not covered" > rewardedAt[_job] = block.timestamp</span>; } &nbsp; /// @notice Updates accountance for _jobPeriodCredits <span class="fstat-no" title="function not covered" > function _updateJobPeriod(address _job) internal {</span> <span class="cstat-no" title="statement not covered" > _jobPeriodCredits[_job] = _calculateJobPeriodCredits(_job)</span>; } &nbsp; /// @notice Quotes the outdated job liquidities and calculates _periodCredits /// @dev This function is also responsible for keeping the KP3R/WETH quote updated <span class="fstat-no" title="function not covered" > function _calculateJobPeriodCredits(address _job) internal virtual returns (uint256 _periodCredits) {</span> <span class="cstat-no" title="statement not covered" > if (_tick[kp3rWethPool].period != _period(block.timestamp)) {</span> // Updates KP3R/WETH quote if needed <span class="cstat-no" title="statement not covered" > _tick[kp3rWethPool] = observeLiquidity(kp3rWethPool)</span>; } &nbsp; <span class="cstat-no" title="statement not covered" > for (uint256 i; i &lt; _jobLiquidities[_job].length(); i++) {</span> <span class="cstat-no" title="statement not covered" > address _liquidity = _jobLiquidities[_job].at(i);</span> <span class="cstat-no" title="statement not covered" > if (_approvedLiquidities.contains(_liquidity)) {</span> <span class="cstat-no" title="statement not covered" > if (_tick[_liquidity].period != _period(block.timestamp)) {</span> // Updates liquidity cache only if needed <span class="cstat-no" title="statement not covered" > _tick[_liquidity] = observeLiquidity(_liquidity)</span>; } <span class="cstat-no" title="statement not covered" > _periodCredits += _getReward(_quoteLiquidity(liquidityAmount[_job][_liquidity], _liquidity))</span>; } } } &nbsp; /// @notice Updates job accountance calculating the impact of the unbonded liquidity amount <span class="fstat-no" title="function not covered" > function _unbondLiquidityFromJob(</span> address _job, address _liquidity, uint256 _amount ) internal nonReentrant { <span class="cstat-no" title="statement not covered" > if (!_jobLiquidities[_job].contains(_liquidity)) revert JobLiquidityUnexistent();</span> <span class="cstat-no" title="statement not covered" > if (liquidityAmount[_job][_liquidity] &lt; _amount) revert JobLiquidityInsufficient();</span> &nbsp; // Ensures current twaps in job liquidities <span class="cstat-no" title="statement not covered" > _updateJobPeriod(_job)</span>; <span class="cstat-no" title="statement not covered" > uint256 _periodCreditsToRemove = _getReward(_quoteLiquidity(_amount, _liquidity));</span> &nbsp; // A liquidity can be revoked causing a job to have 0 periodCredits <span class="cstat-no" title="statement not covered" > if (_jobPeriodCredits[_job] &gt; 0) {</span> // Removes a % correspondant to a full rewardPeriodTime for the liquidity withdrawn vs all of the liquidities <span class="cstat-no" title="statement not covered" > _jobLiquidityCredits[_job] -= (_jobLiquidityCredits[_job] * _periodCreditsToRemove) / _jobPeriodCredits[_job]</span>; <span class="cstat-no" title="statement not covered" > _jobPeriodCredits[_job] -= _periodCreditsToRemove</span>; } &nbsp; <span class="cstat-no" title="statement not covered" > liquidityAmount[_job][_liquidity] -= _amount</span>; <span class="cstat-no" title="statement not covered" > if (liquidityAmount[_job][_liquidity] == 0) {</span> <span class="cstat-no" title="statement not covered" > _jobLiquidities[_job].remove(_liquidity)</span>; } } &nbsp; /// @notice Returns a fraction of the multiplier or the whole multiplier if equal or more than a rewardPeriodTime has passed <span class="fstat-no" title="function not covered" > function _phase(uint256 _timePassed, uint256 _multiplier) internal view returns (uint256 _result) {</span> <span class="cstat-no" title="statement not covered" > if (_timePassed &lt; rewardPeriodTime) {</span> <span class="cstat-no" title="statement not covered" > _result = (_timePassed * _multiplier) / rewardPeriodTime</span>; } else <span class="cstat-no" title="statement not covered" >_result = _multiplier</span>; } &nbsp; /// @notice Returns the start of the period of the provided timestamp <span class="fstat-no" title="function not covered" > function _period(uint256 _timestamp) internal view returns (uint256 _periodTimestamp) {</span> <span class="cstat-no" title="statement not covered" > return _timestamp - (_timestamp % rewardPeriodTime);</span> } &nbsp; /// @notice Calculates relation between rewardPeriod and inflationPeriod <span class="fstat-no" title="function not covered" > function _getReward(uint256 _baseAmount) internal view returns (uint256 _credits) {</span> <span class="cstat-no" title="statement not covered" > return FullMath.mulDiv(_baseAmount, rewardPeriodTime, inflationPeriod);</span> } &nbsp; /// @notice Returns underlying KP3R amount for a given liquidity amount <span class="fstat-no" title="function not covered" > function _quoteLiquidity(uint256 _amount, address _liquidity) internal view virtual returns (uint256 _quote) {</span> <span class="cstat-no" title="statement not covered" > if (_tick[_liquidity].period != 0) {</span> <span class="cstat-no" title="statement not covered" > int56 _tickDifference = _isKP3RToken0[_liquidity] ? _tick[_liquidity].difference : -_tick[_liquidity].difference;</span> <span class="cstat-no" title="statement not covered" > _quote = IKeep3rHelper(keep3rHelper).getKP3RsAtTick(_amount, _tickDifference, rewardPeriodTime)</span>; } } &nbsp; /// @notice Returns KP3R amount for a given ETH amount <span class="fstat-no" title="function not covered" > function _quoteKp3rs(uint256 _eth) internal view virtual returns (uint256 _amountOut) {</span> <span class="cstat-no" title="statement not covered" > int56 _tickDifference = _isKP3RToken0[kp3rWethPool] ? _tick[kp3rWethPool].difference : -_tick[kp3rWethPool].difference;</span> <span class="cstat-no" title="statement not covered" > _amountOut = IKeep3rHelper(keep3rHelper).getQuoteAtTick(uint128(_eth), _tickDifference, rewardPeriodTime)</span>; } &nbsp; /// @notice Updates job credits to current quotes and rewards job's pending minted credits /// @dev Ensures a maximum of 1 period of credits <span class="fstat-no" title="function not covered" > function _settleJobAccountance(address _job) internal virtual {</span> <span class="cstat-no" title="statement not covered" > _updateJobCreditsIfNeeded(_job)</span>; <span class="cstat-no" title="statement not covered" > _rewardJobCredits(_job)</span>; <span class="cstat-no" title="statement not covered" > _jobLiquidityCredits[_job] = Math.min(_jobLiquidityCredits[_job], _jobPeriodCredits[_job])</span>; } } &nbsp;</pre></td></tr> </table></pre> <div class='push'></div><!-- for sticky footer --> </div><!-- /wrapper --> <div class='footer quiet pad2 space-top1 center small'> Code coverage generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Fri May 20 2022 12:16:04 GMT+0200 (Central European Summer Time) </div> </div> <script src="../../../prettify.js"></script> <script> window.onload = function () { if (typeof prettyPrint === 'function') { prettyPrint(); } }; </script> <script src="../../../sorter.js"></script> </body> </html>