编译器
0.8.17+commit.8df45f5f
文件 1 的 14:BaseAdminOperation.sol
pragma solidity ^0.8.4;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol";
import {TransferHelper} from "./util/TransferHelper.sol";
abstract contract BaseAdminOperation is Pausable, Ownable {
event AdminUpdated(address indexed addr, bool flag);
mapping(address => bool) public isAdmin;
modifier onlyAdmin() {
require(_msgSender() == owner() || isAdmin[_msgSender()], "BaseAdminOperation: !admin");
_;
}
function pause() public onlyAdmin {
_pause();
}
function unpause() public onlyAdmin {
_unpause();
}
function setAdmin(address addr, bool flag) public onlyAdmin {
isAdmin[addr] = flag;
emit AdminUpdated(addr, flag);
}
function inCaseTokenGotStuck(address stuckToken) external virtual onlyOwner {
if (stuckToken == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {
TransferHelper.safeTransferETH(_msgSender(), address(this).balance);
} else {
uint256 amount = IERC20(stuckToken).balanceOf(address(this));
TransferHelper.safeTransfer(stuckToken, _msgSender(), amount);
}
}
}
文件 2 的 14:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 3 的 14:EnumerableSet.sol
pragma solidity ^0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastValue = set._values[lastIndex];
set._values[toDeleteIndex] = lastValue;
set._indexes[lastValue] = valueIndex;
}
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
assembly {
result := store
}
return result;
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
文件 4 的 14:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
文件 5 的 14:IRewarder.sol
pragma solidity ^0.8.0;
import "./IWooStakingManager.sol";
interface IRewarder {
event ClaimOnRewarder(address indexed from, address indexed to, uint256 amount);
event SetStakingManagerOnRewarder(address indexed manager);
function rewardToken() external view returns (address);
function stakingManager() external view returns (IWooStakingManager);
function pendingReward(address _user) external view returns (uint256 rewardAmount);
function claim(address _user) external returns (uint256 rewardAmount);
function claim(address _user, address _to) external returns (uint256 rewardAmount);
function setStakingManager(address _manager) external;
function updateReward() external;
function updateRewardForUser(address _user) external;
function clearRewardToDebt(address _user) external;
}
文件 6 的 14:IWooPPV2.sol
pragma solidity ^0.8.0;
interface IWooPPV2 {
event Deposit(address indexed token, address indexed sender, uint256 amount);
event Withdraw(address indexed token, address indexed receiver, uint256 amount);
event Migrate(address indexed token, address indexed receiver, uint256 amount);
event AdminUpdated(address indexed addr, bool flag);
event FeeAddrUpdated(address indexed newFeeAddr);
event WooracleUpdated(address indexed newWooracle);
event WooSwap(
address indexed fromToken,
address indexed toToken,
uint256 fromAmount,
uint256 toAmount,
address from,
address indexed to,
address rebateTo,
uint256 swapVol,
uint256 swapFee
);
function quoteToken() external view returns (address);
function poolSize(address token) external view returns (uint256);
function tryQuery(address fromToken, address toToken, uint256 fromAmount) external view returns (uint256 toAmount);
function query(address fromToken, address toToken, uint256 fromAmount) external view returns (uint256 toAmount);
function swap(
address fromToken,
address toToken,
uint256 fromAmount,
uint256 minToAmount,
address to,
address rebateTo
) external returns (uint256 realToAmount);
function deposit(address token, uint256 amount) external;
}
文件 7 的 14:IWooStakingCompounder.sol
pragma solidity ^0.8.0;
interface IWooStakingCompounder {
function compoundAll() external;
function compound(uint256 start, uint256 end) external;
function contains(address _user) external view returns (bool);
function addUser(address _user) external;
function addUserIfThresholdMeet(address _user) external returns (bool added);
function removeUser(address _user) external returns (bool removed);
function removeUserIfThresholdFail(address _user) external returns (bool removed);
}
文件 8 的 14:IWooStakingLocal.sol
pragma solidity 0.8.17;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IWooStakingLocal {
event StakeOnLocal(address indexed user, uint256 amount);
event StakeForUsersOnLocal(address[] users, uint256[] amounts, uint256 total);
event UnstakeOnLocal(address indexed user, uint256 amount);
event SetAutoCompoundOnLocal(address indexed user, bool flag);
event CompoundMPOnLocal(address indexed user);
event CompoundAllOnLocal(address indexed user);
event SetStakingManagerOnLocal(address indexed manager);
function want() external view returns (IERC20);
function balances(address user) external view returns (uint256 balance);
function stake(uint256 _amount) external;
function stake(address _user, uint256 _amount) external;
function stakeForUsers(address[] memory _users, uint256[] memory _amounts, uint256 _total) external;
function unstake(uint256 _amount) external;
function unstakeAll() external;
function setAutoCompound(bool _flag) external;
function compoundMP() external;
function compoundAll() external;
}
文件 9 的 14:IWooStakingManager.sol
pragma solidity 0.8.17;
interface IWooStakingManager {
event StakeWooOnStakingManager(address indexed user, uint256 amount);
event UnstakeWooOnStakingManager(address indexed user, uint256 amount);
event AddMPOnStakingManager(address indexed user, uint256 amount);
event CompoundMPOnStakingManager(address indexed user);
event CompoundRewardsOnStakingManager(address indexed user, uint256 wooAmount);
event CompoundAllOnStakingManager(address indexed user);
event CompoundAllForUsersOnStakingManager(address[] users, uint256[] wooRewards);
event SetAutoCompoundOnStakingManager(address indexed user, bool flag);
event SetMPRewarderOnStakingManager(address indexed rewarder);
event SetWooPPOnStakingManager(address indexed wooPP);
event SetStakingLocalOnStakingManager(address indexed stakingProxy);
event SetCompounderOnStakingManager(address indexed compounder);
event AddRewarderOnStakingManager(address indexed rewarder);
event RemoveRewarderOnStakingManager(address indexed rewarder);
event ClaimRewardsOnStakingManager(address indexed user);
function stakeWoo(address _user, uint256 _amount) external;
function unstakeWoo(address _user, uint256 _amount) external;
function mpBalance(address _user) external view returns (uint256);
function wooBalance(address _user) external view returns (uint256);
function wooTotalBalance() external view returns (uint256);
function totalBalance(address _user) external view returns (uint256);
function totalBalance() external view returns (uint256);
function compoundMP(address _user) external;
function addMP(address _user, uint256 _amount) external;
function compoundRewards(address _user) external;
function compoundAll(address _user) external;
function compoundAllForUsers(address[] memory _users) external;
function setAutoCompound(address _user, bool _flag) external;
function pendingRewards(
address _user
) external view returns (uint256 mpRewardAmount, address[] memory rewardTokens, uint256[] memory amounts);
}
文件 10 的 14:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 11 的 14:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 12 的 14:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
}
文件 13 的 14:TransferHelper.sol
pragma solidity ^0.8.0;
library TransferHelper {
function safeApprove(address token, address to, uint256 value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper::safeApprove: approve failed"
);
}
function safeTransfer(address token, address to, uint256 value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper::safeTransfer: transfer failed"
);
}
function safeTransferFrom(address token, address from, address to, uint256 value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper::transferFrom: transferFrom failed"
);
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, "TransferHelper::safeTransferETH: ETH transfer failed");
}
}
文件 14 的 14:WooStakingManager.sol
pragma solidity ^0.8.4;
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import {IRewarder} from "./interfaces/IRewarder.sol";
import {IWooStakingCompounder} from "./interfaces/IWooStakingCompounder.sol";
import {IWooPPV2} from "./interfaces/IWooPPV2.sol";
import {IWooStakingManager} from "./interfaces/IWooStakingManager.sol";
import {IWooStakingLocal} from "./interfaces/IWooStakingLocal.sol";
import {BaseAdminOperation} from "./BaseAdminOperation.sol";
import {TransferHelper} from "./util/TransferHelper.sol";
contract WooStakingManager is IWooStakingManager, BaseAdminOperation, ReentrancyGuard {
using EnumerableSet for EnumerableSet.AddressSet;
mapping(address => uint256) public wooBalance;
mapping(address => uint256) public mpBalance;
uint256 public wooTotalBalance;
uint256 public mpTotalBalance;
EnumerableSet.AddressSet private stakers;
IWooPPV2 public wooPP;
IWooStakingLocal public stakingLocal;
address public immutable woo;
IRewarder public mpRewarder;
EnumerableSet.AddressSet private rewarders;
IWooStakingCompounder public compounder;
constructor(address _woo) {
woo = _woo;
}
modifier onlyMpRewarder() {
require(address(mpRewarder) == msg.sender, "RESTRICTED_TO_MP_REWARDER");
_;
}
function stakeWoo(address _user, uint256 _amount) public onlyAdmin {
if (_amount == 0) {
return;
}
_updateRewardsForUser(_user);
mpRewarder.claim(_user);
wooBalance[_user] += _amount;
wooTotalBalance += _amount;
_clearRewardsToDebt(_user);
if (_amount > 0) {
stakers.add(_user);
}
emit StakeWooOnStakingManager(_user, _amount);
}
function unstakeWoo(address _user, uint256 _amount) public onlyAdmin {
if (_amount == 0) {
return;
}
_updateRewardsForUser(_user);
mpRewarder.claim(_user);
uint256 wooPrevBalance = wooBalance[_user];
wooBalance[_user] -= _amount;
wooTotalBalance -= _amount;
uint256 burnAmount = (mpBalance[_user] * _amount) / wooPrevBalance;
mpBalance[_user] -= burnAmount;
mpTotalBalance -= burnAmount;
_clearRewardsToDebt(_user);
compounder.removeUserIfThresholdFail(_user);
if (wooBalance[_user] == 0) {
stakers.remove(_user);
}
emit UnstakeWooOnStakingManager(_user, _amount);
}
function _updateRewardsForUser(address _user) internal {
mpRewarder.updateRewardForUser(_user);
unchecked {
for (uint256 i = 0; i < rewarders.length(); ++i) {
IRewarder(rewarders.at(i)).updateRewardForUser(_user);
}
}
}
function _clearRewardsToDebt(address _user) internal {
mpRewarder.clearRewardToDebt(_user);
unchecked {
for (uint256 i = 0; i < rewarders.length(); ++i) {
IRewarder(rewarders.at(i)).clearRewardToDebt(_user);
}
}
}
function totalBalance(address _user) external view returns (uint256) {
return wooBalance[_user] + mpBalance[_user];
}
function totalBalance() external view returns (uint256) {
return wooTotalBalance + mpTotalBalance;
}
function pendingRewards(
address _user
) external view returns (uint256 mpRewardAmount, address[] memory rewardTokens, uint256[] memory amounts) {
mpRewardAmount = mpRewarder.pendingReward(_user);
uint256 length = rewarders.length();
rewardTokens = new address[](length);
amounts = new uint256[](length);
unchecked {
for (uint256 i = 0; i < length; ++i) {
IRewarder _rewarder = IRewarder(rewarders.at(i));
rewardTokens[i] = _rewarder.rewardToken();
amounts[i] = _rewarder.pendingReward(_user);
}
}
}
function claimRewards() external nonReentrant {
address _user = msg.sender;
require(!compounder.contains(_user), "WooStakingManager: !COMPOUND");
_claim(_user);
}
function claimRewards(address _user) external onlyAdmin {
_claim(_user);
}
function _claim(address _user) internal {
for (uint256 i = 0; i < rewarders.length(); ++i) {
IRewarder _rewarder = IRewarder(rewarders.at(i));
_rewarder.claim(_user);
}
emit ClaimRewardsOnStakingManager(_user);
}
function setAutoCompound(address _user, bool _flag) external onlyAdmin {
if (_flag) {
compounder.addUserIfThresholdMeet(_user);
} else {
compounder.removeUser(_user);
}
emit SetAutoCompoundOnStakingManager(_user, _flag);
}
function compoundAll(address _user) external onlyAdmin {
compoundMP(_user);
compoundRewards(_user);
emit CompoundAllOnStakingManager(_user);
}
function compoundAllForUsers(address[] memory _users) external onlyAdmin {
uint256 len = _users.length;
unchecked {
for (uint256 i = 0; i < len; ++i) {
compoundMP(_users[i]);
}
}
uint256[] memory rewards = new uint256[](len);
address selfAddr = address(this);
uint256[] memory wooRewards = new uint256[](len);
uint256 wooTotalAmount = 0;
uint256 rewarderLen = rewarders.length();
for (uint256 i = 0; i < rewarderLen; ++i) {
uint256 totalReward = 0;
IRewarder _rewarder = IRewarder(rewarders.at(i));
for (uint256 j = 0; j < len; ++j) {
uint256 rewardAmount = _rewarder.claim(_users[j], address(wooPP));
rewards[j] = rewardAmount;
totalReward += rewardAmount;
}
uint256 rewarderTotalWoo = 0;
address rewardToken = _rewarder.rewardToken();
if (rewardToken == woo) {
rewarderTotalWoo = totalReward;
} else {
rewarderTotalWoo = wooPP.swap(rewardToken, woo, totalReward, 0, selfAddr, selfAddr);
}
for (uint256 j = 0; j < len; ++j) {
wooRewards[j] += (rewarderTotalWoo * rewards[j]) / totalReward;
}
wooTotalAmount += rewarderTotalWoo;
}
if (wooTotalAmount > 0) {
TransferHelper.safeApprove(woo, address(stakingLocal), wooTotalAmount);
stakingLocal.stakeForUsers(_users, wooRewards, wooTotalAmount);
}
emit CompoundAllForUsersOnStakingManager(_users, wooRewards);
}
function compoundMP(address _user) public onlyAdmin {
uint256 i;
uint256 len = rewarders.length();
unchecked {
for (i = 0; i < len; ++i) {
IRewarder(rewarders.at(i)).updateRewardForUser(_user);
}
}
mpRewarder.claim(_user);
unchecked {
for (i = 0; i < len; ++i) {
IRewarder(rewarders.at(i)).clearRewardToDebt(_user);
}
}
emit CompoundMPOnStakingManager(_user);
}
function addMP(address _user, uint256 _amount) public onlyMpRewarder {
mpBalance[_user] += _amount;
mpTotalBalance += _amount;
emit AddMPOnStakingManager(_user, _amount);
}
function compoundRewards(address _user) public onlyAdmin {
uint256 wooAmount = 0;
address selfAddr = address(this);
uint256 len = rewarders.length();
for (uint256 i = 0; i < len; ++i) {
IRewarder _rewarder = IRewarder(rewarders.at(i));
if (_rewarder.rewardToken() == woo) {
wooAmount += _rewarder.claim(_user, selfAddr);
} else {
uint256 rewardAmount = _rewarder.claim(_user, address(wooPP));
if (rewardAmount > 0) {
wooAmount += wooPP.swap(_rewarder.rewardToken(), woo, rewardAmount, 0, selfAddr, selfAddr);
}
}
}
if (wooAmount > 0) {
TransferHelper.safeApprove(woo, address(stakingLocal), wooAmount);
stakingLocal.stake(_user, wooAmount);
}
emit CompoundRewardsOnStakingManager(_user, wooAmount);
}
function syncBalances(address[] memory _users, uint256[] memory _balances) external onlyAdmin {
require(_users.length == _balances.length, "WooStakingManager: INVALID_INPUTS");
uint256 len = _users.length;
address user;
uint256 balance;
uint256 prevBalance;
unchecked {
for (uint256 i = 0; i < len; ++i) {
user = _users[i];
balance = _balances[i];
prevBalance = wooBalance[user];
if (balance > prevBalance) {
stakeWoo(user, balance - prevBalance);
} else if (balance < prevBalance) {
unstakeWoo(user, prevBalance - balance);
}
}
}
}
function allStakersLength() external view returns (uint256) {
return stakers.length();
}
function allStakers() external view returns (address[] memory) {
uint256 len = stakers.length();
address[] memory _stakers = new address[](len);
unchecked {
for (uint256 i = 0; i < len; ++i) {
_stakers[i] = stakers.at(i);
}
}
return _stakers;
}
function allStakers(uint256 start, uint256 end) external view returns (address[] memory) {
address[] memory _stakers = new address[](end - start);
unchecked {
for (uint256 i = start; i < end; ++i) {
_stakers[i - start] = stakers.at(i);
}
}
return _stakers;
}
function setMPRewarder(address _rewarder) external onlyAdmin {
mpRewarder = IRewarder(_rewarder);
require(address(IRewarder(_rewarder).stakingManager()) == address(this), "!stakingManager");
emit SetMPRewarderOnStakingManager(_rewarder);
}
function addRewarder(address _rewarder) external onlyAdmin {
require(address(IRewarder(_rewarder).stakingManager()) == address(this), "!stakingManager");
rewarders.add(_rewarder);
emit AddRewarderOnStakingManager(_rewarder);
}
function removeRewarder(address _rewarder) external onlyAdmin {
rewarders.remove(_rewarder);
emit RemoveRewarderOnStakingManager(_rewarder);
}
function setCompounder(address _compounder) external onlyAdmin {
if (address(compounder) != address(0)) {
setAdmin(address(compounder), false);
}
compounder = IWooStakingCompounder(_compounder);
setAdmin(_compounder, true);
emit SetCompounderOnStakingManager(_compounder);
}
function setWooPP(address _wooPP) external onlyOwner {
wooPP = IWooPPV2(_wooPP);
emit SetWooPPOnStakingManager(_wooPP);
}
function setStakingLocal(address _stakingLocal) external onlyOwner {
if (address(stakingLocal) != address(0)) {
setAdmin(address(stakingLocal), false);
}
stakingLocal = IWooStakingLocal(_stakingLocal);
setAdmin(_stakingLocal, true);
emit SetStakingLocalOnStakingManager(_stakingLocal);
}
}
{
"compilationTarget": {
"contracts/WooStakingManager.sol": "WooStakingManager"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 20000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_woo","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AddMPOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rewarder","type":"address"}],"name":"AddRewarderOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"flag","type":"bool"}],"name":"AdminUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"ClaimRewardsOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"users","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"wooRewards","type":"uint256[]"}],"name":"CompoundAllForUsersOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"CompoundAllOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"CompoundMPOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"wooAmount","type":"uint256"}],"name":"CompoundRewardsOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rewarder","type":"address"}],"name":"RemoveRewarderOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"flag","type":"bool"}],"name":"SetAutoCompoundOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"compounder","type":"address"}],"name":"SetCompounderOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rewarder","type":"address"}],"name":"SetMPRewarderOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingProxy","type":"address"}],"name":"SetStakingLocalOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wooPP","type":"address"}],"name":"SetWooPPOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeWooOnStakingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UnstakeWooOnStakingManager","type":"event"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addMP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewarder","type":"address"}],"name":"addRewarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"allStakers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allStakers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allStakersLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"compoundAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"compoundAllForUsers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"compoundMP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"compoundRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"compounder","outputs":[{"internalType":"contract IWooStakingCompounder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stuckToken","type":"address"}],"name":"inCaseTokenGotStuck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mpBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mpRewarder","outputs":[{"internalType":"contract IRewarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mpTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingRewards","outputs":[{"internalType":"uint256","name":"mpRewardAmount","type":"uint256"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewarder","type":"address"}],"name":"removeRewarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"flag","type":"bool"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"setAutoCompound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_compounder","type":"address"}],"name":"setCompounder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewarder","type":"address"}],"name":"setMPRewarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingLocal","type":"address"}],"name":"setStakingLocal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wooPP","type":"address"}],"name":"setWooPP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeWoo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingLocal","outputs":[{"internalType":"contract IWooStakingLocal","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint256[]","name":"_balances","type":"uint256[]"}],"name":"syncBalances","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"totalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unstakeWoo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"woo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wooBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wooPP","outputs":[{"internalType":"contract IWooPPV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wooTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]