Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 3,219 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Set Pending Gove... | 17461526 | 991 days ago | IN | 0 ETH | 0.00091504 | ||||
| Remove Strategy | 13124677 | 1642 days ago | IN | 0 ETH | 0.0020827 | ||||
| Remove Strategy | 13124677 | 1642 days ago | IN | 0 ETH | 0.0020827 | ||||
| Remove Strategy | 13124677 | 1642 days ago | IN | 0 ETH | 0.0020827 | ||||
| Remove Strategy | 13124677 | 1642 days ago | IN | 0 ETH | 0.00252341 | ||||
| Remove Strategy | 13124677 | 1642 days ago | IN | 0 ETH | 0.00252341 | ||||
| Work For Tokens | 13122092 | 1643 days ago | IN | 0 ETH | 0.20747194 | ||||
| Work For Tokens | 13119495 | 1643 days ago | IN | 0 ETH | 0.09316936 | ||||
| Work For Tokens | 13117112 | 1644 days ago | IN | 0 ETH | 0.1007854 | ||||
| Work For Tokens | 13111721 | 1644 days ago | IN | 0 ETH | 0.07782628 | ||||
| Work For Tokens | 13109169 | 1645 days ago | IN | 0 ETH | 0.26236493 | ||||
| Work For Tokens | 13107034 | 1645 days ago | IN | 0 ETH | 0.11483128 | ||||
| Work For Tokens | 13106638 | 1645 days ago | IN | 0 ETH | 0.0974216 | ||||
| Work For Tokens | 13104216 | 1646 days ago | IN | 0 ETH | 0.13913071 | ||||
| Work For Tokens | 13102210 | 1646 days ago | IN | 0 ETH | 0.18017062 | ||||
| Remove Strategy | 13101591 | 1646 days ago | IN | 0 ETH | 0.00393381 | ||||
| Work For Tokens | 13101268 | 1646 days ago | IN | 0 ETH | 0.07546929 | ||||
| Work For Tokens | 13098817 | 1646 days ago | IN | 0 ETH | 0.06802637 | ||||
| Work For Tokens | 13096216 | 1647 days ago | IN | 0 ETH | 0.28416274 | ||||
| Work For Tokens | 13091275 | 1648 days ago | IN | 0 ETH | 0.10266092 | ||||
| Work For Tokens | 13090036 | 1648 days ago | IN | 0 ETH | 0.12546577 | ||||
| Work For Tokens | 13089316 | 1648 days ago | IN | 0 ETH | 0.17732165 | ||||
| Work For Tokens | 13088309 | 1648 days ago | IN | 0 ETH | 0.09411507 | ||||
| Work For Tokens | 13087564 | 1648 days ago | IN | 0 ETH | 0.04924808 | ||||
| Work For Tokens | 13085826 | 1648 days ago | IN | 0 ETH | 0.09797026 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
CrvStrategyKeep3rJob2
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@lbertenasco/contract-utils/contracts/abstract/MachineryReady.sol";
import "@lbertenasco/contract-utils/contracts/keep3r/Keep3rAbstract.sol";
import "../interfaces/jobs/ICrvStrategyKeep3rJob.sol";
import "../interfaces/jobs/ICrvStrategyKeep3rJobV2.sol";
import "../interfaces/jobs/v2/IV2Keeper.sol";
import "../interfaces/keep3r/IKeep3rEscrow.sol";
import "../interfaces/yearn/IV1Controller.sol";
import "../interfaces/yearn/IV1Vault.sol";
import "../interfaces/yearn/IBaseStrategy.sol";
import "../interfaces/crv/ICrvStrategy.sol";
import "../interfaces/crv/ICrvClaimable.sol";
contract CrvStrategyKeep3rJob2 is MachineryReady, Keep3r, ICrvStrategyKeep3rJob, ICrvStrategyKeep3rJobV2 {
using SafeMath for uint256;
uint256 public constant PRECISION = 1_000;
uint256 public constant MAX_REWARD_MULTIPLIER = 1 * PRECISION; // 1x max reward multiplier
uint256 public override rewardMultiplier = MAX_REWARD_MULTIPLIER;
mapping(address => uint256) public override requiredHarvest;
mapping(address => uint256) public override requiredEarn;
mapping(address => uint256) public override lastWorkAt;
mapping(address => bool) public override strategyIsV1;
uint256 public override maxHarvestPeriod;
uint256 public override lastHarvest;
uint256 public override harvestCooldown;
EnumerableSet.AddressSet internal _availableStrategies;
// v2 specific
address public override v2Keeper;
constructor(
address _mechanicsRegistry,
address _keep3r,
address _bond,
uint256 _minBond,
uint256 _earned,
uint256 _age,
bool _onlyEOA,
uint256 _maxHarvestPeriod,
uint256 _harvestCooldown,
address _v2Keeper
) public MachineryReady(_mechanicsRegistry) Keep3r(_keep3r) {
_setKeep3rRequirements(_bond, _minBond, _earned, _age, _onlyEOA);
_setMaxHarvestPeriod(_maxHarvestPeriod);
_setHarvestCooldown(_harvestCooldown);
v2Keeper = _v2Keeper;
}
// Keep3r Setters
function setKeep3r(address _keep3r) external override onlyGovernor {
_setKeep3r(_keep3r);
}
function setKeep3rRequirements(
address _bond,
uint256 _minBond,
uint256 _earned,
uint256 _age,
bool _onlyEOA
) external override onlyGovernor {
_setKeep3rRequirements(_bond, _minBond, _earned, _age, _onlyEOA);
}
function setV2Keep3r(address _v2Keeper) external override onlyGovernor {
v2Keeper = _v2Keeper;
}
function setRewardMultiplier(uint256 _rewardMultiplier) external override onlyGovernorOrMechanic {
_setRewardMultiplier(_rewardMultiplier);
emit SetRewardMultiplier(_rewardMultiplier);
}
function _setRewardMultiplier(uint256 _rewardMultiplier) internal {
require(_rewardMultiplier <= MAX_REWARD_MULTIPLIER, "CrvStrategyKeep3rJob::set-reward-multiplier:multiplier-exceeds-max");
rewardMultiplier = _rewardMultiplier;
}
// Setters
function addStrategies(
address[] calldata _strategies,
uint256[] calldata _requiredHarvests,
uint256[] calldata _requiredEarns
) external override onlyGovernorOrMechanic {
require(
_strategies.length == _requiredHarvests.length && _strategies.length == _requiredEarns.length,
"CrvStrategyKeep3rJob::add-strategies:strategies-required-harvests-and-earns-different-length"
);
for (uint256 i; i < _strategies.length; i++) {
_addStrategy(_strategies[i], _requiredHarvests[i], _requiredEarns[i]);
}
}
function addStrategy(
address _strategy,
uint256 _requiredHarvest,
uint256 _requiredEarn
) external override onlyGovernorOrMechanic {
_addStrategy(_strategy, _requiredHarvest, _requiredEarn);
}
function _addStrategy(
address _strategy,
uint256 _requiredHarvest,
uint256 _requiredEarn
) internal {
require(requiredHarvest[_strategy] == 0, "CrvStrategyKeep3rJob::add-strategy:strategy-already-added");
_setRequiredHarvest(_strategy, _requiredHarvest);
_setRequiredEarn(_strategy, _requiredEarn);
_availableStrategies.add(_strategy);
lastWorkAt[_strategy] = block.timestamp;
emit StrategyAdded(_strategy, _requiredHarvest, _requiredEarn);
}
function updateStrategies(
address[] calldata _strategies,
uint256[] calldata _requiredHarvests,
uint256[] calldata _requiredEarns
) external override onlyGovernorOrMechanic {
require(
_strategies.length == _requiredHarvests.length && _strategies.length == _requiredEarns.length,
"CrvStrategyKeep3rJob::update-strategies:strategies-required-harvests-and-earns-different-length"
);
for (uint256 i; i < _strategies.length; i++) {
_updateStrategy(_strategies[i], _requiredHarvests[i], _requiredEarns[i]);
}
}
function updateStrategy(
address _strategy,
uint256 _requiredHarvest,
uint256 _requiredEarn
) external override onlyGovernorOrMechanic {
_updateStrategy(_strategy, _requiredHarvest, _requiredEarn);
}
function _updateStrategy(
address _strategy,
uint256 _requiredHarvest,
uint256 _requiredEarn
) internal {
require(requiredHarvest[_strategy] > 0, "CrvStrategyKeep3rJob::update-required-harvest:strategy-not-added");
_setRequiredHarvest(_strategy, _requiredHarvest);
_setRequiredEarn(_strategy, _requiredEarn);
emit StrategyModified(_strategy, _requiredHarvest, _requiredEarn);
}
function removeStrategy(address _strategy) external override onlyGovernorOrMechanic {
require(requiredHarvest[_strategy] > 0, "CrvStrategyKeep3rJob::remove-strategy:strategy-not-added");
requiredHarvest[_strategy] = 0;
_availableStrategies.remove(_strategy);
emit StrategyRemoved(_strategy);
}
function _setRequiredHarvest(address _strategy, uint256 _requiredHarvest) internal {
require(_requiredHarvest > 0, "CrvStrategyKeep3rJob::set-required-harvest:should-not-be-zero");
requiredHarvest[_strategy] = _requiredHarvest;
}
function _setRequiredEarn(address _strategy, uint256 _requiredEarn) internal {
require(_requiredEarn > 0, "CrvStrategyKeep3rJob::set-required-earn:should-not-be-zero");
try ICrvStrategy(_strategy).controller() {
strategyIsV1[_strategy] = true;
} catch {}
requiredEarn[_strategy] = _requiredEarn;
}
function setMaxHarvestPeriod(uint256 _maxHarvestPeriod) external override onlyGovernorOrMechanic {
_setMaxHarvestPeriod(_maxHarvestPeriod);
}
function _setMaxHarvestPeriod(uint256 _maxHarvestPeriod) internal {
require(_maxHarvestPeriod > 0, "CrvStrategyKeep3rJob::set-max-harvest-period:should-not-be-zero");
maxHarvestPeriod = _maxHarvestPeriod;
}
function setHarvestCooldown(uint256 _harvestCooldown) external override onlyGovernorOrMechanic {
_setHarvestCooldown(_harvestCooldown);
}
function _setHarvestCooldown(uint256 _harvestCooldown) internal {
harvestCooldown = _harvestCooldown;
}
// Getters
function strategies() public view override returns (address[] memory _strategies) {
_strategies = new address[](_availableStrategies.length());
for (uint256 i; i < _availableStrategies.length(); i++) {
_strategies[i] = _availableStrategies.at(i);
}
}
// Keeper view actions
function calculateHarvest(address _strategy) public override returns (uint256 _amount) {
require(requiredHarvest[_strategy] > 0, "CrvStrategyKeep3rJob::calculate-harvest:strategy-not-added");
address _gauge = ICrvStrategy(_strategy).gauge();
address _voter = ICrvStrategy(_strategy).voter();
return ICrvClaimable(_gauge).claimable_tokens(_voter);
}
function workable(address _strategy) external override notPaused returns (bool) {
return _workable(_strategy);
}
function _workable(address _strategy) internal returns (bool) {
require(requiredHarvest[_strategy] > 0, "CrvStrategyKeep3rJob::workable:strategy-not-added");
// ensures no other strategy has been harvested for at least the harvestCooldown
if (block.timestamp < lastHarvest.add(harvestCooldown)) return false;
// if strategy has exceeded maxHarvestPeriod, force workable true
if (block.timestamp > lastWorkAt[_strategy].add(maxHarvestPeriod)) return true;
// if V2, check harvestTrigger for "earn"
if (!strategyIsV1[_strategy] && IBaseStrategy(_strategy).harvestTrigger(requiredEarn[_strategy])) return true;
return calculateHarvest(_strategy) >= requiredHarvest[_strategy];
}
// Keeper actions
function _work(address _strategy, bool _workForTokens) internal returns (uint256 _credits) {
uint256 _initialGas = gasleft();
require(_workable(_strategy), "CrvStrategyKeep3rJob::harvest:not-workable");
_workInternal(_strategy);
_credits = _calculateCredits(_initialGas);
emit Worked(_strategy, msg.sender, _credits, _workForTokens);
}
function _workInternal(address _strategy) internal {
if (strategyIsV1[_strategy]) {
_workV1(_strategy);
} else {
_workV2(_strategy);
}
_postWork(_strategy);
}
function _workV1(address _strategy) internal {
// Checks if vault has enough available amount to earn
address controller = ICrvStrategy(_strategy).controller();
address want = ICrvStrategy(_strategy).want();
address vault = IV1Controller(controller).vaults(want);
uint256 available = IV1Vault(vault).available();
if (available >= requiredEarn[_strategy]) {
IV1Vault(vault).earn();
}
ICrvStrategy(_strategy).harvest();
}
function _workV2(address _strategy) internal {
IV2Keeper(v2Keeper).harvest(_strategy);
}
function work(address _strategy) external override returns (uint256 _credits) {
return workForBond(_strategy);
}
function workForBond(address _strategy) public override notPaused onlyKeeper returns (uint256 _credits) {
_credits = _work(_strategy, false);
_paysKeeperAmount(msg.sender, _credits);
}
function workForTokens(address _strategy) external override notPaused onlyKeeper returns (uint256 _credits) {
_credits = _work(_strategy, true);
_paysKeeperInTokens(msg.sender, _credits);
}
function _calculateCredits(uint256 _initialGas) internal view returns (uint256 _credits) {
// Gets default credits from KP3R_Helper and applies job reward multiplier
return _getQuoteLimitFor(msg.sender, _initialGas).mul(rewardMultiplier).div(PRECISION);
}
// Mechanics keeper bypass
function forceWork(address _strategy) external override onlyGovernorOrMechanic {
_workInternal(_strategy);
emit ForceWorked(_strategy);
}
function _postWork(address _strategy) internal {
lastWorkAt[_strategy] = block.timestamp;
lastHarvest = block.timestamp;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import './UtilsReady.sol';
import '../utils/Machinery.sol';
abstract
contract MachineryReady is UtilsReady, Machinery {
constructor(address _mechanicsRegistry) public Machinery(_mechanicsRegistry) UtilsReady() {
}
// Machinery: restricted-access
function setMechanicsRegistry(address _mechanicsRegistry) external override onlyGovernor {
_setMechanicsRegistry(_mechanicsRegistry);
}
// Machinery: modifiers
modifier onlyGovernorOrMechanic() {
require(isGovernor(msg.sender) || isMechanic(msg.sender), "Machinery::onlyGovernorOrMechanic:invalid-msg-sender");
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import '@openzeppelin/contracts/math/SafeMath.sol';
import '../../interfaces/keep3r/IKeep3rV1.sol';
import '../../interfaces/keep3r/IKeep3r.sol';
abstract
contract Keep3r is IKeep3r {
using SafeMath for uint256;
IKeep3rV1 internal _Keep3r;
address public override bond;
uint256 public override minBond;
uint256 public override earned;
uint256 public override age;
bool public override onlyEOA;
constructor(address _keep3r) public {
_setKeep3r(_keep3r);
}
// Setters
function _setKeep3r(address _keep3r) internal {
_Keep3r = IKeep3rV1(_keep3r);
emit Keep3rSet(_keep3r);
}
function _setKeep3rRequirements(address _bond, uint256 _minBond, uint256 _earned, uint256 _age, bool _onlyEOA) internal {
bond = _bond;
minBond = _minBond;
earned = _earned;
age = _age;
onlyEOA = _onlyEOA;
emit Keep3rRequirementsSet(_bond, _minBond, _earned, _age, _onlyEOA);
}
// Modifiers
// Only checks if caller is a valid keeper, payment should be handled manually
modifier onlyKeeper() {
_isKeeper();
_;
}
// view
function keep3r() external view override returns (address _keep3r) {
return address(_Keep3r);
}
// handles default payment after execution
modifier paysKeeper() {
_;
_paysKeeper(msg.sender);
}
// Internal helpers
function _isKeeper() internal {
if (onlyEOA) require(msg.sender == tx.origin, "keep3r::isKeeper:keeper-is-not-eoa");
if (minBond == 0 && earned == 0 && age == 0) {
// If no custom keeper requirements are set, just evaluate if sender is a registered keeper
require(_Keep3r.isKeeper(msg.sender), "keep3r::isKeeper:keeper-is-not-registered");
} else {
if (bond == address(0)) {
// Checks for min KP3R, earned and age.
require(_Keep3r.isMinKeeper(msg.sender, minBond, earned, age), "keep3r::isKeeper:keeper-not-min-requirements");
} else {
// Checks for min custom-bond, earned and age.
require(_Keep3r.isBondedKeeper(msg.sender, bond, minBond, earned, age), "keep3r::isKeeper:keeper-not-custom-min-requirements");
}
}
}
function _getQuoteLimitFor(address _for, uint256 _initialGas) internal view returns (uint256 _credits) {
return _Keep3r.KPRH().getQuoteLimitFor(_for, _initialGas.sub(gasleft()));
}
// pays in bonded KP3R after execution
function _paysKeeper(address _keeper) internal {
_Keep3r.worked(_keeper);
}
// pays _amount in KP3R after execution
function _paysKeeperInTokens(address _keeper, uint256 _amount) internal {
_Keep3r.receipt(address(_Keep3r), _keeper, _amount);
}
// pays _amount in bonded KP3R after execution
function _paysKeeperAmount(address _keeper, uint256 _amount) internal {
_Keep3r.workReceipt(_keeper, _amount);
}
// pays _amount in _credit after execution
function _paysKeeperCredit(address _credit, address _keeper, uint256 _amount) internal {
_Keep3r.receipt(_credit, _keeper, _amount);
}
// pays _amount in ETH after execution
function _paysKeeperEth(address _keeper, uint256 _amount) internal {
_Keep3r.receiptETH(_keeper, _amount);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "./IKeep3rJob.sol";
interface ICrvStrategyKeep3rJob is IKeep3rJob {
event StrategyAdded(address _strategy, uint256 _requiredHarvest, uint256 _requiredEarn);
event StrategyModified(address _strategy, uint256 _requiredHarvest, uint256 _requiredEarn);
event StrategyRemoved(address _strategy);
// Actions by Keeper
event Worked(address _strategy, address _keeper, uint256 _credits, bool _workForTokens);
// Actions forced by governor
event ForceWorked(address _strategy);
// Setters
function addStrategies(
address[] calldata _strategies,
uint256[] calldata _requiredHarvests,
uint256[] calldata _requiredEarns
) external;
function addStrategy(
address _strategy,
uint256 _requiredHarvest,
uint256 _requiredEarn
) external;
function updateStrategies(
address[] calldata _strategies,
uint256[] calldata _requiredHarvests,
uint256[] calldata _requiredEarns
) external;
function updateStrategy(
address _strategy,
uint256 _requiredHarvest,
uint256 _requiredEarn
) external;
function removeStrategy(address _strategy) external;
function setMaxHarvestPeriod(uint256 _maxHarvestPeriod) external;
function setHarvestCooldown(uint256 _harvestCooldown) external;
// Getters
function strategies() external view returns (address[] memory _strategies);
function workable(address _strategy) external returns (bool);
function requiredHarvest(address _strategy) external view returns (uint256 _requiredHarvest);
function requiredEarn(address _strategy) external view returns (uint256 _requiredEarn);
function lastWorkAt(address _strategy) external view returns (uint256 _lastWorkAt);
function maxHarvestPeriod() external view returns (uint256 _maxHarvestPeriod);
function lastHarvest() external view returns (uint256 _lastHarvest);
function harvestCooldown() external view returns (uint256 _harvestCooldown);
function calculateHarvest(address _strategy) external returns (uint256 _amount);
// Keeper actions
function work(address _strategy) external returns (uint256 _credits);
function workForBond(address _strategy) external returns (uint256 _credits);
function workForTokens(address _strategy) external returns (uint256 _credits);
// Mechanics keeper bypass
function forceWork(address _strategy) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface ICrvStrategyKeep3rJobV2 {
function v2Keeper() external view returns (address _v2Keeper);
function strategyIsV1(address _strategy) external view returns (bool);
function setV2Keep3r(address _v2Keeper) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.8;
interface IV2Keeper {
// Getters
function jobs() external view returns (address[] memory);
event JobAdded(address _job);
event JobRemoved(address _job);
// Setters
function addJobs(address[] calldata _jobs) external;
function addJob(address _job) external;
function removeJob(address _job) external;
// Jobs actions
function tend(address _strategy) external;
function harvest(address _strategy) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "@lbertenasco/contract-utils/interfaces/abstract/IUtilsReady.sol";
interface IKeep3rEscrow is IUtilsReady {
function returnLPsToGovernance() external;
function addLiquidityToJob(
address liquidity,
address job,
uint256 amount
) external;
function applyCreditToJob(
address provider,
address liquidity,
address job
) external;
function unbondLiquidityFromJob(
address liquidity,
address job,
uint256 amount
) external;
function removeLiquidityFromJob(address liquidity, address job) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IV1Controller {
function stretegies(address _want) external view returns (address _strategy);
function vaults(address _want) external view returns (address _vault);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IV1Vault {
function token() external view returns (address);
function underlying() external view returns (address);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function controller() external view returns (address);
function governance() external view returns (address);
function getPricePerFullShare() external view returns (uint256);
function available() external view returns (uint256);
function earn() external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IBaseStrategy {
function vault() external view returns (address _vault);
function strategist() external view returns (address _strategist);
function rewards() external view returns (address _rewards);
function keeper() external view returns (address _keeper);
function want() external view returns (address _want);
function name() external view returns (string memory _name);
// Setters
function setStrategist(address _strategist) external;
function setKeeper(address _keeper) external;
function setRewards(address _rewards) external;
function tendTrigger(uint256 callCost) external view returns (bool);
function tend() external;
function harvestTrigger(uint256 callCost) external view returns (bool);
function harvest() external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "./../yearn/IHarvestableStrategy.sol";
interface ICrvStrategy is IHarvestableStrategy {
function gauge() external pure returns (address);
function voter() external pure returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface ICrvClaimable {
function claimable_tokens(address _address) external returns (uint256 _amount);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import '../utils/Governable.sol';
import '../utils/CollectableDust.sol';
import '../utils/Pausable.sol';
abstract
contract UtilsReady is Governable, CollectableDust, Pausable {
constructor() public Governable(msg.sender) {
}
// Governable: restricted-access
function setPendingGovernor(address _pendingGovernor) external override onlyGovernor {
_setPendingGovernor(_pendingGovernor);
}
function acceptGovernor() external override onlyPendingGovernor {
_acceptGovernor();
}
// Collectable Dust: restricted-access
function sendDust(
address _to,
address _token,
uint256 _amount
) external override virtual onlyGovernor {
_sendDust(_to, _token, _amount);
}
// Pausable: restricted-access
function pause(bool _paused) external override onlyGovernor {
_pause(_paused);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "@openzeppelin/contracts/utils/EnumerableSet.sol";
import '../../interfaces/utils/IMachinery.sol';
import '../../interfaces/mechanics/IMechanicsRegistry.sol';
abstract
contract Machinery is IMachinery {
using EnumerableSet for EnumerableSet.AddressSet;
IMechanicsRegistry internal MechanicsRegistry;
constructor(address _mechanicsRegistry) public {
_setMechanicsRegistry(_mechanicsRegistry);
}
function _setMechanicsRegistry(address _mechanicsRegistry) internal {
MechanicsRegistry = IMechanicsRegistry(_mechanicsRegistry);
}
// View helpers
function mechanicsRegistry() external view override returns (address _mechanicRegistry) {
return address(MechanicsRegistry);
}
function isMechanic(address _mechanic) public view override returns (bool _isMechanic) {
return MechanicsRegistry.isMechanic(_mechanic);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import '../../interfaces/utils/IGovernable.sol';
abstract
contract Governable is IGovernable {
address public override governor;
address public override pendingGovernor;
constructor(address _governor) public {
require(_governor != address(0), 'governable/governor-should-not-be-zero-address');
governor = _governor;
}
function _setPendingGovernor(address _pendingGovernor) internal {
require(_pendingGovernor != address(0), 'governable/pending-governor-should-not-be-zero-addres');
pendingGovernor = _pendingGovernor;
emit PendingGovernorSet(_pendingGovernor);
}
function _acceptGovernor() internal {
governor = pendingGovernor;
pendingGovernor = address(0);
emit GovernorAccepted();
}
function isGovernor(address _account) public view override returns (bool _isGovernor) {
return _account == governor;
}
modifier onlyGovernor {
require(isGovernor(msg.sender), 'governable/only-governor');
_;
}
modifier onlyPendingGovernor {
require(msg.sender == pendingGovernor, 'governable/only-pending-governor');
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import '@openzeppelin/contracts/utils/Address.sol';
import '@openzeppelin/contracts/utils/EnumerableSet.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import '../../interfaces/utils/ICollectableDust.sol';
abstract
contract CollectableDust is ICollectableDust {
using SafeERC20 for IERC20;
using EnumerableSet for EnumerableSet.AddressSet;
address public constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
EnumerableSet.AddressSet internal protocolTokens;
constructor() public {}
function _addProtocolToken(address _token) internal {
require(!protocolTokens.contains(_token), 'collectable-dust/token-is-part-of-the-protocol');
protocolTokens.add(_token);
}
function _removeProtocolToken(address _token) internal {
require(protocolTokens.contains(_token), 'collectable-dust/token-not-part-of-the-protocol');
protocolTokens.remove(_token);
}
function _sendDust(
address _to,
address _token,
uint256 _amount
) internal {
require(_to != address(0), 'collectable-dust/cant-send-dust-to-zero-address');
require(!protocolTokens.contains(_token), 'collectable-dust/token-is-part-of-the-protocol');
if (_token == ETH_ADDRESS) {
payable(_to).transfer(_amount);
} else {
IERC20(_token).safeTransfer(_to, _amount);
}
emit DustSent(_to, _token, _amount);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import '../../interfaces/utils/IPausable.sol';
abstract
contract Pausable is IPausable {
bool public paused;
constructor() public {}
modifier notPaused() {
require(!paused, 'paused');
_;
}
function _pause(bool _paused) internal {
require(paused != _paused, 'no-change');
paused = _paused;
emit Paused(_paused);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IGovernable {
event PendingGovernorSet(address pendingGovernor);
event GovernorAccepted();
function setPendingGovernor(address _pendingGovernor) external;
function acceptGovernor() external;
function governor() external view returns (address _governor);
function pendingGovernor() external view returns (address _pendingGovernor);
function isGovernor(address _account) external view returns (bool _isGovernor);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) { // Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(value)));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(value)));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(value)));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint256(_at(set._inner, index)));
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface ICollectableDust {
event DustSent(address _to, address token, uint256 amount);
function sendDust(address _to, address _token, uint256 _amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IPausable {
event Paused(bool _paused);
function pause(bool _paused) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IMachinery {
// View helpers
function mechanicsRegistry() external view returns (address _mechanicsRegistry);
function isMechanic(address mechanic) external view returns (bool _isMechanic);
// Setters
function setMechanicsRegistry(address _mechanicsRegistry) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IMechanicsRegistry {
event MechanicAdded(address _mechanic);
event MechanicRemoved(address _mechanic);
function addMechanic(address _mechanic) external;
function removeMechanic(address _mechanic) external;
function mechanics() external view returns (address[] memory _mechanicsList);
function isMechanic(address mechanic) external view returns (bool _isMechanic);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./IKeep3rV1Helper.sol";
interface IKeep3rV1 is IERC20 {
function name() external returns (string memory);
function KPRH() external view returns (IKeep3rV1Helper);
function isKeeper(address _keeper) external returns (bool);
function isMinKeeper(address _keeper, uint256 _minBond, uint256 _earned, uint256 _age) external returns (bool);
function isBondedKeeper(address _keeper, address bond, uint256 _minBond, uint256 _earned, uint256 _age) external returns (bool);
function addKPRCredit(address _job, uint256 _amount) external;
function addJob(address _job) external;
function removeJob(address _job) external;
function addVotes(address voter, uint256 amount) external;
function removeVotes(address voter, uint256 amount) external;
function revoke(address keeper) external;
function worked(address _keeper) external;
function workReceipt(address _keeper, uint256 _amount) external;
function receipt(address credit, address _keeper, uint256 _amount) external;
function receiptETH(address _keeper, uint256 _amount) external;
function addLiquidityToJob(address liquidity, address job, uint amount) external;
function applyCreditToJob(address provider, address liquidity, address job) external;
function unbondLiquidityFromJob(address liquidity, address job, uint amount) external;
function removeLiquidityFromJob(address liquidity, address job) external;
function jobs(address _job) external view returns (bool);
function jobList(uint256 _index) external view returns (address _job);
function credits(address _job, address _credit) external view returns (uint256 _amount);
function liquidityAccepted(address _liquidity) external view returns (bool);
function liquidityProvided(address _provider, address _liquidity, address _job) external view returns (uint256 _amount);
function liquidityApplied(address _provider, address _liquidity, address _job) external view returns (uint256 _amount);
function liquidityAmount(address _provider, address _liquidity, address _job) external view returns (uint256 _amount);
function liquidityUnbonding(address _provider, address _liquidity, address _job) external view returns (uint256 _amount);
function liquidityAmountsUnbonding(address _provider, address _liquidity, address _job) external view returns (uint256 _amount);
function bond(address bonding, uint256 amount) external;
function activate(address bonding) external;
function unbond(address bonding, uint256 amount) external;
function withdraw(address bonding) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IKeep3r {
event Keep3rSet(address _keep3r);
event Keep3rRequirementsSet(address _bond, uint256 _minBond, uint256 _earned, uint256 _age, bool _onlyEOA);
function keep3r() external view returns (address _keep3r);
function bond() external view returns (address _bond);
function minBond() external view returns (uint256 _minBond);
function earned() external view returns (uint256 _earned);
function age() external view returns (uint256 _age);
function onlyEOA() external view returns (bool _onlyEOA);
function setKeep3r(address _keep3r) external;
function setKeep3rRequirements(address _bond, uint256 _minBond, uint256 _earned, uint256 _age, bool _onlyEOA) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IKeep3rV1Helper {
function quote(uint256 eth) external view returns (uint256);
function getFastGas() external view returns (uint256);
function bonds(address keeper) external view returns (uint256);
function getQuoteLimit(uint256 gasUsed) external view returns (uint256);
function getQuoteLimitFor(address origin, uint256 gasUsed) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IKeep3rJob {
event SetRewardMultiplier(uint256 _rewardMultiplier);
function rewardMultiplier() external view returns (uint256 _rewardMultiplier);
function setRewardMultiplier(uint256 _rewardMultiplier) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import '../utils/IGovernable.sol';
import '../utils/ICollectableDust.sol';
import '../utils/IPausable.sol';
interface IUtilsReady is IGovernable, ICollectableDust, IPausable {
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IHarvestableStrategy {
function harvest() external;
function controller() external view returns (address);
function want() external view returns (address);
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_mechanicsRegistry","type":"address"},{"internalType":"address","name":"_keep3r","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"},{"internalType":"bool","name":"_onlyEOA","type":"bool"},{"internalType":"uint256","name":"_maxHarvestPeriod","type":"uint256"},{"internalType":"uint256","name":"_harvestCooldown","type":"uint256"},{"internalType":"address","name":"_v2Keeper","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DustSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_strategy","type":"address"}],"name":"ForceWorked","type":"event"},{"anonymous":false,"inputs":[],"name":"GovernorAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_bond","type":"address"},{"indexed":false,"internalType":"uint256","name":"_minBond","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_earned","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_age","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_onlyEOA","type":"bool"}],"name":"Keep3rRequirementsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_keep3r","type":"address"}],"name":"Keep3rSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"_paused","type":"bool"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pendingGovernor","type":"address"}],"name":"PendingGovernorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_rewardMultiplier","type":"uint256"}],"name":"SetRewardMultiplier","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"_requiredHarvest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_requiredEarn","type":"uint256"}],"name":"StrategyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"_requiredHarvest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_requiredEarn","type":"uint256"}],"name":"StrategyModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_strategy","type":"address"}],"name":"StrategyRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_strategy","type":"address"},{"indexed":false,"internalType":"address","name":"_keeper","type":"address"},{"indexed":false,"internalType":"uint256","name":"_credits","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_workForTokens","type":"bool"}],"name":"Worked","type":"event"},{"inputs":[],"name":"ETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REWARD_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_strategies","type":"address[]"},{"internalType":"uint256[]","name":"_requiredHarvests","type":"uint256[]"},{"internalType":"uint256[]","name":"_requiredEarns","type":"uint256[]"}],"name":"addStrategies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"},{"internalType":"uint256","name":"_requiredHarvest","type":"uint256"},{"internalType":"uint256","name":"_requiredEarn","type":"uint256"}],"name":"addStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"age","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bond","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"calculateHarvest","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"forceWork","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvestCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isGovernor","outputs":[{"internalType":"bool","name":"_isGovernor","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_mechanic","type":"address"}],"name":"isMechanic","outputs":[{"internalType":"bool","name":"_isMechanic","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keep3r","outputs":[{"internalType":"address","name":"_keep3r","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastHarvest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastWorkAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxHarvestPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mechanicsRegistry","outputs":[{"internalType":"address","name":"_mechanicRegistry","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"onlyEOA","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGovernor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"removeStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"requiredEarn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"requiredHarvest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"sendDust","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_harvestCooldown","type":"uint256"}],"name":"setHarvestCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_keep3r","type":"address"}],"name":"setKeep3r","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bond","type":"address"},{"internalType":"uint256","name":"_minBond","type":"uint256"},{"internalType":"uint256","name":"_earned","type":"uint256"},{"internalType":"uint256","name":"_age","type":"uint256"},{"internalType":"bool","name":"_onlyEOA","type":"bool"}],"name":"setKeep3rRequirements","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxHarvestPeriod","type":"uint256"}],"name":"setMaxHarvestPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mechanicsRegistry","type":"address"}],"name":"setMechanicsRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pendingGovernor","type":"address"}],"name":"setPendingGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardMultiplier","type":"uint256"}],"name":"setRewardMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_v2Keeper","type":"address"}],"name":"setV2Keep3r","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategies","outputs":[{"internalType":"address[]","name":"_strategies","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"strategyIsV1","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_strategies","type":"address[]"},{"internalType":"uint256[]","name":"_requiredHarvests","type":"uint256[]"},{"internalType":"uint256[]","name":"_requiredEarns","type":"uint256[]"}],"name":"updateStrategies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"},{"internalType":"uint256","name":"_requiredHarvest","type":"uint256"},{"internalType":"uint256","name":"_requiredEarn","type":"uint256"}],"name":"updateStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"v2Keeper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"work","outputs":[{"internalType":"uint256","name":"_credits","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"workForBond","outputs":[{"internalType":"uint256","name":"_credits","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"workForTokens","outputs":[{"internalType":"uint256","name":"_credits","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"workable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040526103e8600b553480156200001757600080fd5b506040516200386b3803806200386b83398181016040526101408110156200003e57600080fd5b508051602082015160408301516060840151608085015160a086015160c087015160e08801516101008901516101209099015197989697959694959394929391929091888a803380620000c35760405162461bcd60e51b815260040180806020018281038252602e815260200180620037fe602e913960400191505060405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055620000ee8162000152565b50620000fc9050816200017a565b506200010c8888888888620001ce565b620001178362000261565b6200012282620002a7565b601580546001600160a01b0319166001600160a01b039290921691909117905550620002ac975050505050505050565b600480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600580546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f0fec338132ef1fa68cd11242357e5e5e5af67dfd0c957b53ef411bca535817ef9181900360200190a150565b600680546001600160a01b0319166001600160a01b038716908117909155600785905560088490556009839055600a805460ff19168315159081179091556040805192835260208301879052828101869052606083018590526080830191909152517ec65cfa7a4df705cbfccbeeabefaa0a7015a83bc2b7380c2aba930fa3d66d459160a0908290030190a15050505050565b60008111620002a25760405162461bcd60e51b815260040180806020018281038252603f8152602001806200382c603f913960400191505060405180910390fd5b601055565b601255565b61354280620002bc6000396000f3fe608060405234801561001057600080fd5b50600436106102955760003560e01c8063831518b711610167578063e3056a34116100ce578063ef47da6d11610087578063ef47da6d146108f8578063f1a392da1461091e578063f235757f14610926578063fa34d6111461094c578063fb2a410a1461097e578063fd8d68aa1461098657610295565b8063e3056a341461074e578063e43581b814610756578063e58bb6391461077c578063e80d28c314610784578063e89352de14610892578063ead6a8d3146108d257610295565b8063aaf5eb6811610120578063aaf5eb68146105a0578063cbd3188214610685578063d643ad32146106ab578063d6f19262146106c8578063d9f9027f146106d0578063dd7ba4201461072857610295565b8063831518b714610604578063863718191461060c57806392b3b265146106295780639f47130314610631578063a734f06e14610657578063a90924111461065f57610295565b80633afbd4771161020b578063634c7bb5116101c4578063634c7bb514610598578063646f6eb4146105a057806364c9ec6f146105a857806365834acc146105b05780636f2c590a146105d657806382376a99146105de57610295565b80633afbd477146103d6578063452176e1146103fc5780634cc18e57146104225780635473e2c0146104485780635c975abb146105565780636038f10c1461057257610295565b8063175188e81161025d578063175188e81461033c578063234d200f14610362578063262a9dff1461036a5780632db8c129146103725780632dd6d03a146103a857806336df7ea5146103b057610295565b806302329a291461029a5780630bd075a1146102bb5780630c340a24146102d857806310262803146102fc5780631078f38814610334575b600080fd5b6102b9600480360360208110156102b057600080fd5b503515156109b8565b005b6102b9600480360360208110156102d157600080fd5b5035610a0c565b6102e0610a9e565b604080516001600160a01b039092168252519081900360200190f35b6103226004803603602081101561031257600080fd5b50356001600160a01b0316610aad565b60408051918252519081900360200190f35b6102e0610abf565b6102b96004803603602081101561035257600080fd5b50356001600160a01b0316610ad3565b610322610bde565b610322610be4565b6102b96004803603606081101561038857600080fd5b506001600160a01b03813581169160208101359091169060400135610bea565b610322610c42565b610322600480360360208110156103c657600080fd5b50356001600160a01b0316610c48565b610322600480360360208110156103ec57600080fd5b50356001600160a01b0316610c5b565b6103226004803603602081101561041257600080fd5b50356001600160a01b0316610cbe565b6102b96004803603602081101561043857600080fd5b50356001600160a01b0316610e6e565b6102b96004803603606081101561045e57600080fd5b810190602081018135600160201b81111561047857600080fd5b82018360208201111561048a57600080fd5b803590602001918460208302840111600160201b831117156104ab57600080fd5b919390929091602081019035600160201b8111156104c857600080fd5b8201836020820111156104da57600080fd5b803590602001918460208302840111600160201b831117156104fb57600080fd5b919390929091602081019035600160201b81111561051857600080fd5b82018360208201111561052a57600080fd5b803590602001918460208302840111600160201b8311171561054b57600080fd5b509092509050610ebf565b61055e610fc1565b604080519115158252519081900360200190f35b6103226004803603602081101561058857600080fd5b50356001600160a01b0316610fca565b6102e061102d565b61032261103c565b6102e0611042565b61055e600480360360208110156105c657600080fd5b50356001600160a01b0316611051565b6103226110e7565b6102b9600480360360208110156105f457600080fd5b50356001600160a01b03166110ed565b610322611157565b6102b96004803603602081101561062257600080fd5b503561115d565b6102e06111b9565b61055e6004803603602081101561064757600080fd5b50356001600160a01b03166111c8565b6102e0611215565b6103226004803603602081101561067557600080fd5b50356001600160a01b031661122d565b6103226004803603602081101561069b57600080fd5b50356001600160a01b031661123f565b6102b9600480360360208110156106c157600080fd5b5035611251565b6103226112ad565b6106d86112b3565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156107145781810151838201526020016106fc565b505050509050019250505060405180910390f35b6102b96004803603602081101561073e57600080fd5b50356001600160a01b0316611351565b6102e06113ec565b61055e6004803603602081101561076c57600080fd5b50356001600160a01b03166113fb565b6102b961140f565b6102b96004803603606081101561079a57600080fd5b810190602081018135600160201b8111156107b457600080fd5b8201836020820111156107c657600080fd5b803590602001918460208302840111600160201b831117156107e757600080fd5b919390929091602081019035600160201b81111561080457600080fd5b82018360208201111561081657600080fd5b803590602001918460208302840111600160201b8311171561083757600080fd5b919390929091602081019035600160201b81111561085457600080fd5b82018360208201111561086657600080fd5b803590602001918460208302840111600160201b8311171561088757600080fd5b509092509050611478565b6102b9600480360360a08110156108a857600080fd5b506001600160a01b0381351690602081013590604081013590606081013590608001351515611571565b61055e600480360360208110156108e857600080fd5b50356001600160a01b03166115cd565b6102b96004803603602081101561090e57600080fd5b50356001600160a01b03166115e2565b610322611633565b6102b96004803603602081101561093c57600080fd5b50356001600160a01b0316611639565b6102b96004803603606081101561096257600080fd5b506001600160a01b03813516906020810135906040013561168a565b61055e6116e8565b6102b96004803603606081101561099c57600080fd5b506001600160a01b0381351690602081013590604001356116f1565b6109c1336113fb565b610a00576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b610a098161174f565b50565b610a15336113fb565b80610a245750610a2433611051565b610a5f5760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b610a68816117e0565b6040805182815290517f0c002b45a2a56ac47bbd9d9075735e7591415cfc0c3f50d947016a538e8038179181900360200190a150565b6000546001600160a01b031681565b600e6020526000908152604090205481565b60045461010090046001600160a01b031690565b610adc336113fb565b80610aeb5750610aeb33611051565b610b265760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b6001600160a01b0381166000908152600c6020526040902054610b7a5760405162461bcd60e51b8152600401808060200182810382526038815260200180612ff16038913960400191505060405180910390fd5b6001600160a01b0381166000908152600c6020526040812055610b9e601382611826565b50604080516001600160a01b038316815290517f09a1db4b80c32706328728508c941a6b954f31eb5affd32f236c1fd405f8fea49181900360200190a150565b60125481565b60095481565b610bf3336113fb565b610c32576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b610c3d838383611844565b505050565b60105481565b6000610c5382610c5b565b90505b919050565b60045460009060ff1615610c9f576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b610ca7611994565b610cb2826000611c74565b9050610c563382611d2b565b6001600160a01b0381166000908152600c6020526040812054610d125760405162461bcd60e51b815260040180806020018281038252603a815260200180613231603a913960400191505060405180910390fd5b6000826001600160a01b031663a6f19c846040518163ffffffff1660e01b815260040160206040518083038186803b158015610d4d57600080fd5b505afa158015610d61573d6000803e3d6000fd5b505050506040513d6020811015610d7757600080fd5b5051604080516311b25aab60e21b815290519192506000916001600160a01b038616916346c96aac916004808301926020929190829003018186803b158015610dbf57600080fd5b505afa158015610dd3573d6000803e3d6000fd5b505050506040513d6020811015610de957600080fd5b505160408051633313458360e01b81526001600160a01b0380841660048301529151929350908416916333134583916024808201926020929091908290030181600087803b158015610e3a57600080fd5b505af1158015610e4e573d6000803e3d6000fd5b505050506040513d6020811015610e6457600080fd5b5051949350505050565b610e77336113fb565b610eb6576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b610a0981611d9c565b610ec8336113fb565b80610ed75750610ed733611051565b610f125760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b8483148015610f2057508481145b610f5b5760405162461bcd60e51b815260040180806020018281038252605c81526020018061326b605c913960600191505060405180910390fd5b60005b85811015610fb857610fb0878783818110610f7557fe5b905060200201356001600160a01b0316868684818110610f9157fe5b90506020020135858585818110610fa457fe5b90506020020135611df0565b600101610f5e565b50505050505050565b60045460ff1681565b60045460009060ff161561100e576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b611016611994565b611021826001611c74565b9050610c563382611ec4565b6005546001600160a01b031690565b6103e881565b6006546001600160a01b031681565b6000600460019054906101000a90046001600160a01b03166001600160a01b03166365834acc836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156110b557600080fd5b505afa1580156110c9573d6000803e3d6000fd5b505050506040513d60208110156110df57600080fd5b505192915050565b600b5481565b6110f6336113fb565b611135576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b601580546001600160a01b0319166001600160a01b0392909216919091179055565b60075481565b611166336113fb565b80611175575061117533611051565b6111b05760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b610a0981611f1f565b6015546001600160a01b031681565b60045460009060ff161561120c576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b610c5382611f63565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b600c6020526000908152604090205481565b600d6020526000908152604090205481565b61125a336113fb565b80611269575061126933611051565b6112a45760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b610a09816120e6565b60085481565b60606112bf60136120eb565b67ffffffffffffffff811180156112d557600080fd5b506040519080825280602002602001820160405280156112ff578160200160208202803683370190505b50905060005b61130f60136120eb565b81101561134d576113216013826120f6565b82828151811061132d57fe5b6001600160a01b0390921660209283029190910190910152600101611305565b5090565b61135a336113fb565b80611369575061136933611051565b6113a45760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b6113ad81612102565b604080516001600160a01b038316815290517fee8d688761ac1d0fda49e2ac999f0e46b3beaf16857a8e8905aeab2987dc8d389181900360200190a150565b6001546001600160a01b031681565b6000546001600160a01b0390811691161490565b6001546001600160a01b0316331461146e576040805162461bcd60e51b815260206004820181905260248201527f676f7665726e61626c652f6f6e6c792d70656e64696e672d676f7665726e6f72604482015290519081900360640190fd5b611476612143565b565b611481336113fb565b80611490575061149033611051565b6114cb5760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b84831480156114d957508481145b6115145760405162461bcd60e51b815260040180806020018281038252605f815260200180613347605f913960600191505060405180910390fd5b60005b85811015610fb85761156987878381811061152e57fe5b905060200201356001600160a01b031686868481811061154a57fe5b9050602002013585858581811061155d57fe5b90506020020135612193565b600101611517565b61157a336113fb565b6115b9576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b6115c68585858585612249565b5050505050565b600f6020526000908152604090205460ff1681565b6115eb336113fb565b61162a576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b610a09816122dc565b60115481565b611642336113fb565b611681576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b610a0981612304565b611693336113fb565b806116a257506116a233611051565b6116dd5760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b610c3d838383611df0565b600a5460ff1681565b6116fa336113fb565b80611709575061170933611051565b6117445760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b610c3d838383612193565b60045460ff1615158115151415611799576040805162461bcd60e51b81526020600482015260096024820152686e6f2d6368616e676560b81b604482015290519081900360640190fd5b6004805482151560ff19909116811790915560408051918252517f0e2fb031ee032dc02d8011dc50b816eb450cf856abd8261680dac74f72165bd29181900360200190a150565b6103e88111156118215760405162461bcd60e51b81526004018080602001828103825260428152602001806134cb6042913960600191505060405180910390fd5b600b55565b600061183b836001600160a01b03841661239d565b90505b92915050565b6001600160a01b0383166118895760405162461bcd60e51b815260040180806020018281038252602f8152602001806130ae602f913960400191505060405180910390fd5b611894600283612463565b156118d05760405162461bcd60e51b815260040180806020018281038252602e815260200180613203602e913960400191505060405180910390fd5b6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415611931576040516001600160a01b0384169082156108fc029083906000818181858888f1935050505015801561192b573d6000803e3d6000fd5b50611945565b6119456001600160a01b0383168483612478565b604080516001600160a01b0380861682528416602082015280820183905290517f1e34c1aee8e83c2dcc14c21bb4bfeea7f46c0c998cb797ac7cc4d7a18f5c656b9181900360600190a1505050565b600a5460ff16156119dd573332146119dd5760405162461bcd60e51b815260040180806020018281038252602281526020018061340f6022913960400191505060405180910390fd5b6007541580156119ed5750600854155b80156119f95750600954155b15611ab757600554604080516335d2155560e11b815233600482015290516001600160a01b0390921691636ba42aaa916024808201926020929091908290030181600087803b158015611a4b57600080fd5b505af1158015611a5f573d6000803e3d6000fd5b505050506040513d6020811015611a7557600080fd5b5051611ab25760405162461bcd60e51b81526004018080602001828103825260298152602001806133e66029913960400191505060405180910390fd5b611476565b6006546001600160a01b0316611b985760055460075460085460095460408051630ffaf9ed60e11b8152336004820152602481019490945260448401929092526064830152516001600160a01b0390921691631ff5f3da916084808201926020929091908290030181600087803b158015611b3157600080fd5b505af1158015611b45573d6000803e3d6000fd5b505050506040513d6020811015611b5b57600080fd5b5051611ab25760405162461bcd60e51b815260040180806020018281038252602c8152602001806132c7602c913960400191505060405180910390fd5b60055460065460075460085460095460408051637cea367960e11b81523360048201526001600160a01b03958616602482015260448101949094526064840192909252608483015251919092169163f9d46cf29160a48083019260209291908290030181600087803b158015611c0d57600080fd5b505af1158015611c21573d6000803e3d6000fd5b505050506040513d6020811015611c3757600080fd5b50516114765760405162461bcd60e51b81526004018080602001828103825260338152602001806132f36033913960400191505060405180910390fd5b6000805a9050611c8384611f63565b611cbe5760405162461bcd60e51b815260040180806020018281038252602a815260200180613084602a913960400191505060405180910390fd5b611cc784612102565b611cd0816124ca565b604080516001600160a01b0387168152336020820152808201839052851515606082015290519193507f7c1a0f411a17a9888c10f6796bb1a765787a7ef3c95f281f8b1bc5f13975a93a919081900360800190a15092915050565b60055460408051634b3fde2160e01b81526001600160a01b0385811660048301526024820185905291519190921691634b3fde2191604480830192600092919082900301818387803b158015611d8057600080fd5b505af1158015611d94573d6000803e3d6000fd5b505050505050565b600580546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f0fec338132ef1fa68cd11242357e5e5e5af67dfd0c957b53ef411bca535817ef9181900360200190a150565b6001600160a01b0383166000908152600c602052604090205415611e455760405162461bcd60e51b815260040180806020018281038252603981526020018061304b6039913960400191505060405180910390fd5b611e4f83836124ee565b611e598382612549565b611e64601384612630565b506001600160a01b0383166000818152600e602090815260409182902042905581519283528201849052818101839052517f45bb3eed5cd098efb0a286413fb1f3c11841762610cefbabae6a772963e916ba9181900360600190a1505050565b600554604080516346cd669760e11b81526001600160a01b03928316600482018190529285166024820152604481018490529051638d9acd2e9160648082019260009290919082900301818387803b158015611d8057600080fd5b60008111611f5e5760405162461bcd60e51b815260040180806020018281038252603f81526020018061345b603f913960400191505060405180910390fd5b601055565b6001600160a01b0381166000908152600c6020526040812054611fb75760405162461bcd60e51b815260040180806020018281038252603181526020018061349a6031913960400191505060405180910390fd5b601254601154611fc691612645565b421015611fd557506000610c56565b6010546001600160a01b0383166000908152600e6020526040902054611ffa91612645565b42111561200957506001610c56565b6001600160a01b0382166000908152600f602052604090205460ff161580156120af57506001600160a01b0382166000818152600d602090815260409182902054825163ed882c2b60e01b81526004810191909152915163ed882c2b926024808201939291829003018186803b15801561208257600080fd5b505afa158015612096573d6000803e3d6000fd5b505050506040513d60208110156120ac57600080fd5b50515b156120bc57506001610c56565b6001600160a01b0382166000908152600c60205260409020546120de83610cbe565b101592915050565b601255565b6000610c538261269f565b600061183b83836126a3565b6001600160a01b0381166000908152600f602052604090205460ff16156121315761212c81612707565b61213a565b61213a8161299e565b610a0981612a00565b60018054600080546001600160a01b03199081166001600160a01b0384161782559091169091556040517f7880f0fcc848e1f26e461654b100a69f8d0641e29aa29f6596c6afadbb36b5ea9190a1565b6001600160a01b0383166000908152600c60205260409020546121e75760405162461bcd60e51b81526004018080602001828103825260408152602001806133a66040913960400191505060405180910390fd5b6121f183836124ee565b6121fb8382612549565b604080516001600160a01b03851681526020810184905280820183905290517fd1cf2decb3f18f4af19bcc2eb0b44c6ba4792a96a1267d6acdc4734c9c63644f9181900360600190a1505050565b600680546001600160a01b0319166001600160a01b038716908117909155600785905560088490556009839055600a805460ff19168315159081179091556040805192835260208301879052828101869052606083018590526080830191909152517ec65cfa7a4df705cbfccbeeabefaa0a7015a83bc2b7380c2aba930fa3d66d459160a0908290030190a15050505050565b600480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6001600160a01b0381166123495760405162461bcd60e51b81526004018080602001828103825260358152602001806131ce6035913960400191505060405180910390fd5b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f56bddfa0cee9697cebddf9acd7f23dc6583663b05e007b877056d05017994def9181900360200190a150565b6000818152600183016020526040812054801561245957835460001980830191908101906000908790839081106123d057fe5b90600052602060002001549050808760000184815481106123ed57fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061241d57fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505061183e565b600091505061183e565b600061183b836001600160a01b038416612a21565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610c3d908490612a39565b6000610c536103e86124e8600b546124e23387612aea565b90612bec565b90612c45565b6000811161252d5760405162461bcd60e51b815260040180806020018281038252603d815260200180613137603d913960400191505060405180910390fd5b6001600160a01b039091166000908152600c6020526040902055565b600081116125885760405162461bcd60e51b815260040180806020018281038252603a8152602001806130dd603a913960400191505060405180910390fd5b816001600160a01b031663f77c47916040518163ffffffff1660e01b815260040160206040518083038186803b1580156125c157600080fd5b505afa9250505080156125e657506040513d60208110156125e157600080fd5b505160015b6125ef57612614565b506001600160a01b0382166000908152600f60205260409020805460ff191660011790555b6001600160a01b039091166000908152600d6020526040902055565b600061183b836001600160a01b038416612c87565b60008282018381101561183b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b5490565b815460009082106126e55760405162461bcd60e51b81526004018080602001828103825260228152602001806130296022913960400191505060405180910390fd5b8260000182815481106126f457fe5b9060005260206000200154905092915050565b6000816001600160a01b031663f77c47916040518163ffffffff1660e01b815260040160206040518083038186803b15801561274257600080fd5b505afa158015612756573d6000803e3d6000fd5b505050506040513d602081101561276c57600080fd5b505160408051631f1fcd5160e01b815290519192506000916001600160a01b03851691631f1fcd51916004808301926020929190829003018186803b1580156127b457600080fd5b505afa1580156127c8573d6000803e3d6000fd5b505050506040513d60208110156127de57600080fd5b505160408051632988bb9f60e21b81526001600160a01b03808416600483015291519293506000929185169163a622ee7c91602480820192602092909190829003018186803b15801561283057600080fd5b505afa158015612844573d6000803e3d6000fd5b505050506040513d602081101561285a57600080fd5b50516040805163122835d560e21b815290519192506000916001600160a01b038416916348a0d754916004808301926020929190829003018186803b1580156128a257600080fd5b505afa1580156128b6573d6000803e3d6000fd5b505050506040513d60208110156128cc57600080fd5b50516001600160a01b0386166000908152600d6020526040902054909150811061294457816001600160a01b031663d389800f6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561292b57600080fd5b505af115801561293f573d6000803e3d6000fd5b505050505b846001600160a01b0316634641257d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561297f57600080fd5b505af1158015612993573d6000803e3d6000fd5b505050505050505050565b6015546040805163072e008f60e11b81526001600160a01b03848116600483015291519190921691630e5c011e91602480830192600092919082900301818387803b1580156129ec57600080fd5b505af11580156115c6573d6000803e3d6000fd5b6001600160a01b03166000908152600e602052604090204290819055601155565b60009081526001919091016020526040902054151590565b6060612a8e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612cd19092919063ffffffff16565b805190915015610c3d57808060200190516020811015612aad57600080fd5b5051610c3d5760405162461bcd60e51b815260040180806020018281038252602a815260200180613431602a913960400191505060405180910390fd5b600554604080516309aff02b60e01b815290516000926001600160a01b0316916309aff02b916004808301926020929190829003018186803b158015612b2f57600080fd5b505afa158015612b43573d6000803e3d6000fd5b505050506040513d6020811015612b5957600080fd5b50516001600160a01b0316630421d7f284612b755a8690612cea565b6040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b158015612bb957600080fd5b505afa158015612bcd573d6000803e3d6000fd5b505050506040513d6020811015612be357600080fd5b50519392505050565b600082612bfb5750600061183e565b82820282848281612c0857fe5b041461183b5760405162461bcd60e51b81526004018080602001828103825260218152602001806133266021913960400191505060405180910390fd5b600061183b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612d2c565b6000612c938383612a21565b612cc95750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561183e565b50600061183e565b6060612ce08484600085612dce565b90505b9392505050565b600061183b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612f2a565b60008183612db85760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612d7d578181015183820152602001612d65565b50505050905090810190601f168015612daa5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581612dc457fe5b0495945050505050565b606082471015612e0f5760405162461bcd60e51b81526004018080602001828103825260268152602001806131a86026913960400191505060405180910390fd5b612e1885612f84565b612e69576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310612ea85780518252601f199092019160209182019101612e89565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612f0a576040519150601f19603f3d011682016040523d82523d6000602084013e612f0f565b606091505b5091509150612f1f828286612f8a565b979650505050505050565b60008184841115612f7c5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612d7d578181015183820152602001612d65565b505050900390565b3b151590565b60608315612f99575081612ce3565b825115612fa95782518084602001fd5b60405162461bcd60e51b8152602060048201818152845160248401528451859391928392604401919085019080838360008315612d7d578181015183820152602001612d6556fe43727653747261746567794b65657033724a6f623a3a72656d6f76652d73747261746567793a73747261746567792d6e6f742d6164646564456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647343727653747261746567794b65657033724a6f623a3a6164642d73747261746567793a73747261746567792d616c72656164792d616464656443727653747261746567794b65657033724a6f623a3a686172766573743a6e6f742d776f726b61626c65636f6c6c65637461626c652d647573742f63616e742d73656e642d647573742d746f2d7a65726f2d6164647265737343727653747261746567794b65657033724a6f623a3a7365742d72657175697265642d6561726e3a73686f756c642d6e6f742d62652d7a65726f676f7665726e61626c652f6f6e6c792d676f7665726e6f72000000000000000043727653747261746567794b65657033724a6f623a3a7365742d72657175697265642d686172766573743a73686f756c642d6e6f742d62652d7a65726f4d616368696e6572793a3a6f6e6c79476f7665726e6f724f724d656368616e69633a696e76616c69642d6d73672d73656e646572416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c676f7665726e61626c652f70656e64696e672d676f7665726e6f722d73686f756c642d6e6f742d62652d7a65726f2d616464726573636f6c6c65637461626c652d647573742f746f6b656e2d69732d706172742d6f662d7468652d70726f746f636f6c43727653747261746567794b65657033724a6f623a3a63616c63756c6174652d686172766573743a73747261746567792d6e6f742d616464656443727653747261746567794b65657033724a6f623a3a6164642d737472617465676965733a737472617465676965732d72657175697265642d68617276657374732d616e642d6561726e732d646966666572656e742d6c656e6774686b65657033723a3a69734b65657065723a6b65657065722d6e6f742d6d696e2d726571756972656d656e74736b65657033723a3a69734b65657065723a6b65657065722d6e6f742d637573746f6d2d6d696e2d726571756972656d656e7473536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743727653747261746567794b65657033724a6f623a3a7570646174652d737472617465676965733a737472617465676965732d72657175697265642d68617276657374732d616e642d6561726e732d646966666572656e742d6c656e67746843727653747261746567794b65657033724a6f623a3a7570646174652d72657175697265642d686172766573743a73747261746567792d6e6f742d61646465646b65657033723a3a69734b65657065723a6b65657065722d69732d6e6f742d726567697374657265646b65657033723a3a69734b65657065723a6b65657065722d69732d6e6f742d656f615361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656443727653747261746567794b65657033724a6f623a3a7365742d6d61782d686172766573742d706572696f643a73686f756c642d6e6f742d62652d7a65726f43727653747261746567794b65657033724a6f623a3a776f726b61626c653a73747261746567792d6e6f742d616464656443727653747261746567794b65657033724a6f623a3a7365742d7265776172642d6d756c7469706c6965723a6d756c7469706c6965722d657863656564732d6d6178a26469706673582212206bffe07a8431fb375b5d4f7d90bb1d9c2fcb58654ef96eac2ce7bcc279dd1b6564736f6c634300060c0033676f7665726e61626c652f676f7665726e6f722d73686f756c642d6e6f742d62652d7a65726f2d6164647265737343727653747261746567794b65657033724a6f623a3a7365742d6d61782d686172766573742d706572696f643a73686f756c642d6e6f742d62652d7a65726f000000000000000000000000e8d5a85758fe98f7dce251cad552691d49b499bb0000000000000000000000001ceb5cb57c4d4e2b2433641b95dd330a33185a440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b5e3af16b1880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000002a3000000000000000000000000000000000000000000000000000000000000000708000000000000000000000000736d7e3c5a6cb2ce3b764300140abf476f6cfccf
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102955760003560e01c8063831518b711610167578063e3056a34116100ce578063ef47da6d11610087578063ef47da6d146108f8578063f1a392da1461091e578063f235757f14610926578063fa34d6111461094c578063fb2a410a1461097e578063fd8d68aa1461098657610295565b8063e3056a341461074e578063e43581b814610756578063e58bb6391461077c578063e80d28c314610784578063e89352de14610892578063ead6a8d3146108d257610295565b8063aaf5eb6811610120578063aaf5eb68146105a0578063cbd3188214610685578063d643ad32146106ab578063d6f19262146106c8578063d9f9027f146106d0578063dd7ba4201461072857610295565b8063831518b714610604578063863718191461060c57806392b3b265146106295780639f47130314610631578063a734f06e14610657578063a90924111461065f57610295565b80633afbd4771161020b578063634c7bb5116101c4578063634c7bb514610598578063646f6eb4146105a057806364c9ec6f146105a857806365834acc146105b05780636f2c590a146105d657806382376a99146105de57610295565b80633afbd477146103d6578063452176e1146103fc5780634cc18e57146104225780635473e2c0146104485780635c975abb146105565780636038f10c1461057257610295565b8063175188e81161025d578063175188e81461033c578063234d200f14610362578063262a9dff1461036a5780632db8c129146103725780632dd6d03a146103a857806336df7ea5146103b057610295565b806302329a291461029a5780630bd075a1146102bb5780630c340a24146102d857806310262803146102fc5780631078f38814610334575b600080fd5b6102b9600480360360208110156102b057600080fd5b503515156109b8565b005b6102b9600480360360208110156102d157600080fd5b5035610a0c565b6102e0610a9e565b604080516001600160a01b039092168252519081900360200190f35b6103226004803603602081101561031257600080fd5b50356001600160a01b0316610aad565b60408051918252519081900360200190f35b6102e0610abf565b6102b96004803603602081101561035257600080fd5b50356001600160a01b0316610ad3565b610322610bde565b610322610be4565b6102b96004803603606081101561038857600080fd5b506001600160a01b03813581169160208101359091169060400135610bea565b610322610c42565b610322600480360360208110156103c657600080fd5b50356001600160a01b0316610c48565b610322600480360360208110156103ec57600080fd5b50356001600160a01b0316610c5b565b6103226004803603602081101561041257600080fd5b50356001600160a01b0316610cbe565b6102b96004803603602081101561043857600080fd5b50356001600160a01b0316610e6e565b6102b96004803603606081101561045e57600080fd5b810190602081018135600160201b81111561047857600080fd5b82018360208201111561048a57600080fd5b803590602001918460208302840111600160201b831117156104ab57600080fd5b919390929091602081019035600160201b8111156104c857600080fd5b8201836020820111156104da57600080fd5b803590602001918460208302840111600160201b831117156104fb57600080fd5b919390929091602081019035600160201b81111561051857600080fd5b82018360208201111561052a57600080fd5b803590602001918460208302840111600160201b8311171561054b57600080fd5b509092509050610ebf565b61055e610fc1565b604080519115158252519081900360200190f35b6103226004803603602081101561058857600080fd5b50356001600160a01b0316610fca565b6102e061102d565b61032261103c565b6102e0611042565b61055e600480360360208110156105c657600080fd5b50356001600160a01b0316611051565b6103226110e7565b6102b9600480360360208110156105f457600080fd5b50356001600160a01b03166110ed565b610322611157565b6102b96004803603602081101561062257600080fd5b503561115d565b6102e06111b9565b61055e6004803603602081101561064757600080fd5b50356001600160a01b03166111c8565b6102e0611215565b6103226004803603602081101561067557600080fd5b50356001600160a01b031661122d565b6103226004803603602081101561069b57600080fd5b50356001600160a01b031661123f565b6102b9600480360360208110156106c157600080fd5b5035611251565b6103226112ad565b6106d86112b3565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156107145781810151838201526020016106fc565b505050509050019250505060405180910390f35b6102b96004803603602081101561073e57600080fd5b50356001600160a01b0316611351565b6102e06113ec565b61055e6004803603602081101561076c57600080fd5b50356001600160a01b03166113fb565b6102b961140f565b6102b96004803603606081101561079a57600080fd5b810190602081018135600160201b8111156107b457600080fd5b8201836020820111156107c657600080fd5b803590602001918460208302840111600160201b831117156107e757600080fd5b919390929091602081019035600160201b81111561080457600080fd5b82018360208201111561081657600080fd5b803590602001918460208302840111600160201b8311171561083757600080fd5b919390929091602081019035600160201b81111561085457600080fd5b82018360208201111561086657600080fd5b803590602001918460208302840111600160201b8311171561088757600080fd5b509092509050611478565b6102b9600480360360a08110156108a857600080fd5b506001600160a01b0381351690602081013590604081013590606081013590608001351515611571565b61055e600480360360208110156108e857600080fd5b50356001600160a01b03166115cd565b6102b96004803603602081101561090e57600080fd5b50356001600160a01b03166115e2565b610322611633565b6102b96004803603602081101561093c57600080fd5b50356001600160a01b0316611639565b6102b96004803603606081101561096257600080fd5b506001600160a01b03813516906020810135906040013561168a565b61055e6116e8565b6102b96004803603606081101561099c57600080fd5b506001600160a01b0381351690602081013590604001356116f1565b6109c1336113fb565b610a00576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b610a098161174f565b50565b610a15336113fb565b80610a245750610a2433611051565b610a5f5760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b610a68816117e0565b6040805182815290517f0c002b45a2a56ac47bbd9d9075735e7591415cfc0c3f50d947016a538e8038179181900360200190a150565b6000546001600160a01b031681565b600e6020526000908152604090205481565b60045461010090046001600160a01b031690565b610adc336113fb565b80610aeb5750610aeb33611051565b610b265760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b6001600160a01b0381166000908152600c6020526040902054610b7a5760405162461bcd60e51b8152600401808060200182810382526038815260200180612ff16038913960400191505060405180910390fd5b6001600160a01b0381166000908152600c6020526040812055610b9e601382611826565b50604080516001600160a01b038316815290517f09a1db4b80c32706328728508c941a6b954f31eb5affd32f236c1fd405f8fea49181900360200190a150565b60125481565b60095481565b610bf3336113fb565b610c32576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b610c3d838383611844565b505050565b60105481565b6000610c5382610c5b565b90505b919050565b60045460009060ff1615610c9f576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b610ca7611994565b610cb2826000611c74565b9050610c563382611d2b565b6001600160a01b0381166000908152600c6020526040812054610d125760405162461bcd60e51b815260040180806020018281038252603a815260200180613231603a913960400191505060405180910390fd5b6000826001600160a01b031663a6f19c846040518163ffffffff1660e01b815260040160206040518083038186803b158015610d4d57600080fd5b505afa158015610d61573d6000803e3d6000fd5b505050506040513d6020811015610d7757600080fd5b5051604080516311b25aab60e21b815290519192506000916001600160a01b038616916346c96aac916004808301926020929190829003018186803b158015610dbf57600080fd5b505afa158015610dd3573d6000803e3d6000fd5b505050506040513d6020811015610de957600080fd5b505160408051633313458360e01b81526001600160a01b0380841660048301529151929350908416916333134583916024808201926020929091908290030181600087803b158015610e3a57600080fd5b505af1158015610e4e573d6000803e3d6000fd5b505050506040513d6020811015610e6457600080fd5b5051949350505050565b610e77336113fb565b610eb6576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b610a0981611d9c565b610ec8336113fb565b80610ed75750610ed733611051565b610f125760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b8483148015610f2057508481145b610f5b5760405162461bcd60e51b815260040180806020018281038252605c81526020018061326b605c913960600191505060405180910390fd5b60005b85811015610fb857610fb0878783818110610f7557fe5b905060200201356001600160a01b0316868684818110610f9157fe5b90506020020135858585818110610fa457fe5b90506020020135611df0565b600101610f5e565b50505050505050565b60045460ff1681565b60045460009060ff161561100e576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b611016611994565b611021826001611c74565b9050610c563382611ec4565b6005546001600160a01b031690565b6103e881565b6006546001600160a01b031681565b6000600460019054906101000a90046001600160a01b03166001600160a01b03166365834acc836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156110b557600080fd5b505afa1580156110c9573d6000803e3d6000fd5b505050506040513d60208110156110df57600080fd5b505192915050565b600b5481565b6110f6336113fb565b611135576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b601580546001600160a01b0319166001600160a01b0392909216919091179055565b60075481565b611166336113fb565b80611175575061117533611051565b6111b05760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b610a0981611f1f565b6015546001600160a01b031681565b60045460009060ff161561120c576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b610c5382611f63565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b600c6020526000908152604090205481565b600d6020526000908152604090205481565b61125a336113fb565b80611269575061126933611051565b6112a45760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b610a09816120e6565b60085481565b60606112bf60136120eb565b67ffffffffffffffff811180156112d557600080fd5b506040519080825280602002602001820160405280156112ff578160200160208202803683370190505b50905060005b61130f60136120eb565b81101561134d576113216013826120f6565b82828151811061132d57fe5b6001600160a01b0390921660209283029190910190910152600101611305565b5090565b61135a336113fb565b80611369575061136933611051565b6113a45760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b6113ad81612102565b604080516001600160a01b038316815290517fee8d688761ac1d0fda49e2ac999f0e46b3beaf16857a8e8905aeab2987dc8d389181900360200190a150565b6001546001600160a01b031681565b6000546001600160a01b0390811691161490565b6001546001600160a01b0316331461146e576040805162461bcd60e51b815260206004820181905260248201527f676f7665726e61626c652f6f6e6c792d70656e64696e672d676f7665726e6f72604482015290519081900360640190fd5b611476612143565b565b611481336113fb565b80611490575061149033611051565b6114cb5760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b84831480156114d957508481145b6115145760405162461bcd60e51b815260040180806020018281038252605f815260200180613347605f913960600191505060405180910390fd5b60005b85811015610fb85761156987878381811061152e57fe5b905060200201356001600160a01b031686868481811061154a57fe5b9050602002013585858581811061155d57fe5b90506020020135612193565b600101611517565b61157a336113fb565b6115b9576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b6115c68585858585612249565b5050505050565b600f6020526000908152604090205460ff1681565b6115eb336113fb565b61162a576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b610a09816122dc565b60115481565b611642336113fb565b611681576040805162461bcd60e51b81526020600482015260186024820152600080516020613117833981519152604482015290519081900360640190fd5b610a0981612304565b611693336113fb565b806116a257506116a233611051565b6116dd5760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b610c3d838383611df0565b600a5460ff1681565b6116fa336113fb565b80611709575061170933611051565b6117445760405162461bcd60e51b81526004018080602001828103825260348152602001806131746034913960400191505060405180910390fd5b610c3d838383612193565b60045460ff1615158115151415611799576040805162461bcd60e51b81526020600482015260096024820152686e6f2d6368616e676560b81b604482015290519081900360640190fd5b6004805482151560ff19909116811790915560408051918252517f0e2fb031ee032dc02d8011dc50b816eb450cf856abd8261680dac74f72165bd29181900360200190a150565b6103e88111156118215760405162461bcd60e51b81526004018080602001828103825260428152602001806134cb6042913960600191505060405180910390fd5b600b55565b600061183b836001600160a01b03841661239d565b90505b92915050565b6001600160a01b0383166118895760405162461bcd60e51b815260040180806020018281038252602f8152602001806130ae602f913960400191505060405180910390fd5b611894600283612463565b156118d05760405162461bcd60e51b815260040180806020018281038252602e815260200180613203602e913960400191505060405180910390fd5b6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415611931576040516001600160a01b0384169082156108fc029083906000818181858888f1935050505015801561192b573d6000803e3d6000fd5b50611945565b6119456001600160a01b0383168483612478565b604080516001600160a01b0380861682528416602082015280820183905290517f1e34c1aee8e83c2dcc14c21bb4bfeea7f46c0c998cb797ac7cc4d7a18f5c656b9181900360600190a1505050565b600a5460ff16156119dd573332146119dd5760405162461bcd60e51b815260040180806020018281038252602281526020018061340f6022913960400191505060405180910390fd5b6007541580156119ed5750600854155b80156119f95750600954155b15611ab757600554604080516335d2155560e11b815233600482015290516001600160a01b0390921691636ba42aaa916024808201926020929091908290030181600087803b158015611a4b57600080fd5b505af1158015611a5f573d6000803e3d6000fd5b505050506040513d6020811015611a7557600080fd5b5051611ab25760405162461bcd60e51b81526004018080602001828103825260298152602001806133e66029913960400191505060405180910390fd5b611476565b6006546001600160a01b0316611b985760055460075460085460095460408051630ffaf9ed60e11b8152336004820152602481019490945260448401929092526064830152516001600160a01b0390921691631ff5f3da916084808201926020929091908290030181600087803b158015611b3157600080fd5b505af1158015611b45573d6000803e3d6000fd5b505050506040513d6020811015611b5b57600080fd5b5051611ab25760405162461bcd60e51b815260040180806020018281038252602c8152602001806132c7602c913960400191505060405180910390fd5b60055460065460075460085460095460408051637cea367960e11b81523360048201526001600160a01b03958616602482015260448101949094526064840192909252608483015251919092169163f9d46cf29160a48083019260209291908290030181600087803b158015611c0d57600080fd5b505af1158015611c21573d6000803e3d6000fd5b505050506040513d6020811015611c3757600080fd5b50516114765760405162461bcd60e51b81526004018080602001828103825260338152602001806132f36033913960400191505060405180910390fd5b6000805a9050611c8384611f63565b611cbe5760405162461bcd60e51b815260040180806020018281038252602a815260200180613084602a913960400191505060405180910390fd5b611cc784612102565b611cd0816124ca565b604080516001600160a01b0387168152336020820152808201839052851515606082015290519193507f7c1a0f411a17a9888c10f6796bb1a765787a7ef3c95f281f8b1bc5f13975a93a919081900360800190a15092915050565b60055460408051634b3fde2160e01b81526001600160a01b0385811660048301526024820185905291519190921691634b3fde2191604480830192600092919082900301818387803b158015611d8057600080fd5b505af1158015611d94573d6000803e3d6000fd5b505050505050565b600580546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f0fec338132ef1fa68cd11242357e5e5e5af67dfd0c957b53ef411bca535817ef9181900360200190a150565b6001600160a01b0383166000908152600c602052604090205415611e455760405162461bcd60e51b815260040180806020018281038252603981526020018061304b6039913960400191505060405180910390fd5b611e4f83836124ee565b611e598382612549565b611e64601384612630565b506001600160a01b0383166000818152600e602090815260409182902042905581519283528201849052818101839052517f45bb3eed5cd098efb0a286413fb1f3c11841762610cefbabae6a772963e916ba9181900360600190a1505050565b600554604080516346cd669760e11b81526001600160a01b03928316600482018190529285166024820152604481018490529051638d9acd2e9160648082019260009290919082900301818387803b158015611d8057600080fd5b60008111611f5e5760405162461bcd60e51b815260040180806020018281038252603f81526020018061345b603f913960400191505060405180910390fd5b601055565b6001600160a01b0381166000908152600c6020526040812054611fb75760405162461bcd60e51b815260040180806020018281038252603181526020018061349a6031913960400191505060405180910390fd5b601254601154611fc691612645565b421015611fd557506000610c56565b6010546001600160a01b0383166000908152600e6020526040902054611ffa91612645565b42111561200957506001610c56565b6001600160a01b0382166000908152600f602052604090205460ff161580156120af57506001600160a01b0382166000818152600d602090815260409182902054825163ed882c2b60e01b81526004810191909152915163ed882c2b926024808201939291829003018186803b15801561208257600080fd5b505afa158015612096573d6000803e3d6000fd5b505050506040513d60208110156120ac57600080fd5b50515b156120bc57506001610c56565b6001600160a01b0382166000908152600c60205260409020546120de83610cbe565b101592915050565b601255565b6000610c538261269f565b600061183b83836126a3565b6001600160a01b0381166000908152600f602052604090205460ff16156121315761212c81612707565b61213a565b61213a8161299e565b610a0981612a00565b60018054600080546001600160a01b03199081166001600160a01b0384161782559091169091556040517f7880f0fcc848e1f26e461654b100a69f8d0641e29aa29f6596c6afadbb36b5ea9190a1565b6001600160a01b0383166000908152600c60205260409020546121e75760405162461bcd60e51b81526004018080602001828103825260408152602001806133a66040913960400191505060405180910390fd5b6121f183836124ee565b6121fb8382612549565b604080516001600160a01b03851681526020810184905280820183905290517fd1cf2decb3f18f4af19bcc2eb0b44c6ba4792a96a1267d6acdc4734c9c63644f9181900360600190a1505050565b600680546001600160a01b0319166001600160a01b038716908117909155600785905560088490556009839055600a805460ff19168315159081179091556040805192835260208301879052828101869052606083018590526080830191909152517ec65cfa7a4df705cbfccbeeabefaa0a7015a83bc2b7380c2aba930fa3d66d459160a0908290030190a15050505050565b600480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6001600160a01b0381166123495760405162461bcd60e51b81526004018080602001828103825260358152602001806131ce6035913960400191505060405180910390fd5b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f56bddfa0cee9697cebddf9acd7f23dc6583663b05e007b877056d05017994def9181900360200190a150565b6000818152600183016020526040812054801561245957835460001980830191908101906000908790839081106123d057fe5b90600052602060002001549050808760000184815481106123ed57fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061241d57fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505061183e565b600091505061183e565b600061183b836001600160a01b038416612a21565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610c3d908490612a39565b6000610c536103e86124e8600b546124e23387612aea565b90612bec565b90612c45565b6000811161252d5760405162461bcd60e51b815260040180806020018281038252603d815260200180613137603d913960400191505060405180910390fd5b6001600160a01b039091166000908152600c6020526040902055565b600081116125885760405162461bcd60e51b815260040180806020018281038252603a8152602001806130dd603a913960400191505060405180910390fd5b816001600160a01b031663f77c47916040518163ffffffff1660e01b815260040160206040518083038186803b1580156125c157600080fd5b505afa9250505080156125e657506040513d60208110156125e157600080fd5b505160015b6125ef57612614565b506001600160a01b0382166000908152600f60205260409020805460ff191660011790555b6001600160a01b039091166000908152600d6020526040902055565b600061183b836001600160a01b038416612c87565b60008282018381101561183b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b5490565b815460009082106126e55760405162461bcd60e51b81526004018080602001828103825260228152602001806130296022913960400191505060405180910390fd5b8260000182815481106126f457fe5b9060005260206000200154905092915050565b6000816001600160a01b031663f77c47916040518163ffffffff1660e01b815260040160206040518083038186803b15801561274257600080fd5b505afa158015612756573d6000803e3d6000fd5b505050506040513d602081101561276c57600080fd5b505160408051631f1fcd5160e01b815290519192506000916001600160a01b03851691631f1fcd51916004808301926020929190829003018186803b1580156127b457600080fd5b505afa1580156127c8573d6000803e3d6000fd5b505050506040513d60208110156127de57600080fd5b505160408051632988bb9f60e21b81526001600160a01b03808416600483015291519293506000929185169163a622ee7c91602480820192602092909190829003018186803b15801561283057600080fd5b505afa158015612844573d6000803e3d6000fd5b505050506040513d602081101561285a57600080fd5b50516040805163122835d560e21b815290519192506000916001600160a01b038416916348a0d754916004808301926020929190829003018186803b1580156128a257600080fd5b505afa1580156128b6573d6000803e3d6000fd5b505050506040513d60208110156128cc57600080fd5b50516001600160a01b0386166000908152600d6020526040902054909150811061294457816001600160a01b031663d389800f6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561292b57600080fd5b505af115801561293f573d6000803e3d6000fd5b505050505b846001600160a01b0316634641257d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561297f57600080fd5b505af1158015612993573d6000803e3d6000fd5b505050505050505050565b6015546040805163072e008f60e11b81526001600160a01b03848116600483015291519190921691630e5c011e91602480830192600092919082900301818387803b1580156129ec57600080fd5b505af11580156115c6573d6000803e3d6000fd5b6001600160a01b03166000908152600e602052604090204290819055601155565b60009081526001919091016020526040902054151590565b6060612a8e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612cd19092919063ffffffff16565b805190915015610c3d57808060200190516020811015612aad57600080fd5b5051610c3d5760405162461bcd60e51b815260040180806020018281038252602a815260200180613431602a913960400191505060405180910390fd5b600554604080516309aff02b60e01b815290516000926001600160a01b0316916309aff02b916004808301926020929190829003018186803b158015612b2f57600080fd5b505afa158015612b43573d6000803e3d6000fd5b505050506040513d6020811015612b5957600080fd5b50516001600160a01b0316630421d7f284612b755a8690612cea565b6040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b158015612bb957600080fd5b505afa158015612bcd573d6000803e3d6000fd5b505050506040513d6020811015612be357600080fd5b50519392505050565b600082612bfb5750600061183e565b82820282848281612c0857fe5b041461183b5760405162461bcd60e51b81526004018080602001828103825260218152602001806133266021913960400191505060405180910390fd5b600061183b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612d2c565b6000612c938383612a21565b612cc95750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561183e565b50600061183e565b6060612ce08484600085612dce565b90505b9392505050565b600061183b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612f2a565b60008183612db85760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612d7d578181015183820152602001612d65565b50505050905090810190601f168015612daa5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581612dc457fe5b0495945050505050565b606082471015612e0f5760405162461bcd60e51b81526004018080602001828103825260268152602001806131a86026913960400191505060405180910390fd5b612e1885612f84565b612e69576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310612ea85780518252601f199092019160209182019101612e89565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612f0a576040519150601f19603f3d011682016040523d82523d6000602084013e612f0f565b606091505b5091509150612f1f828286612f8a565b979650505050505050565b60008184841115612f7c5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612d7d578181015183820152602001612d65565b505050900390565b3b151590565b60608315612f99575081612ce3565b825115612fa95782518084602001fd5b60405162461bcd60e51b8152602060048201818152845160248401528451859391928392604401919085019080838360008315612d7d578181015183820152602001612d6556fe43727653747261746567794b65657033724a6f623a3a72656d6f76652d73747261746567793a73747261746567792d6e6f742d6164646564456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647343727653747261746567794b65657033724a6f623a3a6164642d73747261746567793a73747261746567792d616c72656164792d616464656443727653747261746567794b65657033724a6f623a3a686172766573743a6e6f742d776f726b61626c65636f6c6c65637461626c652d647573742f63616e742d73656e642d647573742d746f2d7a65726f2d6164647265737343727653747261746567794b65657033724a6f623a3a7365742d72657175697265642d6561726e3a73686f756c642d6e6f742d62652d7a65726f676f7665726e61626c652f6f6e6c792d676f7665726e6f72000000000000000043727653747261746567794b65657033724a6f623a3a7365742d72657175697265642d686172766573743a73686f756c642d6e6f742d62652d7a65726f4d616368696e6572793a3a6f6e6c79476f7665726e6f724f724d656368616e69633a696e76616c69642d6d73672d73656e646572416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c676f7665726e61626c652f70656e64696e672d676f7665726e6f722d73686f756c642d6e6f742d62652d7a65726f2d616464726573636f6c6c65637461626c652d647573742f746f6b656e2d69732d706172742d6f662d7468652d70726f746f636f6c43727653747261746567794b65657033724a6f623a3a63616c63756c6174652d686172766573743a73747261746567792d6e6f742d616464656443727653747261746567794b65657033724a6f623a3a6164642d737472617465676965733a737472617465676965732d72657175697265642d68617276657374732d616e642d6561726e732d646966666572656e742d6c656e6774686b65657033723a3a69734b65657065723a6b65657065722d6e6f742d6d696e2d726571756972656d656e74736b65657033723a3a69734b65657065723a6b65657065722d6e6f742d637573746f6d2d6d696e2d726571756972656d656e7473536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743727653747261746567794b65657033724a6f623a3a7570646174652d737472617465676965733a737472617465676965732d72657175697265642d68617276657374732d616e642d6561726e732d646966666572656e742d6c656e67746843727653747261746567794b65657033724a6f623a3a7570646174652d72657175697265642d686172766573743a73747261746567792d6e6f742d61646465646b65657033723a3a69734b65657065723a6b65657065722d69732d6e6f742d726567697374657265646b65657033723a3a69734b65657065723a6b65657065722d69732d6e6f742d656f615361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656443727653747261746567794b65657033724a6f623a3a7365742d6d61782d686172766573742d706572696f643a73686f756c642d6e6f742d62652d7a65726f43727653747261746567794b65657033724a6f623a3a776f726b61626c653a73747261746567792d6e6f742d616464656443727653747261746567794b65657033724a6f623a3a7365742d7265776172642d6d756c7469706c6965723a6d756c7469706c6965722d657863656564732d6d6178a26469706673582212206bffe07a8431fb375b5d4f7d90bb1d9c2fcb58654ef96eac2ce7bcc279dd1b6564736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e8d5a85758fe98f7dce251cad552691d49b499bb0000000000000000000000001ceb5cb57c4d4e2b2433641b95dd330a33185a440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b5e3af16b1880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000002a3000000000000000000000000000000000000000000000000000000000000000708000000000000000000000000736d7e3c5a6cb2ce3b764300140abf476f6cfccf
-----Decoded View---------------
Arg [0] : _mechanicsRegistry (address): 0xE8d5A85758FE98F7Dce251CAd552691D49b499Bb
Arg [1] : _keep3r (address): 0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44
Arg [2] : _bond (address): 0x0000000000000000000000000000000000000000
Arg [3] : _minBond (uint256): 50000000000000000000
Arg [4] : _earned (uint256): 0
Arg [5] : _age (uint256): 0
Arg [6] : _onlyEOA (bool): True
Arg [7] : _maxHarvestPeriod (uint256): 172800
Arg [8] : _harvestCooldown (uint256): 1800
Arg [9] : _v2Keeper (address): 0x736D7e3c5a6CB2CE3B764300140ABF476F6CFCCF
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 000000000000000000000000e8d5a85758fe98f7dce251cad552691d49b499bb
Arg [1] : 0000000000000000000000001ceb5cb57c4d4e2b2433641b95dd330a33185a44
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 000000000000000000000000000000000000000000000002b5e3af16b1880000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [7] : 000000000000000000000000000000000000000000000000000000000002a300
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000708
Arg [9] : 000000000000000000000000736d7e3c5a6cb2ce3b764300140abf476f6cfccf
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.