Source Code
Overview
MNT Balance
MNT Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
MasterChef
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import {Math} from "./libraries/Math.sol";
import {Rewarder} from "./libraries/Rewarder.sol";
import {Constants} from "./libraries/Constants.sol";
import {Amounts} from "./libraries/Amounts.sol";
import {IMoe} from "./interfaces/IMoe.sol";
import {IVeMoe} from "./interfaces/IVeMoe.sol";
import {IMasterChef} from "./interfaces/IMasterChef.sol";
import {IMasterChefRewarder} from "./interfaces/IMasterChefRewarder.sol";
import {IRewarderFactory, IBaseRewarder} from "./interfaces/IRewarderFactory.sol";
/**
* @title Master Chef Contract
* @dev The MasterChef allows users to deposit tokens to earn MOE tokens distributed as liquidity mining rewards.
* The MOE token is minted by the MasterChef contract and distributed to the users.
* A share of the rewards is sent to the treasury.
* The weight of each pool is determined by the amount of votes in the VeMOE contract and by the top pool ids.
* On top of the MOE rewards, the MasterChef can also distribute extra rewards in other tokens using extra rewarders.
*/
contract MasterChef is Ownable2StepUpgradeable, IMasterChef {
using SafeERC20 for IERC20;
using SafeERC20 for IMoe;
using Math for uint256;
using Rewarder for Rewarder.Parameter;
using Amounts for Amounts.Parameter;
IMoe private immutable _moe;
IVeMoe private immutable _veMoe;
IRewarderFactory private immutable _rewarderFactory;
address private immutable _lbHooksManager;
uint256 private immutable _treasuryShare;
address private _treasury;
address private _gap0; // unused, but needed for the storage layout to be the same as the previous contract
address private _gap1; // unused, but needed for the storage layout to be the same as the previous contract
uint96 private _moePerSecond;
Farm[] private _farms;
/**
* @dev Constructor for the MasterChef contract.
* @param moe The address of the MOE token.
* @param veMoe The address of the VeMOE contract.
* @param rewarderFactory The address of the rewarder factory.
* @param lbHooksManager The address of the LB hooks manager.
* @param treasuryShare The share of the rewards that will be sent to the treasury.
*/
constructor(
IMoe moe,
IVeMoe veMoe,
IRewarderFactory rewarderFactory,
address lbHooksManager,
uint256 treasuryShare
) {
_disableInitializers();
if (treasuryShare > Constants.PRECISION) revert MasterChef__InvalidShares();
_moe = moe;
_veMoe = veMoe;
_rewarderFactory = rewarderFactory;
_lbHooksManager = lbHooksManager;
_treasuryShare = treasuryShare;
}
/**
* @dev Initializes the MasterChef contract.
* @param initialOwner The initial owner of the contract.
* @param treasury The initial treasury.
* @param futureFunding The address of the future funding vesting contract.
* @param team The address of the team vesting contract.
* @param futureFundingAmount The amount of MOE tokens to pre-mint for the future funding vesting contract.
* @param teamAmount The amount of MOE tokens to pre-mint for the team vesting contract.
*/
function initialize(
address initialOwner,
address treasury,
address futureFunding,
address team,
uint256 futureFundingAmount,
uint256 teamAmount
) external reinitializer(2) {
__Ownable_init(initialOwner);
_setTreasury(treasury);
uint256 mintedToFutureFunding =
futureFundingAmount > 0 ? _moe.mint(address(futureFunding), futureFundingAmount) : 0;
uint256 mintedToTeam = teamAmount > 0 ? _moe.mint(address(team), teamAmount) : 0;
if (mintedToFutureFunding != futureFundingAmount || mintedToTeam != teamAmount) {
revert MasterChef__MintFailed();
}
}
/**
* @dev Returns the address of the MOE token.
* @return The address of the MOE token.
*/
function getMoe() external view override returns (IMoe) {
return _moe;
}
/**
* @dev Returns the address of the VeMOE contract.
* @return The address of the VeMOE contract.
*/
function getVeMoe() external view override returns (IVeMoe) {
return _veMoe;
}
/**
* @dev Returns the address of the rewarder factory.
* @return The address of the rewarder factory.
*/
function getRewarderFactory() external view override returns (IRewarderFactory) {
return _rewarderFactory;
}
/**
* @dev Returns the address of the LB hooks manager.
* @return The address of the LB hooks manager.
*/
function getLBHooksManager() external view override returns (address) {
return _lbHooksManager;
}
/**
* @dev Returns the address of the treasury.
* @return The address of the treasury.
*/
function getTreasury() external view override returns (address) {
return _treasury;
}
/**
* @dev Returns the share of the rewards that will be sent to the treasury.
* @return The share of the rewards that will be sent to the treasury.
*/
function getTreasuryShare() external view override returns (uint256) {
return _treasuryShare;
}
/**
* @dev Returns the number of farms.
* @return The number of farms.
*/
function getNumberOfFarms() external view override returns (uint256) {
return _farms.length;
}
/**
* @dev Returns the deposit amount of an account on a farm.
* @param pid The pool ID of the farm.
* @param account The account to check for the deposit amount.
* @return The deposit amount of the account on the farm.
*/
function getDeposit(uint256 pid, address account) external view override returns (uint256) {
return _farms[pid].amounts.getAmountOf(account);
}
/**
* @dev Returns the total deposit amount of a farm.
* @param pid The pool ID of the farm.
* @return The total deposit amount of the farm.
*/
function getTotalDeposit(uint256 pid) external view override returns (uint256) {
return _farms[pid].amounts.getTotalAmount();
}
/**
* @dev Returns the pending rewards for a given account on a list of farms.
* @param account The account to check for pending rewards.
* @param pids The pool IDs of the farms.
* @return moeRewards The MOE rewards for the account on the farms.
* @return extraTokens The extra tokens from the extra rewarders.
* @return extraRewards The extra rewards amounts from the extra rewarders.
*/
function getPendingRewards(address account, uint256[] calldata pids)
external
view
override
returns (uint256[] memory moeRewards, IERC20[] memory extraTokens, uint256[] memory extraRewards)
{
moeRewards = new uint256[](pids.length);
extraTokens = new IERC20[](pids.length);
extraRewards = new uint256[](pids.length);
for (uint256 i; i < pids.length; ++i) {
uint256 pid = pids[i];
Farm storage farm = _farms[pid];
Rewarder.Parameter storage rewarder = farm.rewarder;
Amounts.Parameter storage amounts = farm.amounts;
uint256 balance = amounts.getAmountOf(account);
uint256 totalSupply = amounts.getTotalAmount();
{
(, uint256 moeRewardForPid) = _calculateAmounts(_getRewardForPid(rewarder, pid, totalSupply));
moeRewards[i] = rewarder.getPendingReward(account, balance, totalSupply, moeRewardForPid);
}
IMasterChefRewarder extraRewarder = farm.extraRewarder;
if (address(extraRewarder) != address(0)) {
(extraTokens[i], extraRewards[i]) = extraRewarder.getPendingReward(account, balance, totalSupply);
}
}
}
/**
* @dev Returns the token of a farm.
* @param pid The pool ID of the farm.
* @return The token of the farm.
*/
function getToken(uint256 pid) external view override returns (IERC20) {
return _farms[pid].token;
}
/**
* @dev Returns the last update timestamp of a farm.
* @param pid The pool ID of the farm.
* @return The last update timestamp of the farm.
*/
function getLastUpdateTimestamp(uint256 pid) external view override returns (uint256) {
return _farms[pid].rewarder.lastUpdateTimestamp;
}
/**
* @dev Returns the extra rewarder of a farm.
* @param pid The pool ID of the farm.
* @return The extra rewarder of the farm.
*/
function getExtraRewarder(uint256 pid) external view override returns (IMasterChefRewarder) {
return _farms[pid].extraRewarder;
}
/**
* @dev Returns the MOE per second.
* @return The MOE per second.
*/
function getMoePerSecond() external view override returns (uint256) {
return _moePerSecond;
}
/**
* @dev Returns the MOE per second for a given pool ID.
* If the pool ID is not in the top pool IDs, it will return 0.
* Else, it will return the MOE per second multiplied by the weight of the pool ID over the total weight.
* @param pid The pool ID.
* @return The MOE per second for the pool ID.
*/
function getMoePerSecondForPid(uint256 pid) external view override returns (uint256) {
return _getRewardForPid(pid, _moePerSecond, _veMoe.getTotalWeight());
}
/**
* @dev Deposits tokens to a farm.
* @param pid The pool ID of the farm.
* @param amount The amount of tokens to deposit.
*/
function deposit(uint256 pid, uint256 amount) external override {
_modify(pid, msg.sender, amount.toInt256());
if (amount > 0) _farms[pid].token.safeTransferFrom(msg.sender, address(this), amount);
}
/**
* @dev Withdraws tokens from a farm.
* @param pid The pool ID of the farm.
* @param amount The amount of tokens to withdraw.
*/
function withdraw(uint256 pid, uint256 amount) external override {
_modify(pid, msg.sender, -amount.toInt256());
if (amount > 0) _farms[pid].token.safeTransfer(msg.sender, amount);
}
/**
* @dev Claims the rewards from a list of farms.
* @param pids The pool IDs of the farms.
*/
function claim(uint256[] calldata pids) external override {
for (uint256 i; i < pids.length; ++i) {
_modify(pids[i], msg.sender, 0);
}
}
/**
* @dev Emergency withdraws tokens from a farm, without claiming any rewards.
* @param pid The pool ID of the farm.
*/
function emergencyWithdraw(uint256 pid) external override {
Farm storage farm = _farms[pid];
uint256 balance = farm.amounts.getAmountOf(msg.sender);
int256 deltaAmount = -balance.toInt256();
farm.amounts.update(msg.sender, deltaAmount);
farm.token.safeTransfer(msg.sender, balance);
emit PositionModified(pid, msg.sender, deltaAmount, 0);
}
/**
* @dev Updates all the farms in the pids list.
* @param pids The pool IDs to update.
*/
function updateAll(uint256[] calldata pids) external override {
_updateAll(pids);
}
/**
* @dev Sets the MOE per second.
* It will update all the farms that are in the top pool IDs.
* @param moePerSecond The new MOE per second.
*/
function setMoePerSecond(uint96 moePerSecond) external override onlyOwner {
if (moePerSecond > Constants.MAX_MOE_PER_SECOND) revert MasterChef__InvalidMoePerSecond();
_updateAll(_veMoe.getTopPoolIds());
_moePerSecond = moePerSecond;
emit MoePerSecondSet(moePerSecond);
}
/**
* @dev Adds a farm.
* @param token The token of the farm.
* @param extraRewarder The extra rewarder of the farm.
*/
function add(IERC20 token, IMasterChefRewarder extraRewarder) external override {
if (msg.sender != address(_lbHooksManager)) _checkOwner();
uint256 pid = _farms.length;
Farm storage farm = _farms.push();
farm.token = token;
farm.rewarder.lastUpdateTimestamp = block.timestamp;
if (address(extraRewarder) != address(0)) _setExtraRewarder(pid, extraRewarder);
token.balanceOf(address(this)); // sanity check
emit FarmAdded(pid, token);
}
/**
* @dev Sets the extra rewarder of a farm.
* @param pid The pool ID of the farm.
* @param extraRewarder The new extra rewarder of the farm.
*/
function setExtraRewarder(uint256 pid, IMasterChefRewarder extraRewarder) external override onlyOwner {
_setExtraRewarder(pid, extraRewarder);
}
/**
* @dev Sets the treasury.
* @param treasury The new treasury.
*/
function setTreasury(address treasury) external override onlyOwner {
_setTreasury(treasury);
}
/**
* @dev Blocks the renouncing of ownership.
*/
function renounceOwnership() public pure override {
revert MasterChef__CannotRenounceOwnership();
}
/**
* @dev Returns the reward for a given pool ID.
* If the pool ID is not in the top pool IDs, it will return 0.
* Else, it will return the reward multiplied by the weight of the pool ID over the total weight.
* @param rewarder The storage pointer to the rewarder.
* @param pid The pool ID.
* @param totalSupply The total supply.
* @return The reward for the pool ID.
*/
function _getRewardForPid(Rewarder.Parameter storage rewarder, uint256 pid, uint256 totalSupply)
private
view
returns (uint256)
{
return _getRewardForPid(pid, rewarder.getTotalRewards(_moePerSecond, totalSupply), _veMoe.getTotalWeight());
}
/**
* @dev Returns the reward for a given pool ID.
* If the pool ID is not in the top pool IDs, it will return 0.
* Else, it will return the reward multiplied by the weight of the pool ID over the total weight.
* @param pid The pool ID.
* @param totalRewards The total rewards.
* @param totalWeight The total weight.
* @return The reward for the pool ID.
*/
function _getRewardForPid(uint256 pid, uint256 totalRewards, uint256 totalWeight) private view returns (uint256) {
return totalWeight == 0 ? 0 : totalRewards * _veMoe.getWeight(pid) / totalWeight;
}
/**
* @dev Sets the extra rewarder of a farm.
* Will call link/unlink to make sure the rewarders are properly set/unset.
* It is very important that a rewarder that was previously linked can't be linked again.
* @param pid The pool ID of the farm.
* @param extraRewarder The new extra rewarder of the farm.
*/
function _setExtraRewarder(uint256 pid, IMasterChefRewarder extraRewarder) private {
if (
address(extraRewarder) != address(0)
&& _rewarderFactory.getRewarderType(extraRewarder) != IRewarderFactory.RewarderType.MasterChefRewarder
) {
revert MasterChef__NotMasterchefRewarder();
}
IMasterChefRewarder oldExtraRewarder = _farms[pid].extraRewarder;
if (address(oldExtraRewarder) != address(0)) oldExtraRewarder.unlink(pid);
if (address(extraRewarder) != address(0)) extraRewarder.link(pid);
_farms[pid].extraRewarder = extraRewarder;
emit ExtraRewarderSet(pid, extraRewarder);
}
/**
* @dev Updates all the farms in the pids list.
* @param pids The pool IDs to update.
*/
function _updateAll(uint256[] memory pids) private {
uint256 length = pids.length;
uint256 totalWeight = _veMoe.getTotalWeight();
uint256 moePerSecond = _moePerSecond;
for (uint256 i; i < length; ++i) {
uint256 pid = pids[i];
Farm storage farm = _farms[pid];
Rewarder.Parameter storage rewarder = farm.rewarder;
uint256 totalSupply = farm.amounts.getTotalAmount();
uint256 totalRewards = rewarder.getTotalRewards(moePerSecond, totalSupply);
uint256 totalMoeRewardForPid = _getRewardForPid(pid, totalRewards, totalWeight);
uint256 moeRewardForPid = _mintMoe(totalMoeRewardForPid);
rewarder.updateAccDebtPerShare(totalSupply, moeRewardForPid);
}
}
/**
* @dev Modifies the position of an account on a farm.
* @param pid The pool ID of the farm.
* @param account The account to modify the position of.
* @param deltaAmount The delta amount to modify the position with.
*/
function _modify(uint256 pid, address account, int256 deltaAmount) private {
Farm storage farm = _farms[pid];
Rewarder.Parameter storage rewarder = farm.rewarder;
IMasterChefRewarder extraRewarder = farm.extraRewarder;
(uint256 oldBalance, uint256 newBalance, uint256 oldTotalSupply,) = farm.amounts.update(account, deltaAmount);
uint256 totalMoeRewardForPid = _getRewardForPid(rewarder, pid, oldTotalSupply);
uint256 moeRewardForPid = _mintMoe(totalMoeRewardForPid);
uint256 moeReward = rewarder.update(account, oldBalance, newBalance, oldTotalSupply, moeRewardForPid);
if (moeReward > 0) _moe.safeTransfer(account, moeReward);
if (address(extraRewarder) != address(0)) {
extraRewarder.onModify(account, pid, oldBalance, newBalance, oldTotalSupply);
}
emit PositionModified(pid, account, deltaAmount, moeReward);
}
/**
* @dev Sets the treasury.
* @param treasury The new treasury.
*/
function _setTreasury(address treasury) private {
if (treasury == address(0)) revert MasterChef__ZeroAddress();
_treasury = treasury;
emit TreasurySet(treasury);
}
/**
* @dev Mints MOE tokens to the treasury and to this contract.
* @param amount The amount of MOE tokens to mint.
* @return The amount of MOE tokens minted for liquidity mining.
*/
function _mintMoe(uint256 amount) private returns (uint256) {
if (amount == 0) return 0;
(uint256 treasuryAmount, uint256 liquidityMiningAmount) = _calculateAmounts(amount);
_moe.mint(_treasury, treasuryAmount);
return _moe.mint(address(this), liquidityMiningAmount);
}
/**
* @dev Calculates the amounts of MOE tokens to mint for each recipient.
* @param amount The amount of MOE tokens to mint.
* @return treasuryAmount The amount of MOE tokens to mint for the treasury.
* @return liquidityMiningAmount The amount of MOE tokens to mint for liquidity mining.
*/
function _calculateAmounts(uint256 amount)
private
view
returns (uint256 treasuryAmount, uint256 liquidityMiningAmount)
{
treasuryAmount = amount * _treasuryShare / Constants.PRECISION;
liquidityMiningAmount = amount - treasuryAmount;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../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 Address for address;
/**
* @dev An operation with an ERC20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @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);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @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).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// 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 cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.20;
import {OwnableUpgradeable} from "./OwnableUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is specified at deployment time in the constructor for `Ownable`. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable2Step
struct Ownable2StepStorage {
address _pendingOwner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable2Step")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant Ownable2StepStorageLocation = 0x237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00;
function _getOwnable2StepStorage() private pure returns (Ownable2StepStorage storage $) {
assembly {
$.slot := Ownable2StepStorageLocation
}
}
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
function __Ownable2Step_init() internal onlyInitializing {
}
function __Ownable2Step_init_unchained() internal onlyInitializing {
}
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
return $._pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
$._pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
delete $._pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
if (pendingOwner() != sender) {
revert OwnableUnauthorizedAccount(sender);
}
_transferOwnership(sender);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title Math
* @dev Library for mathematical operations with overflow and underflow checks.
*/
library Math {
error Math__UnderOverflow();
uint256 internal constant MAX_INT256 = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
/**
* @dev Adds a signed integer to an unsigned integer with overflow check.
* The result must be greater than or equal to 0 and less than or equal to MAX_INT256.
* @param x Unsigned integer to add to.
* @param delta Signed integer to add.
* @return y The result of the addition.
*/
function addDelta(uint256 x, int256 delta) internal pure returns (uint256 y) {
uint256 success;
assembly {
y := add(x, delta)
success := iszero(or(gt(x, MAX_INT256), gt(y, MAX_INT256)))
}
if (success == 0) revert Math__UnderOverflow();
}
/**
* @dev Safely converts an unsigned integer to a signed integer.
* @param x Unsigned integer to convert.
* @return y Signed integer result.
*/
function toInt256(uint256 x) internal pure returns (int256 y) {
if (x > MAX_INT256) revert Math__UnderOverflow();
return int256(x);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Amounts} from "./Amounts.sol";
import {Constants} from "./Constants.sol";
/**
* @title Rewarder Library
* @dev A library that defines various functions for calculating rewards.
* It takes care about the reward debt and the accumulated debt per share.
* The version 2 should be used as it offers more precision and avoid potential rounding errors.
*/
library Rewarder {
using Amounts for Amounts.Parameter;
struct Parameter {
uint256 lastUpdateTimestamp;
uint256 accDebtPerShare;
mapping(address => uint256) debt;
}
/**
* @dev Returns the debt associated with an amount.
* @param accDebtPerShare The accumulated debt per share.
* @param deposit The amount.
* @return The debt associated with the amount.
*/
function getDebt(uint256 accDebtPerShare, uint256 deposit) internal pure returns (uint256) {
return (deposit * accDebtPerShare) >> Constants.ACC_PRECISION_BITS;
}
/**
* @dev Returns the debt per share associated with a total deposit and total rewards.
* @param totalDeposit The total deposit.
* @param totalRewards The total rewards.
* @return The debt per share associated with the total deposit and total rewards.
*/
function getDebtPerShare(uint256 totalDeposit, uint256 totalRewards) internal pure returns (uint256) {
return totalDeposit == 0 ? 0 : (totalRewards << Constants.ACC_PRECISION_BITS) / totalDeposit;
}
/**
* @dev Returns the total rewards to emit.
* If the end timestamp is in the past, the rewards are calculated up to the end timestamp.
* If the last update timestamp is in the future, it will return 0.
* @param rewarder The storage pointer to the rewarder.
* @param rewardPerSecond The reward per second.
* @param endTimestamp The end timestamp.
* @param totalSupply The total supply.
* @return The total rewards.
*/
function getTotalRewards(
Parameter storage rewarder,
uint256 rewardPerSecond,
uint256 endTimestamp,
uint256 totalSupply
) internal view returns (uint256) {
if (totalSupply == 0) return 0;
uint256 lastUpdateTimestamp = rewarder.lastUpdateTimestamp;
uint256 timestamp = block.timestamp > endTimestamp ? endTimestamp : block.timestamp;
return timestamp > lastUpdateTimestamp ? (timestamp - lastUpdateTimestamp) * rewardPerSecond : 0;
}
/**
* @dev Returns the total rewards to emit.
* @param rewarder The storage pointer to the rewarder.
* @param rewardPerSecond The reward per second.
* @param totalSupply The total supply.
* @return The total rewards.
*/
function getTotalRewards(Parameter storage rewarder, uint256 rewardPerSecond, uint256 totalSupply)
internal
view
returns (uint256)
{
return getTotalRewards(rewarder, rewardPerSecond, block.timestamp, totalSupply);
}
/**
* @dev Returns the pending reward of an account.
* @param rewarder The storage pointer to the rewarder.
* @param amounts The storage pointer to the amounts.
* @param account The address of the account.
* @param totalRewards The total rewards.
* @return The pending reward of the account.
*/
function getPendingReward(
Parameter storage rewarder,
Amounts.Parameter storage amounts,
address account,
uint256 totalRewards
) internal view returns (uint256) {
return getPendingReward(rewarder, account, amounts.getAmountOf(account), amounts.getTotalAmount(), totalRewards);
}
/**
* @dev Returns the pending reward of an account.
* If the balance of the account is 0, it will always return 0.
* @param rewarder The storage pointer to the rewarder.
* @param account The address of the account.
* @param balance The balance of the account.
* @param totalSupply The total supply.
* @param totalRewards The total rewards.
* @return The pending reward of the account.
*/
function getPendingReward(
Parameter storage rewarder,
address account,
uint256 balance,
uint256 totalSupply,
uint256 totalRewards
) internal view returns (uint256) {
uint256 accDebtPerShare = rewarder.accDebtPerShare + getDebtPerShare(totalSupply, totalRewards);
return balance == 0 ? 0 : getDebt(accDebtPerShare, balance) - rewarder.debt[account];
}
/**
* @dev Updates the rewarder.
* If the balance of the account is 0, it will always return 0.
* @param rewarder The storage pointer to the rewarder.
* @param account The address of the account.
* @param oldBalance The old balance of the account.
* @param newBalance The new balance of the account.
* @param totalSupply The total supply.
* @param totalRewards The total rewards.
* @return rewards The rewards of the account.
*/
function update(
Parameter storage rewarder,
address account,
uint256 oldBalance,
uint256 newBalance,
uint256 totalSupply,
uint256 totalRewards
) internal returns (uint256 rewards) {
uint256 accDebtPerShare = updateAccDebtPerShare(rewarder, totalSupply, totalRewards);
rewards = oldBalance == 0 ? 0 : getDebt(accDebtPerShare, oldBalance) - rewarder.debt[account];
rewarder.debt[account] = getDebt(accDebtPerShare, newBalance);
}
/**
* @dev Updates the accumulated debt per share.
* If the last update timestamp is in the future, it will not update the last update timestamp.
* @param rewarder The storage pointer to the rewarder.
* @param totalSupply The total supply.
* @param totalRewards The total rewards.
* @return The accumulated debt per share.
*/
function updateAccDebtPerShare(Parameter storage rewarder, uint256 totalSupply, uint256 totalRewards)
internal
returns (uint256)
{
uint256 debtPerShare = getDebtPerShare(totalSupply, totalRewards);
if (block.timestamp > rewarder.lastUpdateTimestamp) rewarder.lastUpdateTimestamp = block.timestamp;
return debtPerShare == 0 ? rewarder.accDebtPerShare : rewarder.accDebtPerShare += debtPerShare;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title Constants Library
* @dev A library that defines various constants used throughout the codebase.
*/
library Constants {
uint256 internal constant ACC_PRECISION_BITS = 64;
uint256 internal constant PRECISION = 1e18;
uint8 internal constant NEW_ACC_PRECISION_BITS = 128;
uint256 internal constant MAX_NUMBER_OF_FARMS = 32;
uint256 internal constant MAX_NUMBER_OF_REWARDS = 32;
uint256 internal constant MAX_MOE_PER_SECOND = 10e18;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Math} from "./Math.sol";
/**
* @title Amounts Library
* @dev A library that defines various functions for manipulating amounts of a key and a total.
* The key can be bytes32, address, or uint256.
*/
library Amounts {
using Math for uint256;
struct Parameter {
uint256 totalAmount;
mapping(bytes32 => uint256) amounts;
}
/**
* @dev Returns the amount of a key.
* @param amounts The storage pointer to the amounts.
* @param key The key of the amount.
* @return The amount of the key.
*/
function getAmountOf(Parameter storage amounts, bytes32 key) internal view returns (uint256) {
return amounts.amounts[key];
}
/**
* @dev Returns the amount of an address.
* @param amounts The storage pointer to the amounts.
* @param account The address of the amount.
* @return The amount of the address.
*/
function getAmountOf(Parameter storage amounts, address account) internal view returns (uint256) {
return getAmountOf(amounts, bytes32(uint256(uint160(account))));
}
/**
* @dev Returns the amount of an id.
* @param amounts The storage pointer to the amounts.
* @param id The id of the amount.
* @return The amount of the id.
*/
function getAmountOf(Parameter storage amounts, uint256 id) internal view returns (uint256) {
return getAmountOf(amounts, bytes32(id));
}
/**
* @dev Returns the total amount.
* @param amounts The storage pointer to the amounts.
* @return The total amount.
*/
function getTotalAmount(Parameter storage amounts) internal view returns (uint256) {
return amounts.totalAmount;
}
/**
* @dev Updates the amount of a key. The delta is added to the key amount and the total amount.
* @param amounts The storage pointer to the amounts.
* @param key The key of the amount.
* @param deltaAmount The delta amount to update.
* @return oldAmount The old amount of the key.
* @return newAmount The new amount of the key.
* @return oldTotalAmount The old total amount.
* @return newTotalAmount The new total amount.
*/
function update(Parameter storage amounts, bytes32 key, int256 deltaAmount)
internal
returns (uint256 oldAmount, uint256 newAmount, uint256 oldTotalAmount, uint256 newTotalAmount)
{
oldAmount = amounts.amounts[key];
oldTotalAmount = amounts.totalAmount;
if (deltaAmount == 0) {
newAmount = oldAmount;
newTotalAmount = oldTotalAmount;
} else {
newAmount = oldAmount.addDelta(deltaAmount);
newTotalAmount = oldTotalAmount.addDelta(deltaAmount);
amounts.amounts[key] = newAmount;
amounts.totalAmount = newTotalAmount;
}
}
/**
* @dev Updates the amount of an address. The delta is added to the address amount and the total amount.
* @param amounts The storage pointer to the amounts.
* @param account The address of the amount.
* @param deltaAmount The delta amount to update.
* @return oldAmount The old amount of the key.
* @return newAmount The new amount of the key.
* @return oldTotalAmount The old total amount.
* @return newTotalAmount The new total amount.
*/
function update(Parameter storage amounts, address account, int256 deltaAmount)
internal
returns (uint256 oldAmount, uint256 newAmount, uint256 oldTotalAmount, uint256 newTotalAmount)
{
return update(amounts, bytes32(uint256(uint160(account))), deltaAmount);
}
/**
* @dev Updates the amount of an id. The delta is added to the id amount and the total amount.
* @param amounts The storage pointer to the amounts.
* @param id The id of the amount.
* @param deltaAmount The delta amount to update.
* @return oldAmount The old amount of the key.
* @return newAmount The new amount of the key.
* @return oldTotalAmount The old total amount.
* @return newTotalAmount The new total amount.
*/
function update(Parameter storage amounts, uint256 id, int256 deltaAmount)
internal
returns (uint256 oldAmount, uint256 newAmount, uint256 oldTotalAmount, uint256 newTotalAmount)
{
return update(amounts, bytes32(id), deltaAmount);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IMoe is IERC20 {
error Moe__NotMinter(address account);
error Moe__InvalidInitialSupply();
function getMinter() external view returns (address);
function getMaxSupply() external view returns (uint256);
function mint(address account, uint256 amount) external returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IVeMoeRewarder} from "./IVeMoeRewarder.sol";
import {IMoeStaking} from "./IMoeStaking.sol";
import {IMasterChef} from "./IMasterChef.sol";
import {Amounts} from "../libraries/Amounts.sol";
import {Rewarder} from "../libraries/Rewarder.sol";
import {IRewarderFactory} from "./IRewarderFactory.sol";
interface IVeMoe {
error VeMoe__InvalidLength();
error VeMoe__InsufficientVeMoe(uint256 totalVeMoe, uint256 requiredVeMoe);
error VeMoe__InvalidCaller();
error VeMoe__InvalidBribeAddress();
error VeMoe__InvalidPid(uint256 pid);
error VeMoe__InvalidWeight();
error VeMoe__InvalidAlpha();
error VeMoe__CannotUnstakeWithVotes();
error VeMoe__NoBribeForPid(uint256 pid);
error VeMoe__TooManyPoolIds();
error VeMoe__DuplicatePoolId(uint256 pid);
error VeMoe__CannotRenounceOwnership();
struct User {
uint256 veMoe;
Amounts.Parameter votes;
mapping(uint256 => IVeMoeRewarder) bribes;
}
struct Reward {
Rewarder.Parameter rewarder;
IERC20 token;
uint256 reserve;
}
struct BribeReward {
IVeMoeRewarder bribe;
uint256 rewardAmount;
}
event BribesSet(address indexed account, uint256[] pids, IVeMoeRewarder[] bribes);
event Claim(address indexed account, int256 deltaVeMoe);
event TopPoolIdsSet(uint256[] topPoolIds);
event Vote(address account, uint256[] pids, int256[] deltaVeAmounts);
event VeMoePerSecondPerMoeSet(uint256 veMoePerSecondPerMoe);
event AlphaSet(uint256 alpha);
function balanceOf(address account) external view returns (uint256 veMoe);
function claim(uint256[] memory pids) external;
function emergencyUnsetBribes(uint256[] memory pids) external;
function getBribesOf(address account, uint256 pid) external view returns (IVeMoeRewarder);
function getBribesTotalVotes(IVeMoeRewarder bribe, uint256 pid) external view returns (uint256);
function getMasterChef() external view returns (IMasterChef);
function getMaxVeMoePerMoe() external view returns (uint256);
function getMoeStaking() external view returns (IMoeStaking);
function getPendingRewards(address account, uint256[] calldata pids)
external
view
returns (IERC20[] memory tokens, uint256[] memory pendingRewards);
function getTopPidsTotalVotes() external view returns (uint256);
function getTopPoolIds() external view returns (uint256[] memory);
function getTotalVotes() external view returns (uint256);
function getTotalWeight() external view returns (uint256);
function getTotalVotesOf(address account) external view returns (uint256);
function getVeMoePerSecondPerMoe() external view returns (uint256);
function getVotes(uint256 pid) external view returns (uint256);
function getWeight(uint256 pid) external view returns (uint256);
function getVotesOf(address account, uint256 pid) external view returns (uint256);
function getAlpha() external view returns (uint256);
function getRewarderFactory() external view returns (IRewarderFactory);
function isInTopPoolIds(uint256 pid) external view returns (bool);
function onModify(address account, uint256 oldBalance, uint256 newBalance, uint256 oldTotalSupply, uint256)
external;
function setBribes(uint256[] memory pids, IVeMoeRewarder[] memory bribes) external;
function setTopPoolIds(uint256[] memory pids) external;
function setAlpha(uint256 alpha) external;
function setVeMoePerSecondPerMoe(uint256 veMoePerSecondPerMoe) external;
function vote(uint256[] memory pids, int256[] memory deltaAmounts) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IMasterChefRewarder} from "./IMasterChefRewarder.sol";
import {IMoe} from "./IMoe.sol";
import {IVeMoe} from "./IVeMoe.sol";
import {Rewarder} from "../libraries/Rewarder.sol";
import {Amounts} from "../libraries/Amounts.sol";
import {IRewarderFactory} from "./IRewarderFactory.sol";
interface IMasterChef {
error MasterChef__InvalidShares();
error MasterChef__InvalidMoePerSecond();
error MasterChef__ZeroAddress();
error MasterChef__NotMasterchefRewarder();
error MasterChef__CannotRenounceOwnership();
error MasterChef__MintFailed();
struct Farm {
Amounts.Parameter amounts;
Rewarder.Parameter rewarder;
IERC20 token;
IMasterChefRewarder extraRewarder;
}
event PositionModified(uint256 indexed pid, address indexed account, int256 deltaAmount, uint256 moeReward);
event MoePerSecondSet(uint256 moePerSecond);
event FarmAdded(uint256 indexed pid, IERC20 indexed token);
event ExtraRewarderSet(uint256 indexed pid, IMasterChefRewarder extraRewarder);
event TreasurySet(address indexed treasury);
function add(IERC20 token, IMasterChefRewarder extraRewarder) external;
function claim(uint256[] memory pids) external;
function deposit(uint256 pid, uint256 amount) external;
function emergencyWithdraw(uint256 pid) external;
function getDeposit(uint256 pid, address account) external view returns (uint256);
function getLastUpdateTimestamp(uint256 pid) external view returns (uint256);
function getPendingRewards(address account, uint256[] memory pids)
external
view
returns (uint256[] memory moeRewards, IERC20[] memory extraTokens, uint256[] memory extraRewards);
function getExtraRewarder(uint256 pid) external view returns (IMasterChefRewarder);
function getMoe() external view returns (IMoe);
function getMoePerSecond() external view returns (uint256);
function getMoePerSecondForPid(uint256 pid) external view returns (uint256);
function getNumberOfFarms() external view returns (uint256);
function getToken(uint256 pid) external view returns (IERC20);
function getTotalDeposit(uint256 pid) external view returns (uint256);
function getTreasury() external view returns (address);
function getTreasuryShare() external view returns (uint256);
function getRewarderFactory() external view returns (IRewarderFactory);
function getLBHooksManager() external view returns (address);
function getVeMoe() external view returns (IVeMoe);
function setExtraRewarder(uint256 pid, IMasterChefRewarder extraRewarder) external;
function setMoePerSecond(uint96 moePerSecond) external;
function setTreasury(address treasury) external;
function updateAll(uint256[] calldata pids) external;
function withdraw(uint256 pid, uint256 amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IBaseRewarder} from "./IBaseRewarder.sol";
interface IMasterChefRewarder is IBaseRewarder {
error MasterChefRewarder__AlreadyLinked();
error MasterChefRewarder__NotLinked();
error MasterChefRewarder__UseUnlink();
enum Status {
Unlinked,
Linked,
Stopped
}
function link(uint256 pid) external;
function unlink(uint256 pid) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IBaseRewarder} from "../interfaces/IBaseRewarder.sol";
interface IRewarderFactory {
error RewarderFactory__ZeroAddress();
error RewarderFactory__InvalidRewarderType();
error RewarderFactory__InvalidPid();
enum RewarderType {
InvalidRewarder,
MasterChefRewarder,
VeMoeRewarder,
JoeStakingRewarder
}
event RewarderCreated(
RewarderType indexed rewarderType, IERC20 indexed token, uint256 indexed pid, IBaseRewarder rewarder
);
event RewarderImplementationSet(RewarderType indexed rewarderType, IBaseRewarder indexed implementation);
function getRewarderImplementation(RewarderType rewarderType) external view returns (IBaseRewarder);
function getRewarderCount(RewarderType rewarderType) external view returns (uint256);
function getRewarderAt(RewarderType rewarderType, uint256 index) external view returns (IBaseRewarder);
function getRewarderType(IBaseRewarder rewarder) external view returns (RewarderType);
function setRewarderImplementation(RewarderType rewarderType, IBaseRewarder implementation) external;
function createRewarder(RewarderType rewarderType, IERC20 token, uint256 pid) external returns (IBaseRewarder);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @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 or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* 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.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @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`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// 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
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable
struct OwnableStorage {
address _owner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;
function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
assembly {
$.slot := OwnableStorageLocation
}
}
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
function __Ownable_init(address initialOwner) internal onlyInitializing {
__Ownable_init_unchained(initialOwner);
}
function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
OwnableStorage storage $ = _getOwnableStorage();
return $._owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
OwnableStorage storage $ = _getOwnableStorage();
address oldOwner = $._owner;
$._owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IBaseRewarder} from "./IBaseRewarder.sol";
interface IVeMoeRewarder is IBaseRewarder {
function claim(address account, uint256 amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IMoe} from "./IMoe.sol";
import {IVeMoe} from "./IVeMoe.sol";
import {IStableMoe} from "./IStableMoe.sol";
interface IMoeStaking {
event PositionModified(address indexed account, int256 deltaAmount);
function getMoe() external view returns (IMoe);
function getVeMoe() external view returns (IVeMoe);
function getSMoe() external view returns (IStableMoe);
function getDeposit(address account) external view returns (uint256);
function getTotalDeposit() external view returns (uint256);
function stake(uint256 amount) external;
function unstake(uint256 amount) external;
function claim() external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IBaseRewarder {
error BaseRewarder__NativeTransferFailed();
error BaseRewarder__InvalidCaller();
error BaseRewarder__Stopped();
error BaseRewarder__AlreadyStopped();
error BaseRewarder__NotNativeRewarder();
error BaseRewarder__ZeroAmount();
error BaseRewarder__ZeroReward();
error BaseRewarder__InvalidDuration();
error BaseRewarder__InvalidPid(uint256 pid);
error BaseRewarder__InvalidStartTimestamp(uint256 startTimestamp);
error BaseRewarder__CannotRenounceOwnership();
event Claim(address indexed account, IERC20 indexed token, uint256 reward);
event RewardParameterUpdated(uint256 rewardPerSecond, uint256 startTimestamp, uint256 endTimestamp);
event Stopped();
event Swept(IERC20 indexed token, address indexed account, uint256 amount);
function getToken() external view returns (IERC20);
function getCaller() external view returns (address);
function getPid() external view returns (uint256);
function getRewarderParameter()
external
view
returns (IERC20 token, uint256 rewardPerSecond, uint256 lastUpdateTimestamp, uint256 endTimestamp);
function getRemainingReward() external view returns (uint256);
function getPendingReward(address account, uint256 balance, uint256 totalSupply)
external
view
returns (IERC20 token, uint256 pendingReward);
function isStopped() external view returns (bool);
function initialize(address initialOwner) external;
function setRewardPerSecond(uint256 maxRewardPerSecond, uint256 expectedDuration)
external
returns (uint256 rewardPerSecond);
function setRewarderParameters(uint256 maxRewardPerSecond, uint256 startTimestamp, uint256 expectedDuration)
external
returns (uint256 rewardPerSecond);
function stop() external;
function sweep(IERC20 token, address account) external;
function onModify(address account, uint256 pid, uint256 oldBalance, uint256 newBalance, uint256 totalSupply)
external
returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Rewarder} from "../libraries/Rewarder.sol";
import {IMoeStaking} from "../interfaces/IMoeStaking.sol";
interface IStableMoe {
error StableMoe__UnauthorizedCaller();
error StableMoe__RewardAlreadyAdded(IERC20 reward);
error StableMoe__RewardAlreadyRemoved(IERC20 reward);
error StableMoe__ActiveReward(IERC20 reward);
error StableMoe__NativeTransferFailed();
error StableMoe__TooManyActiveRewards();
error StableMoe__CannotRenounceOwnership();
struct Reward {
Rewarder.Parameter rewarder;
uint256 reserve;
}
event Claim(address indexed account, IERC20 indexed token, uint256 amount);
event AddReward(IERC20 indexed reward);
event RemoveReward(IERC20 indexed reward);
event Sweep(IERC20 indexed token, address indexed account);
function getMoeStaking() external view returns (IMoeStaking);
function getNumberOfRewards() external view returns (uint256);
function getRewardToken(uint256 id) external view returns (address);
function getRewardTokens() external view returns (address[] memory);
function getPendingRewards(address account)
external
view
returns (IERC20[] memory tokens, uint256[] memory rewards);
function claim() external;
function onModify(
address account,
uint256 oldBalance,
uint256 newBalance,
uint256 oldTotalSupply,
uint256 newTotalSupply
) external;
function addReward(IERC20 reward) external;
function removeReward(IERC20 reward) external;
function sweep(IERC20 token, address account) external;
}{
"remappings": [
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@tj-dexv2/=lib/dexv2/",
"@solmate/=lib/solmate/",
"dexv2/=lib/dexv2/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"solmate/=lib/solmate/src/"
],
"optimizer": {
"enabled": true,
"runs": 600
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IMoe","name":"moe","type":"address"},{"internalType":"contract IVeMoe","name":"veMoe","type":"address"},{"internalType":"contract IRewarderFactory","name":"rewarderFactory","type":"address"},{"internalType":"address","name":"lbHooksManager","type":"address"},{"internalType":"uint256","name":"treasuryShare","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"MasterChef__CannotRenounceOwnership","type":"error"},{"inputs":[],"name":"MasterChef__InvalidMoePerSecond","type":"error"},{"inputs":[],"name":"MasterChef__InvalidShares","type":"error"},{"inputs":[],"name":"MasterChef__MintFailed","type":"error"},{"inputs":[],"name":"MasterChef__NotMasterchefRewarder","type":"error"},{"inputs":[],"name":"MasterChef__ZeroAddress","type":"error"},{"inputs":[],"name":"Math__UnderOverflow","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"contract IMasterChefRewarder","name":"extraRewarder","type":"address"}],"name":"ExtraRewarderSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"}],"name":"FarmAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"moePerSecond","type":"uint256"}],"name":"MoePerSecondSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"int256","name":"deltaAmount","type":"int256"},{"indexed":false,"internalType":"uint256","name":"moeReward","type":"uint256"}],"name":"PositionModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasury","type":"address"}],"name":"TreasurySet","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"contract IMasterChefRewarder","name":"extraRewarder","type":"address"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pids","type":"uint256[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"getDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"getExtraRewarder","outputs":[{"internalType":"contract IMasterChefRewarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLBHooksManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"getLastUpdateTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMoe","outputs":[{"internalType":"contract IMoe","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMoePerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"getMoePerSecondForPid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumberOfFarms","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"pids","type":"uint256[]"}],"name":"getPendingRewards","outputs":[{"internalType":"uint256[]","name":"moeRewards","type":"uint256[]"},{"internalType":"contract IERC20[]","name":"extraTokens","type":"address[]"},{"internalType":"uint256[]","name":"extraRewards","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewarderFactory","outputs":[{"internalType":"contract IRewarderFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"getToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"getTotalDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVeMoe","outputs":[{"internalType":"contract IVeMoe","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"futureFunding","type":"address"},{"internalType":"address","name":"team","type":"address"},{"internalType":"uint256","name":"futureFundingAmount","type":"uint256"},{"internalType":"uint256","name":"teamAmount","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"contract IMasterChefRewarder","name":"extraRewarder","type":"address"}],"name":"setExtraRewarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"moePerSecond","type":"uint96"}],"name":"setMoePerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pids","type":"uint256[]"}],"name":"updateAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6101206040523480156200001257600080fd5b506040516200284f3803806200284f83398101604081905262000035916200015d565b6200003f62000093565b670de0b6b3a7640000811115620000695760405163169cfea160e11b815260040160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c05290911660e05261010052620001d1565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000e45760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b0390811614620001445780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6001600160a01b03811681146200014457600080fd5b600080600080600060a086880312156200017657600080fd5b8551620001838162000147565b6020870151909550620001968162000147565b6040870151909450620001a98162000147565b6060870151909350620001bc8162000147565b80925050608086015190509295509295909350565b60805160a05160c05160e051610100516125de6200027160003960008181610304015261182e01526000818161038601526106570152600081816102c301526112e00152600081816103320152818161050901528181610ca80152818161112e015281816117b7015261192e01526000818161036001528181610e0901528181610eae015281816115ba01528181611ade0152611b6801526125de6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80638da5cb5b11610104578063d4f9dd1d116100a2578063e4b50cb811610071578063e4b50cb81461042c578063e665b4141461043f578063f0f4426014610452578063f2fde38b1461046557600080fd5b8063d4f9dd1d146103eb578063d7c41c79146103fe578063e2bbb15814610411578063e30c39781461042457600080fd5b80639f489e4e116100de5780639f489e4e146103aa578063b507a700146103bd578063c7a61783146103d0578063d23ab97a146103d857600080fd5b80638da5cb5b1461035657806393f945031461035e5780639b4c8ea51461038457600080fd5b8063566aff6a1161017c578063715018a61161014b578063715018a6146102fa578063796441bb1461030257806379ba5097146103285780637e63f0281461033057600080fd5b8063566aff6a1461027d5780635b92d8311461029f5780635c4323ab146102c15780636ba4c138146102e757600080fd5b80633b19e84a116101b85780633b19e84a1461021a578063441a3e701461024457806352c28fab146102575780635312ea8e1461026a57600080fd5b806304093c5b146101df57806321bd31de146101f45780632498aef714610207575b600080fd5b6101f26101ed3660046120aa565b610478565b005b6101f2610202366004612101565b6104b8565b6101f2610215366004612131565b6104ca565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6101f261025236600461215a565b6105ee565b6101f261026536600461217c565b61064c565b6101f26102783660046121aa565b6107d9565b61029061028b3660046121c3565b61088c565b60405161023b93929190612253565b600254600160a01b90046001600160601b03165b60405190815260200161023b565b7f0000000000000000000000000000000000000000000000000000000000000000610227565b6101f26102f53660046120aa565b610b0c565b6101f2610b50565b7f00000000000000000000000000000000000000000000000000000000000000006102b3565b6101f2610b69565b7f0000000000000000000000000000000000000000000000000000000000000000610227565b610227610bb6565b7f0000000000000000000000000000000000000000000000000000000000000000610227565b7f0000000000000000000000000000000000000000000000000000000000000000610227565b6102b36103b8366004612101565b610beb565b6102b36103cb3660046121aa565b610c23565b6003546102b3565b6102b36103e63660046121aa565b610c54565b6102b36103f93660046121aa565b610c81565b6101f261040c3660046122c6565b610d2d565b6101f261041f36600461215a565b610fa3565b610227610ff5565b61022761043a3660046121aa565b61101e565b61022761044d3660046121aa565b611056565b6101f2610460366004612334565b61108e565b6101f2610473366004612334565b61109f565b6104b482828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061112492505050565b5050565b6104c0611278565b6104b482826112ac565b6104d2611278565b678ac7230489e80000816001600160601b0316111561050457604051630793e7b960e31b815260040160405180910390fd5b6105927f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e1e4d4196040518163ffffffff1660e01b8152600401600060405180830381865afa158015610565573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261058d9190810190612367565b611124565b600280546001600160a01b0316600160a01b6001600160601b038416908102919091179091556040519081527f953a915a77e51c643cf28682620b504b7d9df49407f9860e5edeb38babb834f99060200160405180910390a150565b61060a82336105fc846114f9565b6106059061242f565b611527565b80156104b4576104b43382600385815481106106285761062861244b565b60009182526020909120600560079092020101546001600160a01b031691906116ce565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461068457610684611278565b60038054600181018255600091909152600781027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f860810180546001600160a01b0319166001600160a01b0386811691909117909155427fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d8301557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b909101908316156107345761073482846112ac565b6040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079c9190612461565b506040516001600160a01b0385169083907f9d7bf7d496ad44415bf088986e68bcfc590380ab2bf411124744b485329f2fc690600090a350505050565b6000600382815481106107ee576107ee61244b565b60009182526020822060079091020191506108098233611742565b90506000610816826114f9565b61081f9061242f565b905061082c833383611762565b505050600584015461084991506001600160a01b031633846116ce565b6040805182815260006020820152339186917f0e006e790dc8db480892a6d5c0bf539c411db278e5185b07d46bdcc110ba6af5910160405180910390a350505050565b606080808367ffffffffffffffff8111156108a9576108a9612351565b6040519080825280602002602001820160405280156108d2578160200160208202803683370190505b5092508367ffffffffffffffff8111156108ee576108ee612351565b604051908082528060200260200182016040528015610917578160200160208202803683370190505b5091508367ffffffffffffffff81111561093357610933612351565b60405190808252806020026020018201604052801561095c578160200160208202803683370190505b50905060005b84811015610b0257600086868381811061097e5761097e61244b565b90506020020135905060006003828154811061099c5761099c61244b565b6000918252602082206007909102019150600282019082906109be828d611742565b905060006109ca835490565b905060006109e16109dc86898561178d565b61181d565b91506109f29050858f858585611870565b8b8981518110610a0457610a0461244b565b60209081029190910101525060068501546001600160a01b03168015610aea5760405163c718325160e01b81526001600160a01b038f81166004830152602482018590526044820184905282169063c7183251906064016040805180830381865afa158015610a77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9b919061247a565b8b8a81518110610aad57610aad61244b565b602002602001018b8b81518110610ac657610ac661244b565b6020026020010182815250826001600160a01b03166001600160a01b031681525050505b5050505050505080610afb906124a8565b9050610962565b5093509350939050565b60005b81811015610b4b57610b3b838383818110610b2c57610b2c61244b565b90506020020135336000611527565b610b44816124a8565b9050610b0f565b505050565b60405163a3dd49c760e01b815260040160405180910390fd5b3380610b73610ff5565b6001600160a01b031614610baa5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b610bb3816118d6565b50565b6000807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b546001600160a01b031692915050565b6000610c1a8260038581548110610c0457610c0461244b565b6000918252602090912060079091020190611742565b90505b92915050565b600060038281548110610c3857610c3861244b565b9060005260206000209060070201600201600001549050919050565b6000610c1d60038381548110610c6c57610c6c61244b565b90600052602060002090600702016000015490565b6000610c1d82600260149054906101000a90046001600160601b03166001600160601b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166306aba0e16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d289190612461565b61190e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0080546002919068010000000000000000900460ff1680610d7c5750805467ffffffffffffffff808416911610155b15610d9a5760405163f92ee8a960e01b815260040160405180910390fd5b805468ffffffffffffffffff191667ffffffffffffffff83161768010000000000000000178155610dca886119c4565b610dd3876119d5565b6000808511610de3576000610e76565b6040516340c10f1960e01b81526001600160a01b038881166004830152602482018790527f000000000000000000000000000000000000000000000000000000000000000016906340c10f19906044016020604051808303816000875af1158015610e52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e769190612461565b90506000808511610e88576000610f1b565b6040516340c10f1960e01b81526001600160a01b038881166004830152602482018790527f000000000000000000000000000000000000000000000000000000000000000016906340c10f19906044016020604051808303816000875af1158015610ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1b9190612461565b90508582141580610f2c5750848114155b15610f4a5760405163b9f8198b60e01b815260040160405180910390fd5b5050805468ff00000000000000001916815560405167ffffffffffffffff831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050505050565b610fb18233610605846114f9565b80156104b4576104b433308360038681548110610fd057610fd061244b565b60009182526020909120600560079092020101546001600160a01b0316929190611a44565b6000807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00610bdb565b6000600382815481106110335761103361244b565b60009182526020909120600560079092020101546001600160a01b031692915050565b60006003828154811061106b5761106b61244b565b60009182526020909120600660079092020101546001600160a01b031692915050565b611096611278565b610bb3816119d5565b6110a7611278565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319166001600160a01b03831690811782556110eb610bb6565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b60008151905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166306aba0e16040518163ffffffff1660e01b8152600401602060405180830381865afa15801561118a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ae9190612461565b600254909150600160a01b90046001600160601b031660005b838110156112715760008582815181106111e3576111e361244b565b602002602001015190506000600382815481106112025761120261244b565b60009182526020822060079091020191506002820190611220835490565b9050600061122f838884611a83565b9050600061123e86838b61190e565b9050600061124b82611a91565b9050611258858583611be5565b50505050505050508061126a906124a8565b90506111c7565b5050505050565b33611281610bb6565b6001600160a01b0316146112aa5760405163118cdaa760e01b8152336004820152602401610ba1565b565b6001600160a01b0381161580159061135f57506001604051634f4ee65b60e11b81526001600160a01b0383811660048301527f00000000000000000000000000000000000000000000000000000000000000001690639e9dccb690602401602060405180830381865afa158015611327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134b91906124d7565b600381111561135c5761135c6124c1565b14155b1561137d576040516376644cf960e11b815260040160405180910390fd5b6000600383815481106113925761139261244b565b60009182526020909120600660079092020101546001600160a01b0316905080156114125760405163f1e023fd60e01b8152600481018490526001600160a01b0382169063f1e023fd90602401600060405180830381600087803b1580156113f957600080fd5b505af115801561140d573d6000803e3d6000fd5b505050505b6001600160a01b0382161561147c5760405163b1a867d560e01b8152600481018490526001600160a01b0383169063b1a867d590602401600060405180830381600087803b15801561146357600080fd5b505af1158015611477573d6000803e3d6000fd5b505050505b81600384815481106114905761149061244b565b60009182526020918290206007919091020160060180546001600160a01b0319166001600160a01b03938416179055604051918416825284917fa0671cc6d1b10c28ed0b4e4a9eaa3a903f4fa57c3a02426bbcc453004fed8745910160405180910390a2505050565b60006001600160ff1b03821115611523576040516308a942bb60e11b815260040160405180910390fd5b5090565b60006003848154811061153c5761153c61244b565b60009182526020822060066007909202019081015490925060028301916001600160a01b03909116908080611572868989611762565b509250925092506000611586868b8461178d565b9050600061159382611a91565b905060006115a5888c88888887611c36565b905080156115e1576115e16001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168c836116ce565b6001600160a01b0387161561167a5760405163870b50fd60e01b81526001600160a01b038c81166004830152602482018e905260448201889052606482018790526084820186905288169063870b50fd9060a4016020604051808303816000875af1158015611654573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116789190612461565b505b604080518b8152602081018390526001600160a01b038d16918e917f0e006e790dc8db480892a6d5c0bf539c411db278e5185b07d46bdcc110ba6af5910160405180910390a3505050505050505050505050565b6040516001600160a01b03838116602483015260448201839052610b4b91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611cba565b6001600160a01b0381166000908152600183016020526040812054610c1a565b600080808061177b876001600160a01b03881687611d1d565b93509350935093505b93509350935093565b6002546000906118139084906117b5908790600160a01b90046001600160601b031686611a83565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166306aba0e16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d04573d6000803e3d6000fd5b90505b9392505050565b600080670de0b6b3a76400006118537f0000000000000000000000000000000000000000000000000000000000000000856124f8565b61185d919061250f565b91506118698284612531565b9050915091565b60008061187d8484611d7c565b876001015461188c9190612544565b905084156118c8576001600160a01b03861660009081526002880160205260409020546118b98287611da0565b6118c39190612531565b6118cb565b60005b979650505050505050565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b03191681556104b482611db7565b600081156119ba5760405163d851fdfd60e01b81526004810185905282907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d851fdfd90602401602060405180830381865afa15801561197d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a19190612461565b6119ab90856124f8565b6119b5919061250f565b611813565b5060009392505050565b6119cc611e28565b610bb381611e76565b6001600160a01b0381166119fc576040516398e7ce9b60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b038316908117825560405190917f3c864541ef71378c6229510ed90f376565ee42d9c5e0904a984a9e863e6db44f91a250565b6040516001600160a01b038481166024830152838116604483015260648201839052611a7d9186918216906323b872dd906084016116fb565b50505050565b600061181384844285611ea8565b600081600003611aa357506000919050565b600080611aaf8461181d565b6000546040516340c10f1960e01b81526001600160a01b039182166004820152602481018490529294509092507f000000000000000000000000000000000000000000000000000000000000000016906340c10f19906044016020604051808303816000875af1158015611b27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4b9190612461565b506040516340c10f1960e01b8152306004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906340c10f19906044016020604051808303816000875af1158015611bb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bdd9190612461565b949350505050565b600080611bf28484611d7c565b8554909150421115611c02574285555b8015611c275780856001016000828254611c1c9190612544565b925050819055611c2d565b84600101545b95945050505050565b600080611c44888585611be5565b90508515611c80576001600160a01b0387166000908152600289016020526040902054611c718288611da0565b611c7b9190612531565b611c83565b60005b9150611c8f8186611da0565b6001600160a01b03909716600090815260029098016020525060409096209490945550929392505050565b6000611ccf6001600160a01b03841683611ef2565b90508051600014158015611cf4575080806020019051810190611cf29190612557565b155b15610b4b57604051635274afe760e01b81526001600160a01b0384166004820152602401610ba1565b6000828152600184016020526040812054845490919081848103611d45575082915080611784565b611d4f8486611f00565b9250611d5b8286611f00565b60008781526001890160205260409020849055808855905093509350935093565b60008215611d9757611d9283604084901b61250f565b610c1a565b50600092915050565b60006040611dae84846124f8565b901c9392505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff166112aa57604051631afcd79f60e31b815260040160405180910390fd5b611e7e611e28565b6001600160a01b038116610baa57604051631e4fbdf760e01b815260006004820152602401610ba1565b600081600003611eba57506000611bdd565b84546000428510611ecb5742611ecd565b845b9050818111611edd5760006118cb565b85611ee88383612531565b6118cb91906124f8565b6060610c1a83836000611f3c565b8181016001600160ff1b0380841190821117156000819003611f35576040516308a942bb60e11b815260040160405180910390fd5b5092915050565b606081471015611f615760405163cd78605960e01b8152306004820152602401610ba1565b600080856001600160a01b03168486604051611f7d9190612579565b60006040518083038185875af1925050503d8060008114611fba576040519150601f19603f3d011682016040523d82523d6000602084013e611fbf565b606091505b5091509150611fcf868383611fd9565b9695505050505050565b606082611fee57611fe982612035565b611816565b815115801561200557506001600160a01b0384163b155b1561202e57604051639996b31560e01b81526001600160a01b0385166004820152602401610ba1565b5080611816565b8051156120455780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b60008083601f84011261207057600080fd5b50813567ffffffffffffffff81111561208857600080fd5b6020830191508360208260051b85010111156120a357600080fd5b9250929050565b600080602083850312156120bd57600080fd5b823567ffffffffffffffff8111156120d457600080fd5b6120e08582860161205e565b90969095509350505050565b6001600160a01b0381168114610bb357600080fd5b6000806040838503121561211457600080fd5b823591506020830135612126816120ec565b809150509250929050565b60006020828403121561214357600080fd5b81356001600160601b038116811461181657600080fd5b6000806040838503121561216d57600080fd5b50508035926020909101359150565b6000806040838503121561218f57600080fd5b823561219a816120ec565b91506020830135612126816120ec565b6000602082840312156121bc57600080fd5b5035919050565b6000806000604084860312156121d857600080fd5b83356121e3816120ec565b9250602084013567ffffffffffffffff8111156121ff57600080fd5b61220b8682870161205e565b9497909650939450505050565b600081518084526020808501945080840160005b838110156122485781518752958201959082019060010161222c565b509495945050505050565b6060815260006122666060830186612218565b82810360208481019190915285518083528682019282019060005b818110156122a65784516001600160a01b031683529383019391830191600101612281565b505084810360408601526122ba8187612218565b98975050505050505050565b60008060008060008060c087890312156122df57600080fd5b86356122ea816120ec565b955060208701356122fa816120ec565b9450604087013561230a816120ec565b9350606087013561231a816120ec565b9598949750929560808101359460a0909101359350915050565b60006020828403121561234657600080fd5b8135611816816120ec565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561237a57600080fd5b825167ffffffffffffffff8082111561239257600080fd5b818501915085601f8301126123a657600080fd5b8151818111156123b8576123b8612351565b8060051b604051601f19603f830116810181811085821117156123dd576123dd612351565b6040529182528482019250838101850191888311156123fb57600080fd5b938501935b828510156122ba57845184529385019392850192612400565b634e487b7160e01b600052601160045260246000fd5b6000600160ff1b820161244457612444612419565b5060000390565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561247357600080fd5b5051919050565b6000806040838503121561248d57600080fd5b8251612498816120ec565b6020939093015192949293505050565b6000600182016124ba576124ba612419565b5060010190565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156124e957600080fd5b81516004811061181657600080fd5b8082028115828204841417610c1d57610c1d612419565b60008261252c57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610c1d57610c1d612419565b80820180821115610c1d57610c1d612419565b60006020828403121561256957600080fd5b8151801515811461181657600080fd5b6000825160005b8181101561259a5760208186018101518583015201612580565b50600092019182525091905056fea2646970667358221220dfbe43c5969df2a6dfaefc1778de098c1e32d5ed41e46ad89668ddaa3f49294c64736f6c634300081400330000000000000000000000004515a45337f461a11ff0fe8abf3c606ae5dc00c900000000000000000000000055160b0f39848a7b844f3a562210489df301dee7000000000000000000000000e283db759720982094de7fc6edc49d3adf84894300000000000000000000000084ebcc334c24ce53e7c7551670c92a4bd2a84afb000000000000000000000000000000000000000000000000051ce4fed1e17943
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80638da5cb5b11610104578063d4f9dd1d116100a2578063e4b50cb811610071578063e4b50cb81461042c578063e665b4141461043f578063f0f4426014610452578063f2fde38b1461046557600080fd5b8063d4f9dd1d146103eb578063d7c41c79146103fe578063e2bbb15814610411578063e30c39781461042457600080fd5b80639f489e4e116100de5780639f489e4e146103aa578063b507a700146103bd578063c7a61783146103d0578063d23ab97a146103d857600080fd5b80638da5cb5b1461035657806393f945031461035e5780639b4c8ea51461038457600080fd5b8063566aff6a1161017c578063715018a61161014b578063715018a6146102fa578063796441bb1461030257806379ba5097146103285780637e63f0281461033057600080fd5b8063566aff6a1461027d5780635b92d8311461029f5780635c4323ab146102c15780636ba4c138146102e757600080fd5b80633b19e84a116101b85780633b19e84a1461021a578063441a3e701461024457806352c28fab146102575780635312ea8e1461026a57600080fd5b806304093c5b146101df57806321bd31de146101f45780632498aef714610207575b600080fd5b6101f26101ed3660046120aa565b610478565b005b6101f2610202366004612101565b6104b8565b6101f2610215366004612131565b6104ca565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6101f261025236600461215a565b6105ee565b6101f261026536600461217c565b61064c565b6101f26102783660046121aa565b6107d9565b61029061028b3660046121c3565b61088c565b60405161023b93929190612253565b600254600160a01b90046001600160601b03165b60405190815260200161023b565b7f000000000000000000000000e283db759720982094de7fc6edc49d3adf848943610227565b6101f26102f53660046120aa565b610b0c565b6101f2610b50565b7f000000000000000000000000000000000000000000000000051ce4fed1e179436102b3565b6101f2610b69565b7f00000000000000000000000055160b0f39848a7b844f3a562210489df301dee7610227565b610227610bb6565b7f0000000000000000000000004515a45337f461a11ff0fe8abf3c606ae5dc00c9610227565b7f00000000000000000000000084ebcc334c24ce53e7c7551670c92a4bd2a84afb610227565b6102b36103b8366004612101565b610beb565b6102b36103cb3660046121aa565b610c23565b6003546102b3565b6102b36103e63660046121aa565b610c54565b6102b36103f93660046121aa565b610c81565b6101f261040c3660046122c6565b610d2d565b6101f261041f36600461215a565b610fa3565b610227610ff5565b61022761043a3660046121aa565b61101e565b61022761044d3660046121aa565b611056565b6101f2610460366004612334565b61108e565b6101f2610473366004612334565b61109f565b6104b482828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061112492505050565b5050565b6104c0611278565b6104b482826112ac565b6104d2611278565b678ac7230489e80000816001600160601b0316111561050457604051630793e7b960e31b815260040160405180910390fd5b6105927f00000000000000000000000055160b0f39848a7b844f3a562210489df301dee76001600160a01b031663e1e4d4196040518163ffffffff1660e01b8152600401600060405180830381865afa158015610565573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261058d9190810190612367565b611124565b600280546001600160a01b0316600160a01b6001600160601b038416908102919091179091556040519081527f953a915a77e51c643cf28682620b504b7d9df49407f9860e5edeb38babb834f99060200160405180910390a150565b61060a82336105fc846114f9565b6106059061242f565b611527565b80156104b4576104b43382600385815481106106285761062861244b565b60009182526020909120600560079092020101546001600160a01b031691906116ce565b336001600160a01b037f00000000000000000000000084ebcc334c24ce53e7c7551670c92a4bd2a84afb161461068457610684611278565b60038054600181018255600091909152600781027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f860810180546001600160a01b0319166001600160a01b0386811691909117909155427fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d8301557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b909101908316156107345761073482846112ac565b6040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079c9190612461565b506040516001600160a01b0385169083907f9d7bf7d496ad44415bf088986e68bcfc590380ab2bf411124744b485329f2fc690600090a350505050565b6000600382815481106107ee576107ee61244b565b60009182526020822060079091020191506108098233611742565b90506000610816826114f9565b61081f9061242f565b905061082c833383611762565b505050600584015461084991506001600160a01b031633846116ce565b6040805182815260006020820152339186917f0e006e790dc8db480892a6d5c0bf539c411db278e5185b07d46bdcc110ba6af5910160405180910390a350505050565b606080808367ffffffffffffffff8111156108a9576108a9612351565b6040519080825280602002602001820160405280156108d2578160200160208202803683370190505b5092508367ffffffffffffffff8111156108ee576108ee612351565b604051908082528060200260200182016040528015610917578160200160208202803683370190505b5091508367ffffffffffffffff81111561093357610933612351565b60405190808252806020026020018201604052801561095c578160200160208202803683370190505b50905060005b84811015610b0257600086868381811061097e5761097e61244b565b90506020020135905060006003828154811061099c5761099c61244b565b6000918252602082206007909102019150600282019082906109be828d611742565b905060006109ca835490565b905060006109e16109dc86898561178d565b61181d565b91506109f29050858f858585611870565b8b8981518110610a0457610a0461244b565b60209081029190910101525060068501546001600160a01b03168015610aea5760405163c718325160e01b81526001600160a01b038f81166004830152602482018590526044820184905282169063c7183251906064016040805180830381865afa158015610a77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9b919061247a565b8b8a81518110610aad57610aad61244b565b602002602001018b8b81518110610ac657610ac661244b565b6020026020010182815250826001600160a01b03166001600160a01b031681525050505b5050505050505080610afb906124a8565b9050610962565b5093509350939050565b60005b81811015610b4b57610b3b838383818110610b2c57610b2c61244b565b90506020020135336000611527565b610b44816124a8565b9050610b0f565b505050565b60405163a3dd49c760e01b815260040160405180910390fd5b3380610b73610ff5565b6001600160a01b031614610baa5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b610bb3816118d6565b50565b6000807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b546001600160a01b031692915050565b6000610c1a8260038581548110610c0457610c0461244b565b6000918252602090912060079091020190611742565b90505b92915050565b600060038281548110610c3857610c3861244b565b9060005260206000209060070201600201600001549050919050565b6000610c1d60038381548110610c6c57610c6c61244b565b90600052602060002090600702016000015490565b6000610c1d82600260149054906101000a90046001600160601b03166001600160601b03167f00000000000000000000000055160b0f39848a7b844f3a562210489df301dee76001600160a01b03166306aba0e16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d289190612461565b61190e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0080546002919068010000000000000000900460ff1680610d7c5750805467ffffffffffffffff808416911610155b15610d9a5760405163f92ee8a960e01b815260040160405180910390fd5b805468ffffffffffffffffff191667ffffffffffffffff83161768010000000000000000178155610dca886119c4565b610dd3876119d5565b6000808511610de3576000610e76565b6040516340c10f1960e01b81526001600160a01b038881166004830152602482018790527f0000000000000000000000004515a45337f461a11ff0fe8abf3c606ae5dc00c916906340c10f19906044016020604051808303816000875af1158015610e52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e769190612461565b90506000808511610e88576000610f1b565b6040516340c10f1960e01b81526001600160a01b038881166004830152602482018790527f0000000000000000000000004515a45337f461a11ff0fe8abf3c606ae5dc00c916906340c10f19906044016020604051808303816000875af1158015610ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1b9190612461565b90508582141580610f2c5750848114155b15610f4a5760405163b9f8198b60e01b815260040160405180910390fd5b5050805468ff00000000000000001916815560405167ffffffffffffffff831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050505050565b610fb18233610605846114f9565b80156104b4576104b433308360038681548110610fd057610fd061244b565b60009182526020909120600560079092020101546001600160a01b0316929190611a44565b6000807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00610bdb565b6000600382815481106110335761103361244b565b60009182526020909120600560079092020101546001600160a01b031692915050565b60006003828154811061106b5761106b61244b565b60009182526020909120600660079092020101546001600160a01b031692915050565b611096611278565b610bb3816119d5565b6110a7611278565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319166001600160a01b03831690811782556110eb610bb6565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b60008151905060007f00000000000000000000000055160b0f39848a7b844f3a562210489df301dee76001600160a01b03166306aba0e16040518163ffffffff1660e01b8152600401602060405180830381865afa15801561118a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ae9190612461565b600254909150600160a01b90046001600160601b031660005b838110156112715760008582815181106111e3576111e361244b565b602002602001015190506000600382815481106112025761120261244b565b60009182526020822060079091020191506002820190611220835490565b9050600061122f838884611a83565b9050600061123e86838b61190e565b9050600061124b82611a91565b9050611258858583611be5565b50505050505050508061126a906124a8565b90506111c7565b5050505050565b33611281610bb6565b6001600160a01b0316146112aa5760405163118cdaa760e01b8152336004820152602401610ba1565b565b6001600160a01b0381161580159061135f57506001604051634f4ee65b60e11b81526001600160a01b0383811660048301527f000000000000000000000000e283db759720982094de7fc6edc49d3adf8489431690639e9dccb690602401602060405180830381865afa158015611327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134b91906124d7565b600381111561135c5761135c6124c1565b14155b1561137d576040516376644cf960e11b815260040160405180910390fd5b6000600383815481106113925761139261244b565b60009182526020909120600660079092020101546001600160a01b0316905080156114125760405163f1e023fd60e01b8152600481018490526001600160a01b0382169063f1e023fd90602401600060405180830381600087803b1580156113f957600080fd5b505af115801561140d573d6000803e3d6000fd5b505050505b6001600160a01b0382161561147c5760405163b1a867d560e01b8152600481018490526001600160a01b0383169063b1a867d590602401600060405180830381600087803b15801561146357600080fd5b505af1158015611477573d6000803e3d6000fd5b505050505b81600384815481106114905761149061244b565b60009182526020918290206007919091020160060180546001600160a01b0319166001600160a01b03938416179055604051918416825284917fa0671cc6d1b10c28ed0b4e4a9eaa3a903f4fa57c3a02426bbcc453004fed8745910160405180910390a2505050565b60006001600160ff1b03821115611523576040516308a942bb60e11b815260040160405180910390fd5b5090565b60006003848154811061153c5761153c61244b565b60009182526020822060066007909202019081015490925060028301916001600160a01b03909116908080611572868989611762565b509250925092506000611586868b8461178d565b9050600061159382611a91565b905060006115a5888c88888887611c36565b905080156115e1576115e16001600160a01b037f0000000000000000000000004515a45337f461a11ff0fe8abf3c606ae5dc00c9168c836116ce565b6001600160a01b0387161561167a5760405163870b50fd60e01b81526001600160a01b038c81166004830152602482018e905260448201889052606482018790526084820186905288169063870b50fd9060a4016020604051808303816000875af1158015611654573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116789190612461565b505b604080518b8152602081018390526001600160a01b038d16918e917f0e006e790dc8db480892a6d5c0bf539c411db278e5185b07d46bdcc110ba6af5910160405180910390a3505050505050505050505050565b6040516001600160a01b03838116602483015260448201839052610b4b91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611cba565b6001600160a01b0381166000908152600183016020526040812054610c1a565b600080808061177b876001600160a01b03881687611d1d565b93509350935093505b93509350935093565b6002546000906118139084906117b5908790600160a01b90046001600160601b031686611a83565b7f00000000000000000000000055160b0f39848a7b844f3a562210489df301dee76001600160a01b03166306aba0e16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d04573d6000803e3d6000fd5b90505b9392505050565b600080670de0b6b3a76400006118537f000000000000000000000000000000000000000000000000051ce4fed1e17943856124f8565b61185d919061250f565b91506118698284612531565b9050915091565b60008061187d8484611d7c565b876001015461188c9190612544565b905084156118c8576001600160a01b03861660009081526002880160205260409020546118b98287611da0565b6118c39190612531565b6118cb565b60005b979650505050505050565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b03191681556104b482611db7565b600081156119ba5760405163d851fdfd60e01b81526004810185905282907f00000000000000000000000055160b0f39848a7b844f3a562210489df301dee76001600160a01b03169063d851fdfd90602401602060405180830381865afa15801561197d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a19190612461565b6119ab90856124f8565b6119b5919061250f565b611813565b5060009392505050565b6119cc611e28565b610bb381611e76565b6001600160a01b0381166119fc576040516398e7ce9b60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b038316908117825560405190917f3c864541ef71378c6229510ed90f376565ee42d9c5e0904a984a9e863e6db44f91a250565b6040516001600160a01b038481166024830152838116604483015260648201839052611a7d9186918216906323b872dd906084016116fb565b50505050565b600061181384844285611ea8565b600081600003611aa357506000919050565b600080611aaf8461181d565b6000546040516340c10f1960e01b81526001600160a01b039182166004820152602481018490529294509092507f0000000000000000000000004515a45337f461a11ff0fe8abf3c606ae5dc00c916906340c10f19906044016020604051808303816000875af1158015611b27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4b9190612461565b506040516340c10f1960e01b8152306004820152602481018290527f0000000000000000000000004515a45337f461a11ff0fe8abf3c606ae5dc00c96001600160a01b0316906340c10f19906044016020604051808303816000875af1158015611bb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bdd9190612461565b949350505050565b600080611bf28484611d7c565b8554909150421115611c02574285555b8015611c275780856001016000828254611c1c9190612544565b925050819055611c2d565b84600101545b95945050505050565b600080611c44888585611be5565b90508515611c80576001600160a01b0387166000908152600289016020526040902054611c718288611da0565b611c7b9190612531565b611c83565b60005b9150611c8f8186611da0565b6001600160a01b03909716600090815260029098016020525060409096209490945550929392505050565b6000611ccf6001600160a01b03841683611ef2565b90508051600014158015611cf4575080806020019051810190611cf29190612557565b155b15610b4b57604051635274afe760e01b81526001600160a01b0384166004820152602401610ba1565b6000828152600184016020526040812054845490919081848103611d45575082915080611784565b611d4f8486611f00565b9250611d5b8286611f00565b60008781526001890160205260409020849055808855905093509350935093565b60008215611d9757611d9283604084901b61250f565b610c1a565b50600092915050565b60006040611dae84846124f8565b901c9392505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff166112aa57604051631afcd79f60e31b815260040160405180910390fd5b611e7e611e28565b6001600160a01b038116610baa57604051631e4fbdf760e01b815260006004820152602401610ba1565b600081600003611eba57506000611bdd565b84546000428510611ecb5742611ecd565b845b9050818111611edd5760006118cb565b85611ee88383612531565b6118cb91906124f8565b6060610c1a83836000611f3c565b8181016001600160ff1b0380841190821117156000819003611f35576040516308a942bb60e11b815260040160405180910390fd5b5092915050565b606081471015611f615760405163cd78605960e01b8152306004820152602401610ba1565b600080856001600160a01b03168486604051611f7d9190612579565b60006040518083038185875af1925050503d8060008114611fba576040519150601f19603f3d011682016040523d82523d6000602084013e611fbf565b606091505b5091509150611fcf868383611fd9565b9695505050505050565b606082611fee57611fe982612035565b611816565b815115801561200557506001600160a01b0384163b155b1561202e57604051639996b31560e01b81526001600160a01b0385166004820152602401610ba1565b5080611816565b8051156120455780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b60008083601f84011261207057600080fd5b50813567ffffffffffffffff81111561208857600080fd5b6020830191508360208260051b85010111156120a357600080fd5b9250929050565b600080602083850312156120bd57600080fd5b823567ffffffffffffffff8111156120d457600080fd5b6120e08582860161205e565b90969095509350505050565b6001600160a01b0381168114610bb357600080fd5b6000806040838503121561211457600080fd5b823591506020830135612126816120ec565b809150509250929050565b60006020828403121561214357600080fd5b81356001600160601b038116811461181657600080fd5b6000806040838503121561216d57600080fd5b50508035926020909101359150565b6000806040838503121561218f57600080fd5b823561219a816120ec565b91506020830135612126816120ec565b6000602082840312156121bc57600080fd5b5035919050565b6000806000604084860312156121d857600080fd5b83356121e3816120ec565b9250602084013567ffffffffffffffff8111156121ff57600080fd5b61220b8682870161205e565b9497909650939450505050565b600081518084526020808501945080840160005b838110156122485781518752958201959082019060010161222c565b509495945050505050565b6060815260006122666060830186612218565b82810360208481019190915285518083528682019282019060005b818110156122a65784516001600160a01b031683529383019391830191600101612281565b505084810360408601526122ba8187612218565b98975050505050505050565b60008060008060008060c087890312156122df57600080fd5b86356122ea816120ec565b955060208701356122fa816120ec565b9450604087013561230a816120ec565b9350606087013561231a816120ec565b9598949750929560808101359460a0909101359350915050565b60006020828403121561234657600080fd5b8135611816816120ec565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561237a57600080fd5b825167ffffffffffffffff8082111561239257600080fd5b818501915085601f8301126123a657600080fd5b8151818111156123b8576123b8612351565b8060051b604051601f19603f830116810181811085821117156123dd576123dd612351565b6040529182528482019250838101850191888311156123fb57600080fd5b938501935b828510156122ba57845184529385019392850192612400565b634e487b7160e01b600052601160045260246000fd5b6000600160ff1b820161244457612444612419565b5060000390565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561247357600080fd5b5051919050565b6000806040838503121561248d57600080fd5b8251612498816120ec565b6020939093015192949293505050565b6000600182016124ba576124ba612419565b5060010190565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156124e957600080fd5b81516004811061181657600080fd5b8082028115828204841417610c1d57610c1d612419565b60008261252c57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610c1d57610c1d612419565b80820180821115610c1d57610c1d612419565b60006020828403121561256957600080fd5b8151801515811461181657600080fd5b6000825160005b8181101561259a5760208186018101518583015201612580565b50600092019182525091905056fea2646970667358221220dfbe43c5969df2a6dfaefc1778de098c1e32d5ed41e46ad89668ddaa3f49294c64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004515a45337f461a11ff0fe8abf3c606ae5dc00c900000000000000000000000055160b0f39848a7b844f3a562210489df301dee7000000000000000000000000e283db759720982094de7fc6edc49d3adf84894300000000000000000000000084ebcc334c24ce53e7c7551670c92a4bd2a84afb000000000000000000000000000000000000000000000000051ce4fed1e17943
-----Decoded View---------------
Arg [0] : moe (address): 0x4515A45337F461A11Ff0FE8aBF3c606AE5dC00c9
Arg [1] : veMoe (address): 0x55160b0f39848A7B844f3a562210489dF301dee7
Arg [2] : rewarderFactory (address): 0xE283Db759720982094de7Fc6Edc49D3adf848943
Arg [3] : lbHooksManager (address): 0x84EbcC334C24ce53e7C7551670c92a4bD2A84AfB
Arg [4] : treasuryShare (uint256): 368421052631578947
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000004515a45337f461a11ff0fe8abf3c606ae5dc00c9
Arg [1] : 00000000000000000000000055160b0f39848a7b844f3a562210489df301dee7
Arg [2] : 000000000000000000000000e283db759720982094de7fc6edc49d3adf848943
Arg [3] : 00000000000000000000000084ebcc334c24ce53e7c7551670c92a4bd2a84afb
Arg [4] : 000000000000000000000000000000000000000000000000051ce4fed1e17943
Deployed Bytecode Sourcemap
1283:17993:8:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11456:95;;;;;;:::i;:::-;;:::i;:::-;;12872:156;;;;;;:::i;:::-;;:::i;11727:309::-;;;;;;:::i;:::-;;:::i;5145:97::-;5200:7;5226:9;-1:-1:-1;;;;;5226:9:8;5145:97;;;-1:-1:-1;;;;;1838:55:22;;;1820:74;;1808:2;1793:18;5145:97:8;;;;;;;;10304:203;;;;;;:::i;:::-;;:::i;12186:510::-;;;;;;:::i;:::-;;:::i;10943:396::-;;;;;;:::i;:::-;;:::i;6891:1274::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;9147:105::-;9232:13;;-1:-1:-1;;;9232:13:8;;-1:-1:-1;;;;;9232:13:8;9147:105;;;5048:25:22;;;5036:2;5021:18;9147:105:8;4902:177:22;4670:120:8;4767:16;4670:120;;10628:168;;;;;;:::i;:::-;;:::i;13298:111::-;;;:::i;5419:107::-;5505:14;5419:107;;2774:229:0;;;:::i;4449:90:8:-;4526:6;4449:90;;2441:144:1;;;:::i;4238:84:8:-;4311:4;4238:84;;4921:109;5008:15;4921:109;;5989:155;;;;;;:::i;:::-;;:::i;8597:150::-;;;;;;:::i;:::-;;:::i;5625:106::-;5711:6;:13;5625:106;;6318:139;;;;;;:::i;:::-;;:::i;9594:170::-;;;;;;:::i;:::-;;:::i;3442:679::-;;;;;;:::i;:::-;;:::i;9922:220::-;;;;;;:::i;:::-;;:::i;1680:168:0:-;;;:::i;8309:112:8:-;;;;;;:::i;:::-;;:::i;8909:141::-;;;;;;:::i;:::-;;:::i;13122:106::-;;;;;;:::i;:::-;;:::i;2041:247:0:-;;;;;;:::i;:::-;;:::i;11456:95:8:-;11528:16;11539:4;;11528:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11528:10:8;;-1:-1:-1;;;11528:16:8:i;:::-;11456:95;;:::o;12872:156::-;2334:13:1;:11;:13::i;:::-;12984:37:8::1;13002:3;13007:13;12984:17;:37::i;11727:309::-:0;2334:13:1;:11;:13::i;:::-;521:5:19::1;11815:12:8;-1:-1:-1::0;;;;;11815:43:8::1;;11811:89;;;11867:33;;-1:-1:-1::0;;;11867:33:8::1;;;;;;;;;;;11811:89;11911:34;11922:6;-1:-1:-1::0;;;;;11922:20:8::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;11922:22:8::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;11911:10;:34::i;:::-;11956:13;:28:::0;;-1:-1:-1;;;;;11956:28:8::1;-1:-1:-1::0;;;;;;;;11956:28:8;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;12000:29:::1;::::0;9233:58:22;;;12000:29:8::1;::::0;9221:2:22;9206:18;12000:29:8::1;;;;;;;11727:309:::0;:::o;10304:203::-;10379:44;10387:3;10392:10;10405:17;:6;:15;:17::i;:::-;10404:18;;;:::i;:::-;10379:7;:44::i;:::-;10438:10;;10434:66;;10450:50;10481:10;10493:6;10450;10457:3;10450:11;;;;;;;;:::i;:::-;;;;;;;;;:17;:11;;;;;:17;;-1:-1:-1;;;;;10450:17:8;;:50;:30;:50::i;12186:510::-;12280:10;-1:-1:-1;;;;;12302:15:8;12280:38;;12276:57;;12320:13;:11;:13::i;:::-;12358:6;:13;;12402;;;;;-1:-1:-1;12402:13:8;;;;;;;12426:10;;;:18;;-1:-1:-1;;;;;;12426:18:8;-1:-1:-1;;;;;12426:18:8;;;;;;;;;;12490:15;12454:13;;;:51;12402:13;;;;;12520:36;;;12516:79;;12558:37;12576:3;12581:13;12558:17;:37::i;:::-;12606:30;;-1:-1:-1;;;12606:30:8;;12630:4;12606:30;;;1820:74:22;-1:-1:-1;;;;;12606:15:8;;;;;1793:18:22;;12606:30:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;12668:21:8;;-1:-1:-1;;;;;12668:21:8;;;12678:3;;12668:21;;;;;12266:430;;12186:510;;:::o;10943:396::-;11011:17;11031:6;11038:3;11031:11;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;11071:36:8;11031:11;11096:10;11071:24;:36::i;:::-;11053:54;;11117:18;11139;:7;:16;:18::i;:::-;11138:19;;;:::i;:::-;11117:40;-1:-1:-1;11168:44:8;:4;11188:10;11117:40;11168:19;:44::i;:::-;-1:-1:-1;;;11223:10:8;;;;:44;;-1:-1:-1;;;;;;11223:10:8;11247;11259:7;11223:23;:44::i;:::-;11283:49;;;10076:25:22;;;11330:1:8;10132:2:22;10117:18;;10110:34;11305:10:8;;11300:3;;11283:49;;10049:18:22;11283:49:8;;;;;;;11001:338;;;10943:396;:::o;6891:1274::-;7024:27;;;7154:4;7140:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7140:26:8;-1:-1:-1;7127:39:8;-1:-1:-1;7203:4:8;7190:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7190:25:8;-1:-1:-1;7176:39:8;-1:-1:-1;7254:4:8;7240:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7240:26:8;;7225:41;;7282:9;7277:882;7293:15;;;7277:882;;;7329:11;7343:4;;7348:1;7343:7;;;;;;;:::i;:::-;;;;;;;7329:21;;7365:17;7385:6;7392:3;7385:11;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;7449:13:8;;;;7385:11;;7557:28;7385:11;7577:7;7557:19;:28::i;:::-;7539:46;;7599:19;7621:24;:7;1747:19:18;;1647:126;7621:24:8;7599:46;;7681:23;7708:63;7726:44;7743:8;7753:3;7758:11;7726:16;:44::i;:::-;7708:17;:63::i;:::-;7678:93;-1:-1:-1;7806:73:8;;-1:-1:-1;7806:8:8;7832:7;7841;7850:11;7678:93;7806:25;:73::i;:::-;7790:10;7801:1;7790:13;;;;;;;;:::i;:::-;;;;;;;;;;:89;-1:-1:-1;7944:18:8;;;;-1:-1:-1;;;;;7944:18:8;7981:36;;7977:172;;8073:61;;-1:-1:-1;;;8073:61:8;;-1:-1:-1;;;;;10375:55:22;;;8073:61:8;;;10357:74:22;10447:18;;;10440:34;;;10490:18;;;10483:34;;;8073:30:8;;;;;10330:18:22;;8073:61:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8038:11;8050:1;8038:14;;;;;;;;:::i;:::-;;;;;;8054:12;8067:1;8054:15;;;;;;;;:::i;:::-;;;;;;8037:97;;;;;-1:-1:-1;;;;;8037:97:8;-1:-1:-1;;;;;8037:97:8;;;;;;7977:172;7315:844;;;;;;;7310:3;;;;:::i;:::-;;;7277:882;;;;6891:1274;;;;;;;:::o;10628:168::-;10701:9;10696:94;10712:15;;;10696:94;;;10748:31;10756:4;;10761:1;10756:7;;;;;;;:::i;:::-;;;;;;;10765:10;10777:1;10748:7;:31::i;:::-;10729:3;;;:::i;:::-;;;10696:94;;;;10628:168;;:::o;13298:111::-;13365:37;;-1:-1:-1;;;13365:37:8;;;;;;;;;;;2774:229:0;966:10:3;;2869:14:0;:12;:14::i;:::-;-1:-1:-1;;;;;2869:24:0;;2865:96;;2916:34;;-1:-1:-1;;;2916:34:0;;-1:-1:-1;;;;;1838:55:22;;2916:34:0;;;1820:74:22;1793:18;;2916:34:0;;;;;;;;2865:96;2970:26;2989:6;2970:18;:26::i;:::-;2816:187;2774:229::o;2441:144:1:-;2487:7;;1313:22;2533:20;2570:8;-1:-1:-1;;;;;2570:8:1;;2441:144;-1:-1:-1;;2441:144:1:o;5989:155:8:-;6071:7;6097:40;6129:7;6097:6;6104:3;6097:11;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:31;:40::i;:::-;6090:47;;5989:155;;;;;:::o;8597:150::-;8674:7;8700:6;8707:3;8700:11;;;;;;;;:::i;:::-;;;;;;;;;;;:20;;:40;;;8693:47;;8597:150;;;:::o;6318:139::-;6388:7;6414:36;:6;6421:3;6414:11;;;;;;;;:::i;:::-;;;;;;;;;;;:19;;1747::18;;1647:126;9594:170:8;9670:7;9696:61;9713:3;9718:13;;;;;;;;;-1:-1:-1;;;;;9718:13:8;-1:-1:-1;;;;;9696:61:8;9733:6;-1:-1:-1;;;;;9733:21:8;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9696:16;:61::i;3442:679::-;8870:21:2;6431:15;;3665:1:8;;8870:21:2;6431:15;;;;;;:44;;-1:-1:-1;6450:14:2;;:25;;;;:14;;:25;;6431:44;6427:105;;;6498:23;;-1:-1:-1;;;6498:23:2;;;;;;;;;;;6427:105;6541:24;;-1:-1:-1;;6575:22:2;6541:24;;;6575:22;;;;;3678:28:8::1;3693:12:::0;3678:14:::1;:28::i;:::-;3717:22;3730:8;3717:12;:22::i;:::-;3750:29;3816:1:::0;3794:19:::1;:23;:84;;3877:1;3794:84;;;3820:54;::::0;-1:-1:-1;;;3820:54:8;;-1:-1:-1;;;;;11212:55:22;;;3820:54:8::1;::::0;::::1;11194:74:22::0;11284:18;;;11277:34;;;3820:4:8::1;:9;::::0;::::1;::::0;11167:18:22;;3820:54:8::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3750:128;;3888:20;3924:1:::0;3911:10:::1;:14;:57;;3967:1;3911:57;;;3928:36;::::0;-1:-1:-1;;;3928:36:8;;-1:-1:-1;;;;;11212:55:22;;;3928:36:8::1;::::0;::::1;11194:74:22::0;11284:18;;;11277:34;;;3928:4:8::1;:9;::::0;::::1;::::0;11167:18:22;;3928:36:8::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3888:80;;4008:19;3983:21;:44;;:74;;;;4047:10;4031:12;:26;;3983:74;3979:136;;;4080:24;;-1:-1:-1::0;;;4080:24:8::1;;;;;;;;;;;3979:136;-1:-1:-1::0;;6618:23:2;;-1:-1:-1;;6618:23:2;;;6656:20;;11496:18:22;11484:31;;11466:50;;6656:20:2;;11454:2:22;11439:18;6656:20:2;;;;;;;6291:392;3442:679:8;;;;;;;:::o;9922:220::-;9996:43;10004:3;10009:10;10021:17;:6;:15;:17::i;9996:43::-;10054:10;;10050:85;;10066:69;10101:10;10121:4;10128:6;10066;10073:3;10066:11;;;;;;;;:::i;:::-;;;;;;;;;:17;:11;;;;;:17;;-1:-1:-1;;;;;10066:17:8;;:69;;:34;:69::i;1680:168:0:-;1733:7;;1318:27;1784:25;1187:174;8309:112:8;8372:6;8397;8404:3;8397:11;;;;;;;;:::i;:::-;;;;;;;;;:17;:11;;;;;:17;;-1:-1:-1;;;;;8397:17:8;;8309:112;-1:-1:-1;;8309:112:8:o;8909:141::-;8980:19;9018:6;9025:3;9018:11;;;;;;;;:::i;:::-;;;;;;;;;:25;:11;;;;;:25;;-1:-1:-1;;;;;9018:25:8;;8909:141;-1:-1:-1;;8909:141:8:o;13122:106::-;2334:13:1;:11;:13::i;:::-;13199:22:8::1;13212:8;13199:12;:22::i;2041:247:0:-:0;2334:13:1;:11;:13::i;:::-;1318:27:0;2197:26;;-1:-1:-1;;;;;;2197:26:0::1;-1:-1:-1::0;;;;;2197:26:0;::::1;::::0;;::::1;::::0;;2263:7:::1;:5;:7::i;:::-;-1:-1:-1::0;;;;;2238:43:0::1;;;;;;;;;;;2120:168;2041:247:::0;:::o;15883:791:8:-;15944:14;15961:4;:11;15944:28;;15983:19;16005:6;-1:-1:-1;;;;;16005:21:8;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16061:13;;15983:45;;-1:-1:-1;;;;16061:13:8;;-1:-1:-1;;;;;16061:13:8;16038:20;16085:583;16105:6;16101:1;:10;16085:583;;;16132:11;16146:4;16151:1;16146:7;;;;;;;;:::i;:::-;;;;;;;16132:21;;16168:17;16188:6;16195:3;16188:11;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;16251:13:8;;;;16301:29;16188:11;1747:19:18;;1647:126;16301:29:8;16279:51;-1:-1:-1;16344:20:8;16367:51;:8;16392:12;16279:51;16367:24;:51::i;:::-;16344:74;;16433:28;16464:48;16481:3;16486:12;16500:11;16464:16;:48::i;:::-;16433:79;;16526:23;16552:30;16561:20;16552:8;:30::i;:::-;16526:56;-1:-1:-1;16597:60:8;:8;16628:11;16526:56;16597:30;:60::i;:::-;;16118:550;;;;;;;16113:3;;;;:::i;:::-;;;16085:583;;;;15934:740;;;15883:791;:::o;2658:162:1:-;966:10:3;2717:7:1;:5;:7::i;:::-;-1:-1:-1;;;;;2717:23:1;;2713:101;;2763:40;;-1:-1:-1;;;2763:40:1;;966:10:3;2763:40:1;;;1820:74:22;1793:18;;2763:40:1;1674:226:22;2713:101:1;2658:162::o;15079:687:8:-;-1:-1:-1;;;;;15189:36:8;;;;;;:155;;-1:-1:-1;15296:48:8;15245:47;;-1:-1:-1;;;15245:47:8;;-1:-1:-1;;;;;1838:55:22;;;15245:47:8;;;1820:74:22;15245:16:8;:32;;;;1793:18:22;;15245:47:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:99;;;;;;;;:::i;:::-;;;15189:155;15172:250;;;15376:35;;-1:-1:-1;;;15376:35:8;;;;;;;;;;;15172:250;15432:36;15471:6;15478:3;15471:11;;;;;;;;:::i;:::-;;;;;;;;;:25;:11;;;;;:25;;-1:-1:-1;;;;;15471:25:8;;-1:-1:-1;15511:39:8;;15507:73;;15552:28;;-1:-1:-1;;;15552:28:8;;;;;5048:25:22;;;-1:-1:-1;;;;;15552:23:8;;;;;5021:18:22;;15552:28:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15507:73;-1:-1:-1;;;;;15594:36:8;;;15590:65;;15632:23;;-1:-1:-1;;;15632:23:8;;;;;5048:25:22;;;-1:-1:-1;;;;;15632:18:8;;;;;5021::22;;15632:23:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15590:65;15694:13;15666:6;15673:3;15666:11;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:25;;:41;;-1:-1:-1;;;;;;15666:41:8;-1:-1:-1;;;;;15666:41:8;;;;;;15723:36;;1838:55:22;;;1820:74;;15740:3:8;;15723:36;;1793:18:22;15723:36:8;;;;;;;15162:604;15079:687;;:::o;1119:154:20:-;1171:8;-1:-1:-1;;;;;1195:1:20;:14;1191:48;;;1218:21;;-1:-1:-1;;;1218:21:20;;;;;;;;;;;1191:48;-1:-1:-1;1264:1:20;1119:154::o;16931:925:8:-;17016:17;17036:6;17043:3;17036:11;;;;;;;;:::i;:::-;;;;;;;;17154:18;17036:11;;;;;17154:18;;;;17036:11;;-1:-1:-1;17095:13:8;;;;-1:-1:-1;;;;;17154:18:8;;;;17036:11;;17251:41;17036:11;17271:7;17280:11;17251:19;:41::i;:::-;17183:109;;;;;;;17303:28;17334:47;17351:8;17361:3;17366:14;17334:16;:47::i;:::-;17303:78;;17391:23;17417:30;17426:20;17417:8;:30::i;:::-;17391:56;-1:-1:-1;17458:17:8;17478:81;:8;17494:7;17503:10;17515;17527:14;17391:56;17478:15;:81::i;:::-;17458:101;-1:-1:-1;17574:13:8;;17570:56;;17589:37;-1:-1:-1;;;;;17589:4:8;:17;17607:7;17616:9;17589:17;:37::i;:::-;-1:-1:-1;;;;;17641:36:8;;;17637:143;;17693:76;;-1:-1:-1;;;17693:76:8;;-1:-1:-1;;;;;12218:55:22;;;17693:76:8;;;12200:74:22;12290:18;;;12283:34;;;12333:18;;;12326:34;;;12376:18;;;12369:34;;;12419:19;;;12412:35;;;17693:22:8;;;;;12172:19:22;;17693:76:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;17637:143;17795:54;;;10076:25:22;;;10132:2;10117:18;;10110:34;;;-1:-1:-1;;;;;17795:54:8;;;17812:3;;17795:54;;10049:18:22;17795:54:8;;;;;;;17006:850;;;;;;;;;16931:925;;;:::o;1303:160:6:-;1412:43;;-1:-1:-1;;;;;11212:55:22;;;1412:43:6;;;11194:74:22;11284:18;;;11277:34;;;1385:71:6;;1405:5;;1427:14;;;;;11167:18:22;;1412:43:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1385:19;:71::i;973:177:18:-;-1:-1:-1;;;;;1116:25:18;;1061:7;729:20;;;:15;;;:20;;;;;;1087:56;619:137;3412:292;3526:17;;;;3633:64;3640:7;-1:-1:-1;;;;;3657:25:18;;3685:11;3633:6;:64::i;:::-;3626:71;;;;;;;;3412:292;;;;;;;;:::o;13831:280:8:-;14051:13;;13974:7;;14004:100;;14021:3;;14026:52;;:8;;-1:-1:-1;;;14051:13:8;;-1:-1:-1;;;;;14051:13:8;14066:11;14026:24;:52::i;:::-;14080:6;-1:-1:-1;;;;;14080:21:8;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14004:100;13997:107;;13831:280;;;;;;:::o;18990:284::-;19079:22;;290:4:19;19165:23:8;19174:14;19165:6;:23;:::i;:::-;:45;;;;:::i;:::-;19148:62;-1:-1:-1;19244:23:8;19148:62;19244:6;:23;:::i;:::-;19220:47;;18990:284;;;:::o;4131:416:21:-;4331:7;4350:23;4403:42;4419:11;4432:12;4403:15;:42::i;:::-;4376:8;:24;;;:69;;;;:::i;:::-;4350:95;-1:-1:-1;4463:12:21;;:77;;-1:-1:-1;;;;;4518:22:21;;;;;;:13;;;:22;;;;;;4482:33;4490:15;4507:7;4482;:33::i;:::-;:58;;;;:::i;:::-;4463:77;;;4478:1;4463:77;4456:84;4131:416;-1:-1:-1;;;;;;;4131:416:21:o;2472:222:0:-;1318:27;2621:22;;-1:-1:-1;;;;;;2621:22:0;;;2653:34;2678:8;2653:24;:34::i;14519:210:8:-;14623:7;14649:16;;:73;;14687:21;;-1:-1:-1;;;14687:21:8;;;;;5048:25:22;;;14711:11:8;;14687:6;-1:-1:-1;;;;;14687:16:8;;;;5021:18:22;;14687:21:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14672:36;;:12;:36;:::i;:::-;:50;;;;:::i;:::-;14649:73;;;-1:-1:-1;14668:1:8;;14519:210;-1:-1:-1;;;14519:210:8:o;1847:127:1:-;6931:20:2;:18;:20::i;:::-;1929:38:1::1;1954:12;1929:24;:38::i;17950:193:8:-:0;-1:-1:-1;;;;;18012:22:8;;18008:60;;18043:25;;-1:-1:-1;;;18043:25:8;;;;;;;;;;;18008:60;18079:9;:20;;-1:-1:-1;;;;;;18079:20:8;-1:-1:-1;;;;;18079:20:8;;;;;;;18115:21;;18079:20;;18115:21;;;17950:193;:::o;1702:188:6:-;1829:53;;-1:-1:-1;;;;;13648:15:22;;;1829:53:6;;;13630:34:22;13700:15;;;13680:18;;;13673:43;13732:18;;;13725:34;;;1802:81:6;;1822:5;;1844:18;;;;;13542::22;;1829:53:6;13367:398:22;1802:81:6;1702:188;;;;:::o;2765:255:21:-;2911:7;2941:72;2957:8;2967:15;2984;3001:11;2941:15;:72::i;18356:307:8:-;18407:7;18430:6;18440:1;18430:11;18426:25;;-1:-1:-1;18450:1:8;;18356:307;-1:-1:-1;18356:307:8:o;18426:25::-;18463:22;18487:29;18520:25;18538:6;18520:17;:25::i;:::-;18566:9;;18556:36;;-1:-1:-1;;;18556:36:8;;-1:-1:-1;;;;;18566:9:8;;;18556:36;;;11194:74:22;11284:18;;;11277:34;;;18462:83:8;;-1:-1:-1;18462:83:8;;-1:-1:-1;18556:4:8;:9;;;;11167:18:22;;18556:36:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;18609:47:8;;-1:-1:-1;;;18609:47:8;;18627:4;18609:47;;;11194:74:22;11284:18;;;11277:34;;;18609:4:8;-1:-1:-1;;;;;18609:9:8;;;;11167:18:22;;18609:47:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18602:54;18356:307;-1:-1:-1;;;;18356:307:8:o;5917:445:21:-;6053:7;6076:20;6099:42;6115:11;6128:12;6099:15;:42::i;:::-;6174:28;;6076:65;;-1:-1:-1;6156:15:21;:46;6152:98;;;6235:15;6204:46;;6152:98;6268:17;;:87;;6343:12;6315:8;:24;;;:40;;;;;;;:::i;:::-;;;;;;;6268:87;;;6288:8;:24;;;6268:87;6261:94;5917:445;-1:-1:-1;;;;;5917:445:21:o;5036:510::-;5252:15;5279:23;5305:58;5327:8;5337:11;5350:12;5305:21;:58::i;:::-;5279:84;-1:-1:-1;5384:15:21;;:83;;-1:-1:-1;;;;;5445:22:21;;;;;;:13;;;:22;;;;;;5406:36;5414:15;5431:10;5406:7;:36::i;:::-;:61;;;;:::i;:::-;5384:83;;;5402:1;5384:83;5374:93;;5503:36;5511:15;5528:10;5503:7;:36::i;:::-;-1:-1:-1;;;;;5478:22:21;;;;;;;:13;;;;:22;;-1:-1:-1;5478:22:21;;;;:61;;;;-1:-1:-1;5036:510:21;;;-1:-1:-1;;;5036:510:21:o;4059:629:6:-;4478:23;4504:33;-1:-1:-1;;;;;4504:27:6;;4532:4;4504:27;:33::i;:::-;4478:59;;4551:10;:17;4572:1;4551:22;;:57;;;;;4589:10;4578:30;;;;;;;;;;;;:::i;:::-;4577:31;4551:57;4547:135;;;4631:40;;-1:-1:-1;;;4631:40:6;;-1:-1:-1;;;;;1838:55:22;;4631:40:6;;;1820:74:22;1793:18;;4631:40:6;1674:226:22;2256:656:18;2366:17;2478:20;;;:15;;;:20;;;;;;2525:19;;2478:20;;2366:17;;2559:16;;;2555:351;;-1:-1:-1;2603:9:18;;-1:-1:-1;2643:14:18;2555:351;;;2700:31;:9;2719:11;2700:18;:31::i;:::-;2688:43;-1:-1:-1;2762:36:18;:14;2786:11;2762:23;:36::i;:::-;2813:20;;;;:15;;;:20;;;;;:32;;;2859:36;;;2745:53;-1:-1:-1;2256:656:18;;;;;;;:::o;1314:210:21:-;1406:7;1432:17;;:85;;1456:61;1505:12;244:2:19;1457:44:21;;;1456:61;:::i;:::-;1432:85;;;-1:-1:-1;1452:1:21;;1314:210;-1:-1:-1;;1314:210:21:o;849:174::-;931:7;244:2:19;958:25:21;968:15;958:7;:25;:::i;:::-;957:59;;;849:174;-1:-1:-1;;;849:174:21:o;3774:248:1:-;1313:22;3923:8;;-1:-1:-1;;;;;;3941:19:1;;-1:-1:-1;;;;;3941:19:1;;;;;;;;3975:40;;3923:8;;;;;3975:40;;3847:24;;3975:40;3837:185;;3774:248;:::o;7084:141:2:-;8870:21;8560:40;;;;;;7146:73;;7191:17;;-1:-1:-1;;;7191:17:2;;;;;;;;;;;1980:235:1;6931:20:2;:18;:20::i;:::-;-1:-1:-1;;;;;2076:26:1;::::1;2072:95;;2125:31;::::0;-1:-1:-1;;;2125:31:1;;2153:1:::1;2125:31;::::0;::::1;1820:74:22::0;1793:18;;2125:31:1::1;1674:226:22::0;1998:507:21;2180:7;2203:11;2218:1;2203:16;2199:30;;-1:-1:-1;2228:1:21;2221:8;;2199:30;2270:28;;2240:27;2328:15;:30;-1:-1:-1;2328:63:21;;2376:15;2328:63;;;2361:12;2328:63;2308:83;;2421:19;2409:9;:31;:89;;2497:1;2409:89;;;2479:15;2444:31;2456:19;2444:9;:31;:::i;:::-;2443:51;;;;:::i;2705:151:7:-;2780:12;2811:38;2833:6;2841:4;2847:1;2811:21;:38::i;643:300:20:-;784:13;;;-1:-1:-1;;;;;832:17:20;;;851;;;829:40;822:48;709:9;894:12;;;890:46;;915:21;;-1:-1:-1;;;915:21:20;;;;;;;;;;;890:46;720:223;643:300;;;;:::o;3180:392:7:-;3279:12;3331:5;3307:21;:29;3303:108;;;3359:41;;-1:-1:-1;;;3359:41:7;;3394:4;3359:41;;;1820:74:22;1793:18;;3359:41:7;1674:226:22;3303:108:7;3421:12;3435:23;3462:6;-1:-1:-1;;;;;3462:11:7;3481:5;3488:4;3462:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3420:73;;;;3510:55;3537:6;3545:7;3554:10;3510:26;:55::i;:::-;3503:62;3180:392;-1:-1:-1;;;;;;3180:392:7:o;4625:582::-;4769:12;4798:7;4793:408;;4821:19;4829:10;4821:7;:19::i;:::-;4793:408;;;5045:17;;:22;:49;;;;-1:-1:-1;;;;;;5071:18:7;;;:23;5045:49;5041:119;;;5121:24;;-1:-1:-1;;;5121:24:7;;-1:-1:-1;;;;;1838:55:22;;5121:24:7;;;1820:74:22;1793:18;;5121:24:7;1674:226:22;5041:119:7;-1:-1:-1;5180:10:7;5173:17;;5743:516;5874:17;;:21;5870:383;;6102:10;6096:17;6158:15;6145:10;6141:2;6137:19;6130:44;5870:383;6225:17;;-1:-1:-1;;;6225:17:7;;;;;;;;;;;14:367:22;77:8;87:6;141:3;134:4;126:6;122:17;118:27;108:55;;159:1;156;149:12;108:55;-1:-1:-1;182:20:22;;225:18;214:30;;211:50;;;257:1;254;247:12;211:50;294:4;286:6;282:17;270:29;;354:3;347:4;337:6;334:1;330:14;322:6;318:27;314:38;311:47;308:67;;;371:1;368;361:12;308:67;14:367;;;;;:::o;386:437::-;472:6;480;533:2;521:9;512:7;508:23;504:32;501:52;;;549:1;546;539:12;501:52;589:9;576:23;622:18;614:6;611:30;608:50;;;654:1;651;644:12;608:50;693:70;755:7;746:6;735:9;731:22;693:70;:::i;:::-;782:8;;667:96;;-1:-1:-1;386:437:22;-1:-1:-1;;;;386:437:22:o;828:175::-;-1:-1:-1;;;;;928:5:22;924:54;917:5;914:65;904:93;;993:1;990;983:12;1008:364;1104:6;1112;1165:2;1153:9;1144:7;1140:23;1136:32;1133:52;;;1181:1;1178;1171:12;1133:52;1217:9;1204:23;1194:33;;1277:2;1266:9;1262:18;1249:32;1290:52;1336:5;1290:52;:::i;:::-;1361:5;1351:15;;;1008:364;;;;;:::o;1377:292::-;1435:6;1488:2;1476:9;1467:7;1463:23;1459:32;1456:52;;;1504:1;1501;1494:12;1456:52;1543:9;1530:23;-1:-1:-1;;;;;1586:5:22;1582:38;1575:5;1572:49;1562:77;;1635:1;1632;1625:12;1905:248;1973:6;1981;2034:2;2022:9;2013:7;2009:23;2005:32;2002:52;;;2050:1;2047;2040:12;2002:52;-1:-1:-1;;2073:23:22;;;2143:2;2128:18;;;2115:32;;-1:-1:-1;1905:248:22:o;2158:472::-;2268:6;2276;2329:2;2317:9;2308:7;2304:23;2300:32;2297:52;;;2345:1;2342;2335:12;2297:52;2384:9;2371:23;2403:52;2449:5;2403:52;:::i;:::-;2474:5;-1:-1:-1;2531:2:22;2516:18;;2503:32;2544:54;2503:32;2544:54;:::i;2635:180::-;2694:6;2747:2;2735:9;2726:7;2722:23;2718:32;2715:52;;;2763:1;2760;2753:12;2715:52;-1:-1:-1;2786:23:22;;2635:180;-1:-1:-1;2635:180:22:o;2820:593::-;2915:6;2923;2931;2984:2;2972:9;2963:7;2959:23;2955:32;2952:52;;;3000:1;2997;2990:12;2952:52;3039:9;3026:23;3058:52;3104:5;3058:52;:::i;:::-;3129:5;-1:-1:-1;3185:2:22;3170:18;;3157:32;3212:18;3201:30;;3198:50;;;3244:1;3241;3234:12;3198:50;3283:70;3345:7;3336:6;3325:9;3321:22;3283:70;:::i;:::-;2820:593;;3372:8;;-1:-1:-1;3257:96:22;;-1:-1:-1;;;;2820:593:22:o;3418:435::-;3471:3;3509:5;3503:12;3536:6;3531:3;3524:19;3562:4;3591:2;3586:3;3582:12;3575:19;;3628:2;3621:5;3617:14;3649:1;3659:169;3673:6;3670:1;3667:13;3659:169;;;3734:13;;3722:26;;3768:12;;;;3803:15;;;;3695:1;3688:9;3659:169;;;-1:-1:-1;3844:3:22;;3418:435;-1:-1:-1;;;;;3418:435:22:o;3858:1039::-;4207:2;4196:9;4189:21;4170:4;4233:56;4285:2;4274:9;4270:18;4262:6;4233:56;:::i;:::-;4346:22;;;4308:2;4326:18;;;4319:50;;;;4418:13;;4440:22;;;4516:15;;;;4478;;;4549:1;4559:218;4573:6;4570:1;4567:13;4559:218;;;4638:13;;-1:-1:-1;;;;;4634:62:22;4622:75;;4752:15;;;;4717:12;;;;4595:1;4588:9;4559:218;;;4563:3;;4822:9;4817:3;4813:19;4808:2;4797:9;4793:18;4786:47;4850:41;4887:3;4879:6;4850:41;:::i;:::-;4842:49;3858:1039;-1:-1:-1;;;;;;;;3858:1039:22:o;6171:893::-;6275:6;6283;6291;6299;6307;6315;6368:3;6356:9;6347:7;6343:23;6339:33;6336:53;;;6385:1;6382;6375:12;6336:53;6424:9;6411:23;6443:52;6489:5;6443:52;:::i;:::-;6514:5;-1:-1:-1;6571:2:22;6556:18;;6543:32;6584:54;6543:32;6584:54;:::i;:::-;6657:7;-1:-1:-1;6716:2:22;6701:18;;6688:32;6729:54;6688:32;6729:54;:::i;:::-;6802:7;-1:-1:-1;6861:2:22;6846:18;;6833:32;6874:54;6833:32;6874:54;:::i;:::-;6171:893;;;;-1:-1:-1;6171:893:22;;7001:3;6986:19;;6973:33;;7053:3;7038:19;;;7025:33;;-1:-1:-1;6171:893:22;-1:-1:-1;;6171:893:22:o;7573:268::-;7632:6;7685:2;7673:9;7664:7;7660:23;7656:32;7653:52;;;7701:1;7698;7691:12;7653:52;7740:9;7727:23;7759:52;7805:5;7759:52;:::i;7846:127::-;7907:10;7902:3;7898:20;7895:1;7888:31;7938:4;7935:1;7928:15;7962:4;7959:1;7952:15;7978:1105;8073:6;8104:2;8147;8135:9;8126:7;8122:23;8118:32;8115:52;;;8163:1;8160;8153:12;8115:52;8196:9;8190:16;8225:18;8266:2;8258:6;8255:14;8252:34;;;8282:1;8279;8272:12;8252:34;8320:6;8309:9;8305:22;8295:32;;8365:7;8358:4;8354:2;8350:13;8346:27;8336:55;;8387:1;8384;8377:12;8336:55;8416:2;8410:9;8438:2;8434;8431:10;8428:36;;;8444:18;;:::i;:::-;8490:2;8487:1;8483:10;8522:2;8516:9;8585:2;8581:7;8576:2;8572;8568:11;8564:25;8556:6;8552:38;8640:6;8628:10;8625:22;8620:2;8608:10;8605:18;8602:46;8599:72;;;8651:18;;:::i;:::-;8687:2;8680:22;8737:18;;;8771:15;;;;-1:-1:-1;8813:11:22;;;8809:20;;;8841:19;;;8838:39;;;8873:1;8870;8863:12;8838:39;8897:11;;;;8917:135;8933:6;8928:3;8925:15;8917:135;;;8999:10;;8987:23;;8950:12;;;;9030;;;;8917:135;;9302:127;9363:10;9358:3;9354:20;9351:1;9344:31;9394:4;9391:1;9384:15;9418:4;9415:1;9408:15;9434:136;9469:3;-1:-1:-1;;;9490:22:22;;9487:48;;9515:18;;:::i;:::-;-1:-1:-1;9555:1:22;9551:13;;9434:136::o;9575:127::-;9636:10;9631:3;9627:20;9624:1;9617:31;9667:4;9664:1;9657:15;9691:4;9688:1;9681:15;9707:184;9777:6;9830:2;9818:9;9809:7;9805:23;9801:32;9798:52;;;9846:1;9843;9836:12;9798:52;-1:-1:-1;9869:16:22;;9707:184;-1:-1:-1;9707:184:22:o;10528:347::-;10621:6;10629;10682:2;10670:9;10661:7;10657:23;10653:32;10650:52;;;10698:1;10695;10688:12;10650:52;10730:9;10724:16;10749:52;10795:5;10749:52;:::i;:::-;10865:2;10850:18;;;;10844:25;10820:5;;10844:25;;-1:-1:-1;;;10528:347:22:o;10880:135::-;10919:3;10940:17;;;10937:43;;10960:18;;:::i;:::-;-1:-1:-1;11007:1:22;10996:13;;10880:135::o;11527:127::-;11588:10;11583:3;11579:20;11576:1;11569:31;11619:4;11616:1;11609:15;11643:4;11640:1;11633:15;11659:277;11746:6;11799:2;11787:9;11778:7;11774:23;11770:32;11767:52;;;11815:1;11812;11805:12;11767:52;11847:9;11841:16;11886:1;11879:5;11876:12;11866:40;;11902:1;11899;11892:12;12709:168;12782:9;;;12813;;12830:15;;;12824:22;;12810:37;12800:71;;12851:18;;:::i;12882:217::-;12922:1;12948;12938:132;;12992:10;12987:3;12983:20;12980:1;12973:31;13027:4;13024:1;13017:15;13055:4;13052:1;13045:15;12938:132;-1:-1:-1;13084:9:22;;12882:217::o;13104:128::-;13171:9;;;13192:11;;;13189:37;;;13206:18;;:::i;13237:125::-;13302:9;;;13323:10;;;13320:36;;;13336:18;;:::i;13770:277::-;13837:6;13890:2;13878:9;13869:7;13865:23;13861:32;13858:52;;;13906:1;13903;13896:12;13858:52;13938:9;13932:16;13991:5;13984:13;13977:21;13970:5;13967:32;13957:60;;14013:1;14010;14003:12;14052:412;14181:3;14219:6;14213:13;14244:1;14254:129;14268:6;14265:1;14262:13;14254:129;;;14366:4;14350:14;;;14346:25;;14340:32;14327:11;;;14320:53;14283:12;14254:129;;;-1:-1:-1;14438:1:22;14402:16;;14427:13;;;-1:-1:-1;14402:16:22;14052:412;-1:-1:-1;14052:412:22:o
Swarm Source
ipfs://dfbe43c5969df2a6dfaefc1778de098c1e32d5ed41e46ad89668ddaa3f49294c
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in MNT
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.