Address Contract Partially Verified
Address
0xE4D89e8267D2e8f03f751fa807B3bBdB36729F9A
Balance
0 ETH
Nonce
1
Code Size
4112 bytes
Creator
0x947B7742...0277 at tx 0x2f5fd55d...1d2311
Indexed Transactions
0
Contract Bytecode
4112 bytes
0x608060405234801561001057600080fd5b50600436106101215760003560e01c80637532ed2b116100ad578063c00007b011610071578063c00007b014610290578063c6def076146102b6578063c745ccbf146102be578063cc956f3f1461032e578063dc4c90d31461034b57610121565b80637532ed2b146102415780638da5cb5b14610249578063923c1d6114610251578063adc7ea3714610259578063b46b400d1461027657610121565b80633545c789116100f45780633545c7891461018f5780634a92b5fd146101b35780634b8843d5146101d95780635cfbfc6d1461020b5780636a4874a11461023957610121565b806313e7c9d8146101265780632663fcfc146101605780632e9e18541461016a5780632f2770db14610187575b600080fd5b61014c6004803603602081101561013c57600080fd5b50356001600160a01b0316610353565b604080519115158252519081900360200190f35b610168610368565b005b6101686004803603602081101561018057600080fd5b503561038c565b61016861044e565b6101976105cd565b604080516001600160a01b039092168252519081900360200190f35b610197600480360360208110156101c957600080fd5b50356001600160a01b03166105f1565b610168600480360360608110156101ef57600080fd5b506001600160a01b03813516906020810135906040013561060c565b6101686004803603604081101561022157600080fd5b506001600160a01b0381351690602001351515610762565b610197610826565b61019761083e565b610197610856565b61019761087a565b6101686004803603602081101561026f57600080fd5b5035610892565b61027e610933565b60408051918252519081900360200190f35b610168600480360360208110156102a657600080fd5b50356001600160a01b0316610939565b6101976109c5565b610168600480360360208110156102d457600080fd5b8101906020810181356401000000008111156102ef57600080fd5b82018360208201111561030157600080fd5b8035906020019184602083028401116401000000008311171561032357600080fd5b5090925090506109dd565b61014c6004803603602081101561034457600080fd5b5035610ac9565b610197610d6f565b60006020819052908152604090205460ff1681565b3360009081526001602052604090205461038a906001600160a01b0316610d93565b565b60008073f403c135812408bfbe8713b5a23a04b3d48aae316001600160a01b0316631526fe27846040518263ffffffff1660e01b81526004018082815260200191505060c06040518083038186803b1580156103e757600080fd5b505afa1580156103fb573d6000803e3d6000fd5b505050506040513d60c081101561041157600080fd5b5060608101516080909101516001600160a01b03908116600090815260016020526040902080546001600160a01b03191691909216179055505050565b7f000000000000000000000000a3c5a1e09150b75ff251c1a7815a07182c3de2fb6001600160a01b031633146104b4576040805162461bcd60e51b815260206004820152600660248201526510b7bbb732b960d11b604482015290519081900360640190fd5b604080516370a0823160e01b8152306004820152905173d533a949740bb3306d119cc777fa900ba034cd529163a9059cbb91731389388d01708118b497f59521f6943be2541bb79184916370a0823191602480820192602092909190829003018186803b15801561052457600080fd5b505afa158015610538573d6000803e3d6000fd5b505050506040513d602081101561054e57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b15801561059f57600080fd5b505af11580156105b3573d6000803e3d6000fd5b505050506040513d60208110156105c957600080fd5b5050565b7f000000000000000000000000723f9aa67fdd9b0e375ef8553eb2afc28ecd4a9681565b6001602052600090815260409020546001600160a01b031681565b336001600160a01b037f0000000000000000000000006d3a388e310aaa498430d1fe541d6d64ddb423de1614610674576040805162461bcd60e51b815260206004820152600860248201526721706f6f6c4d6e6760c01b604482015290519081900360640190fd5b61067d8161038c565b600073256e1bba846611c37cf89844a02435e6c098b86d6001600160a01b03166304e020dd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106cc57600080fd5b505afa1580156106e0573d6000803e3d6000fd5b505050506040513d60208110156106f657600080fd5b5051604080516398881bc960e01b81526004810185905290519192506001600160a01b038316916398881bc99160248082019260009290919082900301818387803b15801561074457600080fd5b505af1158015610758573d6000803e3d6000fd5b5050505050505050565b7f000000000000000000000000a3c5a1e09150b75ff251c1a7815a07182c3de2fb6001600160a01b031633146107c8576040805162461bcd60e51b815260206004820152600660248201526510b7bbb732b960d11b604482015290519081900360640190fd5b6001600160a01b03821660008181526020818152604091829020805460ff1916851515908117909155825190815291517fbadd5a134a60c76befc7e7d53706d47a82ac7037171f88c24a7f70faa2998ef19281900390910190a25050565b73d533a949740bb3306d119cc777fa900ba034cd5281565b73256e1bba846611c37cf89844a02435e6c098b86d81565b7f000000000000000000000000a3c5a1e09150b75ff251c1a7815a07182c3de2fb81565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b81565b7f000000000000000000000000a3c5a1e09150b75ff251c1a7815a07182c3de2fb6001600160a01b031633146108f8576040805162461bcd60e51b815260206004820152600660248201526510b7bbb732b960d11b604482015290519081900360640190fd5b60028190556040805182815290517fb33211365ccf8563493d1b2ccf9a78aa626fb222777be9b474156c6fe18597f39181900360200190a150565b60025481565b336001600160a01b037f000000000000000000000000723f9aa67fdd9b0e375ef8553eb2afc28ecd4a96161461099e576040805162461bcd60e51b815260206004820152600560248201526421686f6f6b60d81b604482015290519081900360640190fd5b6001600160a01b038082166000908152600160205260409020546109c29116610d93565b50565b73f403c135812408bfbe8713b5a23a04b3d48aae3181565b8060005b81811015610ac35760008073f403c135812408bfbe8713b5a23a04b3d48aae31631526fe27878786818110610a1257fe5b905060200201356040518263ffffffff1660e01b81526004018082815260200191505060c06040518083038186803b158015610a4d57600080fd5b505afa158015610a61573d6000803e3d6000fd5b505050506040513d60c0811015610a7757600080fd5b5060608101516080909101516001600160a01b03908116600090815260016020819052604090912080546001600160a01b03191692909316919091179091559290920191506109e19050565b50505050565b3360009081526020819052604081205460ff1680610b0f57507f000000000000000000000000a3c5a1e09150b75ff251c1a7815a07182c3de2fb6001600160a01b031633145b610b46576040805162461bcd60e51b81526020600482015260036024820152620216f760ec1b604482015290519081900360640190fd5b604080516370a0823160e01b8152306004820152905160009173d533a949740bb3306d119cc777fa900ba034cd52916370a0823191602480820192602092909190829003018186803b158015610b9b57600080fd5b505afa158015610baf573d6000803e3d6000fd5b505050506040513d6020811015610bc557600080fd5b50516003805460ff191660011790556040805163cc956f3f60e01b815260048101869052905191925073f403c135812408bfbe8713b5a23a04b3d48aae319163cc956f3f916024808201926020929091908290030181600087803b158015610c2c57600080fd5b505af1158015610c40573d6000803e3d6000fd5b505050506040513d6020811015610c5657600080fd5b50506003805460ff19169055604080516370a0823160e01b8152306004820152905173d533a949740bb3306d119cc777fa900ba034cd529163a9059cbb913391859185916370a08231916024808301926020929190829003018186803b158015610cbf57600080fd5b505afa158015610cd3573d6000803e3d6000fd5b505050506040513d6020811015610ce957600080fd5b5051604080516001600160e01b031960e087901b1681526001600160a01b03909416600485015291900360248301525160448083019260209291908290030181600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b505050506040513d6020811015610d6457600080fd5b506001949350505050565b7f0000000000000000000000006d3a388e310aaa498430d1fe541d6d64ddb423de81565b6001600160a01b0381161580610dab575060035460ff165b15610db5576109c2565b600254816001600160a01b031663ebe2b12b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610df157600080fd5b505afa158015610e05573d6000803e3d6000fd5b505050506040513d6020811015610e1b57600080fd5b5051014210610e29576109c2565b6000816001600160a01b031663901a7d536040518163ffffffff1660e01b815260040160206040518083038186803b158015610e6457600080fd5b505afa158015610e78573d6000803e3d6000fd5b505050506040513d6020811015610e8e57600080fd5b5051604080516370a0823160e01b815273f403c135812408bfbe8713b5a23a04b3d48aae316004820152905191925060009173d533a949740bb3306d119cc777fa900ba034cd52916370a08231916024808301926020929190829003018186803b158015610efb57600080fd5b505afa158015610f0f573d6000803e3d6000fd5b505050506040513d6020811015610f2557600080fd5b5051905060028202811115610f3b5750506109c2565b6040805163a9059cbb60e01b815273f403c135812408bfbe8713b5a23a04b3d48aae31600482015260016024820152905173d533a949740bb3306d119cc777fa900ba034cd529163a9059cbb9160448083019260209291908290030181600087803b158015610fa957600080fd5b505af1158015610fbd573d6000803e3d6000fd5b505050506040513d6020811015610fd357600080fd5b505050505056fea264697066735822122009b0d975827601799a5e1845f97a07cc85caf0055a5053a626211681b47576fc64736f6c634300060c0033
Verified Source Code Partial Match
Compiler: v0.6.12+commit.27d51765
EVM: istanbul
Optimization: Yes (200 runs)
PoolHarvestHook.sol 147 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "./interfaces/IBooster.sol";
import "./interfaces/IBoosterAdmin.sol";
import "./interfaces/IBoosterRewardManager.sol";
import "./interfaces/IRewards.sol";
import "./interfaces/IRewardHook.sol";
import "./interfaces/IPoolAddHook.sol";
import "./interfaces/IRewardHookExtended.sol";
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
/*
A Hook that forces harvests to happen once period finish is complete
*/
contract PoolHarvestHook is IRewardHook, IPoolAddHook{
address public constant booster = address(0xF403C135812408BFbE8713b5A23a04b3D48AAE31);
address public constant boosterOwner = address(0x256e1bbA846611C37CF89844a02435E6C098b86D);
address public constant cvx = address(0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B);
address public constant crv = address(0xD533a949740bb3306d119CC777fa900bA034cd52);
address public immutable poolManager;
address public immutable poolHook;
address public immutable owner;
mapping(address => bool) public operators;
mapping(address => address) public stashMap;
uint256 public timebuffer;
bool private isOperator;
event AddOperator(address indexed _op, bool _valid);
event ChangeBuffer(uint256 _buffer);
constructor(address _owner, address _poolManager, address _poolHook) public {
owner = _owner;
poolManager = _poolManager;
poolHook = _poolHook;
operators[msg.sender] = true;
timebuffer = 1 hours;
emit AddOperator(msg.sender, true);
}
modifier onlyOwner() {
require(owner == msg.sender, "!owner");
_;
}
modifier onlyOperator() {
require(operators[msg.sender] || owner == msg.sender, "!op");
_;
}
//set operator
function setOperators(address _op, bool _valid) external onlyOwner{
operators[_op] = _valid;
emit AddOperator(_op, _valid);
}
//set time buffer
function setBuffer(uint256 _seconds) external onlyOwner{
timebuffer = _seconds;
emit ChangeBuffer(_seconds);
}
//disable hook by removing all crv on this address
function disable() external onlyOwner{
IERC20(crv).transfer(address(0x1389388d01708118b497f59521f6943Be2541bb7), IERC20(crv).balanceOf(address(this)));
}
function setStashMap(uint256 _pid) public{
//get stash address and crvrewards address
(,,,address crvRewards, address stash,) = IBooster(booster).poolInfo(_pid);
//add mapping stash -> rewards
stashMap[stash] = crvRewards;
}
function setMultiStashMap(uint256[] calldata _pids) public{
uint256 l = _pids.length;
for(uint256 p = 0; p < l; ++p){
//get stash address and crvrewards address
(,,,address crvRewards, address stash,) = IBooster(booster).poolInfo(_pids[p]);
//add mapping stash -> rewards
stashMap[stash] = crvRewards;
}
}
function poolAdded(address /*_gauge*/, uint256 /*_stashVersion*/, uint256 _poolId) external override{
//require called from pool manager
require(msg.sender == poolManager, "!poolMng");
// set stash map
setStashMap(_poolId);
// tell booster owner reward manager to initialize pool (add cvx reward and stash hook)
address rewardmanager = IBoosterAdmin(boosterOwner).stashRewardManager();
IBoosterRewardManager(rewardmanager).initializePool(_poolId);
}
function earmarkRewards(uint256 _pid) external onlyOperator returns(bool){
uint256 crvb = IERC20(crv).balanceOf(address(this));
isOperator = true;
IBooster(booster).earmarkRewards(_pid);
isOperator = false;
IERC20(crv).transfer(msg.sender, IERC20(crv).balanceOf(address(this))-crvb);
return true;
}
//hook from stash
function onRewardClaim() external override{
//msg.sender is a proper stash if in the stash map
_onHarvest(stashMap[msg.sender]);
}
//hook from PoolRewardHook
function getReward(address _stash) public{
require(msg.sender == poolHook, "!hook");
//can trust the stash address given by PoolRewardHook
_onHarvest(stashMap[_stash]);
}
function _onHarvest(address _crvRewards) internal{
//if not set or operator, return
if(_crvRewards == address(0) || isOperator){
return;
}
//check period finish on crvrewards
if (block.timestamp >= IRewards(_crvRewards).periodFinish()+timebuffer) {
return;
}
// //check if there is more crv rewards waiting to be claimed than the current reward epoch
uint256 currentRewards = IRewards(_crvRewards).currentRewards();
uint256 balanceOnBooster = IERC20(crv).balanceOf(booster);
if(balanceOnBooster > currentRewards * 2){
return;
}
//if fail, send 1 wei of crv to booster
IERC20(crv).transfer(booster, 1);
}
}
IBooster.sol 19 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IBooster {
function owner() external view returns(address);
function feeToken() external view returns(address);
function feeDistro() external view returns(address);
function lockFees() external view returns(address);
function stakerRewards() external view returns(address);
function lockRewards() external view returns(address);
function setVoteDelegate(address _voteDelegate) external;
function vote(uint256 _voteId, address _votingAddress, bool _support) external returns(bool);
function voteGaugeWeight(address[] calldata _gauge, uint256[] calldata _weight ) external returns(bool);
function poolInfo(uint256 _pid) external view returns(address _lptoken, address _token, address _gauge, address _crvRewards, address _stash, bool _shutdown);
function earmarkRewards(uint256 _pid) external returns(bool);
function earmarkFees() external returns(bool);
function isShutdown() external view returns(bool);
function poolLength() external view returns (uint256);
}
IRewards.sol 21 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IRewards{
function stake(address, uint256) external;
function stakeFor(address, uint256) external;
function withdraw(address, uint256) external;
function setWeight(address _pool, uint256 _amount) external returns(bool);
function setWeights(address[] calldata _account, uint256[] calldata _amount) external;
function setDistributor(address _distro, bool _valid) external;
function getReward(address) external;
function queueNewRewards(uint256) external;
function addExtraReward(address) external;
function setRewardHook(address) external;
function user_checkpoint(address _account) external returns(bool);
function periodFinish() external view returns(uint256);
function currentRewards() external view returns(uint256);
function rewardToken() external view returns(address);
function rewardMap(address) external view returns(bool);
function earned(address account) external view returns (uint256);
}
IRewardHook.sol 7 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IRewardHook {
function onRewardClaim() external;
}
IPoolAddHook.sol 7 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IPoolAddHook {
function poolAdded(address _gauge, uint256 _stashVersion, uint256 _poolId) external;
}
IBoosterAdmin.sol 12 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IBoosterAdmin {
function owner() external view returns(address);
function stashRewardManager() external view returns(address);
function setStashRewardManager(address _mng) external;
function acceptStashRewardManager() external;
function setStashExtraReward(uint256 _pid, address _token) external;
function setStashRewardHook(uint256 _pid, address _hook) external;
function setStashTokenIsValid(address stashToken, bool isValid) external;
}
IRewardHookExtended.sol 10 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IRewardHookExtended {
function onRewardClaim() external;
function poolRewardLength(address _pool) external view returns(uint256);
function poolRewardList(address _pool, uint256 _index) external view returns(address _rewardContract);
function addPoolReward(address _pool, address _rewardContract) external;
}
IERC20.sol 77 lines
// 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);
}
IBoosterRewardManager.sol 12 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IBoosterRewardManager {
function defaultHook() external view returns(address);
function initializePool(uint256 _pid) external;
function setStashRewardManager(address _mng) external;
function setStashExtraReward(uint256 _pid, address _token) external;
function setStashRewardHook(uint256 _pid, address _hook) external;
function setMultiStashRewardHook(uint256[] calldata _pids, address _hook) external;
function setStashTokenIsValid(address stashToken, bool isValid) external;
}
Read Contract
booster 0xc6def076 → address
boosterOwner 0x7532ed2b → address
crv 0x6a4874a1 → address
cvx 0x923c1d61 → address
operators 0x13e7c9d8 → bool
owner 0x8da5cb5b → address
poolHook 0x3545c789 → address
poolManager 0xdc4c90d3 → address
stashMap 0x4a92b5fd → address
timebuffer 0xb46b400d → uint256
Write Contract 9 functions
These functions modify contract state and require a wallet transaction to execute.
disable 0x2f2770db
No parameters
earmarkRewards 0xcc956f3f
uint256 _pid
returns: bool
getReward 0xc00007b0
address _stash
onRewardClaim 0x2663fcfc
No parameters
poolAdded 0x4b8843d5
address
uint256
uint256 _poolId
setBuffer 0xadc7ea37
uint256 _seconds
setMultiStashMap 0xc745ccbf
uint256[] _pids
setOperators 0x5cfbfc6d
address _op
bool _valid
setStashMap 0x2e9e1854
uint256 _pid
Recent Transactions
No transactions found for this address