View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ComplexRewarderPerSecV2
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./IComplexRewarder.sol";
import "../IStellaDistributorV2.sol";
import "../libraries/BoringERC20.sol";
/**
* This is a sample contract to be used in the StellaDistributorV2 contract for partners to reward
* stakers with their native token alongside STELLA.
*
* It assumes no minting rights, so requires a set amount of YOUR_TOKEN to be transferred to this contract prior.
* E.g. say you've allocated 100,000 XYZ to the STELLA-XYZ farm over 30 days. Then you would need to transfer
* 100,000 XYZ and set the block reward accordingly so it's fully distributed after 30 days.
*/
contract ComplexRewarderPerSecV2 is IComplexRewarder, Ownable, ReentrancyGuard {
using BoringERC20 for IBoringERC20;
IBoringERC20 public immutable override rewardToken;
IStellaDistributorV2 public immutable distributorV2;
bool public immutable isNative;
/// @notice Info of each distributorV2 user.
/// `amount` LP token amount the user has provided.
/// `rewardDebt` The amount of REWARD entitled to the user.
struct UserInfo {
uint256 amount;
uint256 rewardDebt;
}
/// @notice Info of each distributorV2 poolInfo.
/// `accTokenPerShare` Amount of REWARD each LP token is worth.
/// `startTimestamp` The start timestamp of rewards.
/// `lastRewardTimestamp` The last timestamp REWARD was rewarded to the poolInfo.
/// `allocPoint` The amount of allocation points assigned to the pool.
/// `totalRewards` The amount of rewards added to the pool.
struct PoolInfo {
uint256 accTokenPerShare;
uint256 startTimestamp;
uint256 lastRewardTimestamp;
uint256 allocPoint;
uint256 totalRewards;
}
/// @notice Reward info
/// `startTimestamp` The start timestamp of rewards
/// `endTimestamp` The end timestamp of rewards
/// `rewardPerSec` The amount of rewards per second
struct RewardInfo {
uint256 startTimestamp;
uint256 endTimestamp;
uint256 rewardPerSec;
}
/// @notice Info of each pool.
mapping(uint256 => PoolInfo) public poolInfo;
/// @dev this is mostly used for extending reward period
/// @notice Reward info is a set of {endTimestamp, rewardPerSec}
/// indexed by pool id
mapping(uint256 => RewardInfo[]) public poolRewardInfo;
uint256[] public poolIds;
/// @notice Info of each user that stakes LP tokens.
mapping(uint256 => mapping(address => UserInfo)) public userInfo;
/// @dev Total allocation points. Must be the sum of all allocation points in all pools.
uint256 public totalAllocPoint = 0;
/// @notice limit length of reward info
/// how many phases are allowed
uint256 public immutable rewardInfoLimit = 52; //1y
// The precision factor
uint256 private immutable ACC_TOKEN_PRECISION;
event OnReward(address indexed user, uint256 amount);
event RewardRateUpdated(uint256 oldRate, uint256 newRate);
event AddPool(uint256 indexed pid, uint256 allocPoint);
event SetPool(uint256 indexed pid, uint256 allocPoint);
event UpdatePool(
uint256 indexed pid,
uint256 lastRewardTimestamp,
uint256 lpSupply,
uint256 accTokenPerShare
);
event AddRewardInfo(
uint256 indexed pid,
uint256 indexed phase,
uint256 endTimestamp,
uint256 rewardPerSec
);
modifier onlyDistributorV2() {
require(
msg.sender == address(distributorV2),
"onlyDistributorV2: only StellaDistributorV2 can call this function"
);
_;
}
constructor(
IBoringERC20 _rewardToken,
IStellaDistributorV2 _distributorV2,
bool _isNative
) {
require(
Address.isContract(address(_rewardToken)),
"constructor: reward token must be a valid contract"
);
require(
Address.isContract(address(_distributorV2)),
"constructor: StellaDistributorV2 must be a valid contract"
);
rewardToken = _rewardToken;
distributorV2 = _distributorV2;
isNative = _isNative;
uint256 decimalsRewardToken = uint256(
_isNative ? 18 : _rewardToken.safeDecimals()
);
require(
decimalsRewardToken < 30,
"constructor: reward token decimals must be inferior to 30"
);
ACC_TOKEN_PRECISION = uint256(
10**(uint256(30) - (decimalsRewardToken))
);
}
/// @notice Add a new pool. Can only be called by the owner.
/// @param _pid pool id on DistributorV2
/// @param _allocPoint allocation of the new pool.
function add(
uint256 _pid,
uint256 _allocPoint,
uint256 _startTimestamp
) public onlyOwner {
require(poolInfo[_pid].lastRewardTimestamp == 0, "pool already exists");
totalAllocPoint += _allocPoint;
poolInfo[_pid] = PoolInfo({
allocPoint: _allocPoint,
startTimestamp: _startTimestamp,
lastRewardTimestamp: _startTimestamp,
accTokenPerShare: 0,
totalRewards: 0
});
poolIds.push(_pid);
emit AddPool(_pid, _allocPoint);
}
/// @notice if the new reward info is added, the reward & its end timestamp will be extended by the newly pushed reward info.
function addRewardInfo(
uint256 _pid,
uint256 _endTimestamp,
uint256 _rewardPerSec
) external payable onlyOwner {
RewardInfo[] storage rewardInfo = poolRewardInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
require(
rewardInfo.length < rewardInfoLimit,
"add reward info: reward info length exceeds the limit"
);
require(
rewardInfo.length == 0 ||
rewardInfo[rewardInfo.length - 1].endTimestamp >=
block.timestamp,
"add reward info: reward period ended"
);
require(
rewardInfo.length == 0 ||
rewardInfo[rewardInfo.length - 1].endTimestamp < _endTimestamp,
"add reward info: bad new endTimestamp"
);
uint256 startTimestamp = rewardInfo.length == 0
? pool.startTimestamp
: rewardInfo[rewardInfo.length - 1].endTimestamp;
uint256 timeRange = _endTimestamp - startTimestamp;
uint256 totalRewards = timeRange * _rewardPerSec;
if (!isNative) {
rewardToken.safeTransferFrom(
msg.sender,
address(this),
totalRewards
);
} else {
require(
msg.value == totalRewards,
"add reward info: not enough funds to transfer"
);
}
pool.totalRewards += totalRewards;
rewardInfo.push(
RewardInfo({
startTimestamp: startTimestamp,
endTimestamp: _endTimestamp,
rewardPerSec: _rewardPerSec
})
);
emit AddRewardInfo(
_pid,
rewardInfo.length - 1,
_endTimestamp,
_rewardPerSec
);
}
function _endTimestampOf(uint256 _pid, uint256 _timestamp)
internal
view
returns (uint256)
{
RewardInfo[] memory rewardInfo = poolRewardInfo[_pid];
uint256 len = rewardInfo.length;
if (len == 0) {
return 0;
}
for (uint256 i = 0; i < len; ++i) {
if (_timestamp <= rewardInfo[i].endTimestamp)
return rewardInfo[i].endTimestamp;
}
/// @dev when couldn't find any reward info, it means that _timestamp exceed endTimestamp
/// so return the latest reward info.
return rewardInfo[len - 1].endTimestamp;
}
/// @notice this will return end timestamp based on the current block timestamp.
function currentEndTimestamp(uint256 _pid) external view returns (uint256) {
return _endTimestampOf(_pid, block.timestamp);
}
/// @notice Return reward multiplier over the given _from to _to timestamp.
function _getTimeElapsed(
uint256 _from,
uint256 _to,
uint256 _endTimestamp
) public pure returns (uint256) {
if ((_from >= _endTimestamp) || (_from > _to)) {
return 0;
}
if (_to <= _endTimestamp) {
return _to - _from;
}
return _endTimestamp - _from;
}
/// @notice Update reward variables of the given pool.
/// @param _pid The index of the pool. See `poolInfo`.
/// @return pool Returns the pool that was updated.
function updatePool(uint256 _pid)
external
nonReentrant
returns (PoolInfo memory pool)
{
return _updatePool(_pid);
}
/// @notice Update reward variables of the given pool.
/// @param pid The index of the pool. See `poolInfo`.
/// @return pool Returns the pool that was updated.
function _updatePool(uint256 pid) public returns (PoolInfo memory pool) {
pool = poolInfo[pid];
RewardInfo[] memory rewardInfo = poolRewardInfo[pid];
if (block.timestamp <= pool.lastRewardTimestamp) {
return pool;
}
uint256 lpSupply = distributorV2.poolTotalLp(pid);
if (lpSupply == 0) {
// if there is no total supply, return and use the pool's start timestamp as the last reward timestamp
// so that ALL reward will be distributed.
// however, if the first deposit is out of reward period, last reward timestamp will be its timestamp
// in order to keep the multiplier = 0
if (block.timestamp > _endTimestampOf(pid, block.timestamp)) {
pool.lastRewardTimestamp = block.timestamp;
emit UpdatePool(
pid,
pool.lastRewardTimestamp,
lpSupply,
pool.accTokenPerShare
);
}
return pool;
}
/// @dev for each reward info
for (uint256 i = 0; i < rewardInfo.length; ++i) {
// @dev get multiplier based on current timestamp and rewardInfo's end timestamp
// multiplier will be a range of either (current timestamp - pool.timestamp)
// or (reward info's endtimestamp - pool.timestamp) or 0
uint256 timeElapsed = _getTimeElapsed(
pool.lastRewardTimestamp,
block.timestamp,
rewardInfo[i].endTimestamp
);
if (timeElapsed == 0) continue;
// @dev if currentTimestamp exceed end timestamp, use end timestamp as the last reward timestamp
// so that for the next iteration, previous endTimestamp will be used as the last reward timestamp
if (block.timestamp > rewardInfo[i].endTimestamp) {
pool.lastRewardTimestamp = rewardInfo[i].endTimestamp;
} else {
pool.lastRewardTimestamp = block.timestamp;
}
uint256 tokenReward = (timeElapsed *
rewardInfo[i].rewardPerSec *
pool.allocPoint) / totalAllocPoint;
pool.accTokenPerShare += ((tokenReward * ACC_TOKEN_PRECISION) /
lpSupply);
}
poolInfo[pid] = pool;
emit UpdatePool(
pid,
pool.lastRewardTimestamp,
lpSupply,
pool.accTokenPerShare
);
return pool;
}
// Update reward vairables for all pools. Be careful of gas spending!
function massUpdatePools() public nonReentrant {
_massUpdatePools();
}
// Update reward vairables for all pools. Be careful of gas spending!
function _massUpdatePools() internal {
uint256 length = poolIds.length;
for (uint256 pid = 0; pid < length; ++pid) {
_updatePool(poolIds[pid]);
}
}
/// @notice Function called by StellaDistributorV2 whenever staker claims STELLA harvest. Allows staker to also receive a 2nd reward token.
/// @param _user Address of user
/// @param _amount Number of LP tokens the user has
function onStellaReward(
uint256 _pid,
address _user,
uint256 _amount
) external override onlyDistributorV2 nonReentrant {
PoolInfo memory pool = _updatePool(_pid);
UserInfo storage user = userInfo[_pid][_user];
uint256 pending = 0;
uint256 rewardBalance = 0;
if (isNative) {
rewardBalance = address(this).balance;
} else {
rewardBalance = rewardToken.balanceOf(address(this));
}
if (user.amount > 0) {
pending = (((user.amount * pool.accTokenPerShare) /
ACC_TOKEN_PRECISION) - user.rewardDebt);
if (pending > 0) {
if (isNative) {
if (pending > rewardBalance) {
(bool success, ) = _user.call{value: rewardBalance}("");
require(success, "Transfer failed");
} else {
(bool success, ) = _user.call{value: pending}("");
require(success, "Transfer failed");
}
} else {
if (pending > rewardBalance) {
rewardToken.safeTransfer(_user, rewardBalance);
} else {
rewardToken.safeTransfer(_user, pending);
}
}
}
}
user.amount = _amount;
user.rewardDebt =
(user.amount * pool.accTokenPerShare) /
ACC_TOKEN_PRECISION;
emit OnReward(_user, pending);
}
/// @notice View function to see pending Reward on frontend.
function pendingTokens(uint256 _pid, address _user)
external
view
override
returns (uint256)
{
return
_pendingTokens(
_pid,
userInfo[_pid][_user].amount,
userInfo[_pid][_user].rewardDebt
);
}
function _pendingTokens(
uint256 _pid,
uint256 _amount,
uint256 _rewardDebt
) internal view returns (uint256 pending) {
PoolInfo memory pool = poolInfo[_pid];
RewardInfo[] memory rewardInfo = poolRewardInfo[_pid];
uint256 accTokenPerShare = pool.accTokenPerShare;
uint256 lpSupply = distributorV2.poolTotalLp(_pid);
if (block.timestamp > pool.lastRewardTimestamp && lpSupply != 0) {
uint256 cursor = pool.lastRewardTimestamp;
for (uint256 i = 0; i < rewardInfo.length; ++i) {
uint256 timeElapsed = _getTimeElapsed(
cursor,
block.timestamp,
rewardInfo[i].endTimestamp
);
if (timeElapsed == 0) continue;
cursor = rewardInfo[i].endTimestamp;
uint256 tokenReward = (timeElapsed *
rewardInfo[i].rewardPerSec *
pool.allocPoint) / totalAllocPoint;
accTokenPerShare +=
(tokenReward * ACC_TOKEN_PRECISION) /
lpSupply;
}
}
pending = (((_amount * accTokenPerShare) / ACC_TOKEN_PRECISION) -
_rewardDebt);
}
function _rewardPerSecOf(uint256 _pid, uint256 _blockTimestamp)
internal
view
returns (uint256)
{
RewardInfo[] memory rewardInfo = poolRewardInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
uint256 len = rewardInfo.length;
if (len == 0) {
return 0;
}
for (uint256 i = 0; i < len; ++i) {
if (_blockTimestamp <= rewardInfo[i].endTimestamp)
return
(rewardInfo[i].rewardPerSec * pool.allocPoint) /
totalAllocPoint;
}
/// @dev when couldn't find any reward info, it means that timestamp exceed endblock
/// so return 0
return 0;
}
/// @notice View function to see pool rewards per sec
function poolRewardsPerSec(uint256 _pid)
external
view
override
returns (uint256)
{
return _rewardPerSecOf(_pid, block.timestamp);
}
/// @notice Withdraw reward. EMERGENCY ONLY.
function emergencyRewardWithdraw(
uint256 _pid,
uint256 _amount,
address _beneficiary
) external onlyOwner nonReentrant {
PoolInfo storage pool = poolInfo[_pid];
uint256 lpSupply = distributorV2.poolTotalLp(_pid);
uint256 currentStakingPendingReward = _pendingTokens(_pid, lpSupply, 0);
require(
currentStakingPendingReward + _amount <= pool.totalRewards,
"emergency reward withdraw: not enough reward token"
);
pool.totalRewards -= _amount;
if (!isNative) {
rewardToken.safeTransfer(_beneficiary, _amount);
} else {
(bool sent, ) = _beneficiary.call{value: _amount}("");
require(sent, "emergency reward withdraw: failed to send");
}
}
// INCASE SOMETHING WRONG HAPPENS
uint256 public stuckTimeLock = 0;
function inCaseTokensGetStuck(address _token, uint256 _amount) external onlyOwner {
if (stuckTimeLock == 0) {
stuckTimeLock = block.timestamp + 86400;
}
if(stuckTimeLock <= block.timestamp) {
IBoringERC20(_token).safeTransfer(msg.sender, _amount);
stuckTimeLock = 0;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Context.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.
*
* By default, the owner account will be the one that deploys the contract. 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 Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_setOwner(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_setOwner(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 {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "../libraries/IBoringERC20.sol";
interface IComplexRewarder {
function onStellaReward(
uint256 pid,
address user,
uint256 newLpAmount
) external;
function pendingTokens(uint256 pid, address user)
external
view
returns (uint256 pending);
function rewardToken() external view returns (IBoringERC20);
function poolRewardsPerSec(uint256 pid) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
interface IStellaDistributorV2 {
function totalAllocPoint() external view returns (uint256);
function deposit(uint256 _pid, uint256 _amount) external;
function poolLength() external view returns (uint256);
function poolTotalLp(uint256 pid) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
// solhint-disable avoid-low-level-calls
import "./IBoringERC20.sol";
library BoringERC20 {
bytes4 private constant SIG_SYMBOL = 0x95d89b41; // symbol()
bytes4 private constant SIG_NAME = 0x06fdde03; // name()
bytes4 private constant SIG_DECIMALS = 0x313ce567; // decimals()
bytes4 private constant SIG_TRANSFER = 0xa9059cbb; // transfer(address,uint256)
bytes4 private constant SIG_TRANSFER_FROM = 0x23b872dd; // transferFrom(address,address,uint256)
function returnDataToString(bytes memory data)
internal
pure
returns (string memory)
{
if (data.length >= 64) {
return abi.decode(data, (string));
} else if (data.length == 32) {
uint8 i = 0;
while (i < 32 && data[i] != 0) {
i++;
}
bytes memory bytesArray = new bytes(i);
for (i = 0; i < 32 && data[i] != 0; i++) {
bytesArray[i] = data[i];
}
return string(bytesArray);
} else {
return "???";
}
}
/// @notice Provides a safe ERC20.symbol version which returns '???' as fallback string.
/// @param token The address of the ERC-20 token contract.
/// @return (string) Token symbol.
function safeSymbol(IBoringERC20 token)
internal
view
returns (string memory)
{
(bool success, bytes memory data) = address(token).staticcall(
abi.encodeWithSelector(SIG_SYMBOL)
);
return success ? returnDataToString(data) : "???";
}
/// @notice Provides a safe ERC20.name version which returns '???' as fallback string.
/// @param token The address of the ERC-20 token contract.
/// @return (string) Token name.
function safeName(IBoringERC20 token)
internal
view
returns (string memory)
{
(bool success, bytes memory data) = address(token).staticcall(
abi.encodeWithSelector(SIG_NAME)
);
return success ? returnDataToString(data) : "???";
}
/// @notice Provides a safe ERC20.decimals version which returns '18' as fallback value.
/// @param token The address of the ERC-20 token contract.
/// @return (uint8) Token decimals.
function safeDecimals(IBoringERC20 token) internal view returns (uint8) {
(bool success, bytes memory data) = address(token).staticcall(
abi.encodeWithSelector(SIG_DECIMALS)
);
return success && data.length == 32 ? abi.decode(data, (uint8)) : 18;
}
/// @notice Provides a safe ERC20.transfer version for different ERC-20 implementations.
/// Reverts on a failed transfer.
/// @param token The address of the ERC-20 token.
/// @param to Transfer tokens to.
/// @param amount The token amount.
function safeTransfer(
IBoringERC20 token,
address to,
uint256 amount
) internal {
(bool success, bytes memory data) = address(token).call(
abi.encodeWithSelector(SIG_TRANSFER, to, amount)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"BoringERC20: Transfer failed"
);
}
/// @notice Provides a safe ERC20.transferFrom version for different ERC-20 implementations.
/// Reverts on a failed transfer.
/// @param token The address of the ERC-20 token.
/// @param from Transfer tokens from.
/// @param to Transfer tokens to.
/// @param amount The token amount.
function safeTransferFrom(
IBoringERC20 token,
address from,
address to,
uint256 amount
) internal {
(bool success, bytes memory data) = address(token).call(
abi.encodeWithSelector(SIG_TRANSFER_FROM, from, to, amount)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"BoringERC20: TransferFrom failed"
);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @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 Context {
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.7;
interface IBoringERC20 {
function mint(address to, uint256 amount) external;
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
/// @notice EIP 2612
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IBoringERC20","name":"_rewardToken","type":"address"},{"internalType":"contract IStellaDistributorV2","name":"_distributorV2","type":"address"},{"internalType":"bool","name":"_isNative","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"AddPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"phase","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardPerSec","type":"uint256"}],"name":"AddRewardInfo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"OnReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newRate","type":"uint256"}],"name":"RewardRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"SetPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accTokenPerShare","type":"uint256"}],"name":"UpdatePool","type":"event"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"},{"internalType":"uint256","name":"_endTimestamp","type":"uint256"}],"name":"_getTimeElapsed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"_updatePool","outputs":[{"components":[{"internalType":"uint256","name":"accTokenPerShare","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"totalRewards","type":"uint256"}],"internalType":"struct ComplexRewarderPerSecV2.PoolInfo","name":"pool","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint256","name":"_startTimestamp","type":"uint256"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_endTimestamp","type":"uint256"},{"internalType":"uint256","name":"_rewardPerSec","type":"uint256"}],"name":"addRewardInfo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"currentEndTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributorV2","outputs":[{"internalType":"contract IStellaDistributorV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_beneficiary","type":"address"}],"name":"emergencyRewardWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"inCaseTokensGetStuck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isNative","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"onStellaReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"uint256","name":"accTokenPerShare","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"totalRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolRewardInfo","outputs":[{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"endTimestamp","type":"uint256"},{"internalType":"uint256","name":"rewardPerSec","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"poolRewardsPerSec","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardInfoLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IBoringERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stuckTimeLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[{"components":[{"internalType":"uint256","name":"accTokenPerShare","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"totalRewards","type":"uint256"}],"internalType":"struct ComplexRewarderPerSecV2.PoolInfo","name":"pool","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6101206040526000600655603460e09081525060006007553480156200002457600080fd5b506040516200457e3803806200457e83398181016040528101906200004a9190620004a9565b6200006a6200005e6200025560201b60201c565b6200025d60201b60201c565b6001808190555062000087836200032160201b62001e8a1760201c565b620000c9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000c0906200061e565b60405180910390fd5b620000df826200032160201b62001e8a1760201c565b62000121576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001189062000640565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508173ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505080151560c081151560f81b81525050600081620001d857620001d28473ffffffffffffffffffffffffffffffffffffffff166200033460201b62001e9d1760201c565b620001db565b60125b60ff169050601e811062000226576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200021d90620005fc565b60405180910390fd5b80601e62000235919062000821565b600a620002439190620006e4565b61010081815250505050505062000aa7565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080823b905060008111915050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1663313ce56760e01b604051602401604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051620003ca9190620005e3565b600060405180830381855afa9150503d806000811462000407576040519150601f19603f3d011682016040523d82523d6000602084013e6200040c565b606091505b509150915081801562000420575060208151145b6200042d57601262000444565b8080602001905181019062000443919062000505565b5b92505050919050565b6000815190506200045e8162000a3f565b92915050565b600081519050620004758162000a59565b92915050565b6000815190506200048c8162000a73565b92915050565b600081519050620004a38162000a8d565b92915050565b600080600060608486031215620004c557620004c462000940565b5b6000620004d58682870162000464565b9350506020620004e8868287016200047b565b9250506040620004fb868287016200044d565b9150509250925092565b6000602082840312156200051e576200051d62000940565b5b60006200052e8482850162000492565b91505092915050565b6000620005448262000662565b6200055081856200066d565b935062000562818560208601620008db565b80840191505092915050565b60006200057d60398362000678565b91506200058a8262000952565b604082019050919050565b6000620005a460328362000678565b9150620005b182620009a1565b604082019050919050565b6000620005cb60398362000678565b9150620005d882620009f0565b604082019050919050565b6000620005f1828462000537565b915081905092915050565b6000602082019050818103600083015262000617816200056e565b9050919050565b60006020820190508181036000830152620006398162000595565b9050919050565b600060208201905081810360008301526200065b81620005bc565b9050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b6000808291508390505b6001851115620006db57808604811115620006b357620006b262000911565b5b6001851615620006c35780820291505b8081029050620006d38562000945565b945062000693565b94509492505050565b6000620006f182620008c4565b9150620006fe83620008c4565b92506200072d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462000735565b905092915050565b6000826200074757600190506200081a565b816200075757600090506200081a565b81600181146200077057600281146200077b57620007b1565b60019150506200081a565b60ff84111562000790576200078f62000911565b5b8360020a915084821115620007aa57620007a962000911565b5b506200081a565b5060208310610133831016604e8410600b8410161715620007eb5782820a905083811115620007e557620007e462000911565b5b6200081a565b620007fa848484600162000689565b9250905081840481111562000814576200081362000911565b5b81810290505b9392505050565b60006200082e82620008c4565b91506200083b83620008c4565b92508282101562000851576200085062000911565b5b828203905092915050565b60006200086982620008a4565b9050919050565b60008115159050919050565b600062000889826200085c565b9050919050565b60006200089d826200085c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b83811015620008fb578082015181840152602081019050620008de565b838111156200090b576000848401525b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b60008160011c9050919050565b7f636f6e7374727563746f723a2072657761726420746f6b656e20646563696d6160008201527f6c73206d75737420626520696e666572696f7220746f20333000000000000000602082015250565b7f636f6e7374727563746f723a2072657761726420746f6b656e206d757374206260008201527f6520612076616c696420636f6e74726163740000000000000000000000000000602082015250565b7f636f6e7374727563746f723a205374656c6c614469737472696275746f72563260008201527f206d75737420626520612076616c696420636f6e747261637400000000000000602082015250565b62000a4a8162000870565b811462000a5657600080fd5b50565b62000a64816200087c565b811462000a7057600080fd5b50565b62000a7e8162000890565b811462000a8a57600080fd5b50565b62000a9881620008ce565b811462000aa457600080fd5b50565b60805160601c60a05160601c60c05160f81c60e05161010051613a0b62000b73600039600081816115730152818161180a01528181611bb701528181612223015261227e0152600081816106190152610aa70152600081816108cb01528181610c87015281816111b40152818161148701526115c70152600081816107a3015281816111d801528181611347015281816119a701526120a20152600081816108f501528181610cb2015281816114b501528181611767015281816117b70152611da70152613a0b6000f3fe6080604052600436106101655760003560e01c806372333631116100d1578063c6d758cb1161008a578063f2fde38b11610064578063f2fde38b1461055b578063f7c618c114610584578063f98b03ca146105af578063ffcd4263146105da57610165565b8063c6d758cb146104cc578063cea2ba8b146104f5578063d4aa89b51461051e57610165565b8063723336311461039357806373cfc6b2146103d05780637d0d9d5f146103fb5780638da5cb5b1461042657806393f1a40b146104515780639e494bee1461048f57610165565b8063465e81ec11610123578063465e81ec14610285578063505fb46c146102c257806351eb05a6146102eb578063630b5ba11461032857806369883b4e1461033f578063715018a61461037c57610165565b8062d748501461016a5780630832cfbf146101955780631526fe27146101d457806317caf6f1146102155780631d123131146102405780632ea807c514610269575b600080fd5b34801561017657600080fd5b5061017f610617565b60405161018c919061322d565b60405180910390f35b3480156101a157600080fd5b506101bc60048036038101906101b79190612b47565b61063b565b6040516101cb93929190613271565b60405180910390f35b3480156101e057600080fd5b506101fb60048036038101906101f69190612a5a565b610682565b60405161020c9594939291906132a8565b60405180910390f35b34801561022157600080fd5b5061022a6106b8565b604051610237919061322d565b60405180910390f35b34801561024c57600080fd5b5061026760048036038101906102629190612b87565b6106be565b005b610283600480360381019061027e9190612bda565b6109fb565b005b34801561029157600080fd5b506102ac60048036038101906102a79190612a5a565b610e14565b6040516102b9919061322d565b60405180910390f35b3480156102ce57600080fd5b506102e960048036038101906102e49190612bda565b610e27565b005b3480156102f757600080fd5b50610312600480360381019061030d9190612a5a565b610fec565b60405161031f9190613212565b60405180910390f35b34801561033457600080fd5b5061033d611059565b005b34801561034b57600080fd5b5061036660048036038101906103619190612a5a565b6110b8565b604051610373919061322d565b60405180910390f35b34801561038857600080fd5b506103916110dc565b005b34801561039f57600080fd5b506103ba60048036038101906103b59190612bda565b611164565b6040516103c7919061322d565b60405180910390f35b3480156103dc57600080fd5b506103e56111b2565b6040516103f29190613001565b60405180910390f35b34801561040757600080fd5b506104106111d6565b60405161041d9190613037565b60405180910390f35b34801561043257600080fd5b5061043b6111fa565b6040516104489190612f86565b60405180910390f35b34801561045d57600080fd5b5061047860048036038101906104739190612ab4565b611223565b604051610486929190613248565b60405180910390f35b34801561049b57600080fd5b506104b660048036038101906104b19190612a5a565b611254565b6040516104c3919061322d565b60405180910390f35b3480156104d857600080fd5b506104f360048036038101906104ee91906129ed565b611267565b005b34801561050157600080fd5b5061051c60048036038101906105179190612af4565b611345565b005b34801561052a57600080fd5b5061054560048036038101906105409190612a5a565b6118ad565b6040516105529190613212565b60405180910390f35b34801561056757600080fd5b50610582600480360381019061057d91906129c0565b611cad565b005b34801561059057600080fd5b50610599611da5565b6040516105a6919061301c565b60405180910390f35b3480156105bb57600080fd5b506105c4611dc9565b6040516105d1919061322d565b60405180910390f35b3480156105e657600080fd5b5061060160048036038101906105fc9190612ab4565b611dcf565b60405161060e919061322d565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6003602052816000526040600020818154811061065757600080fd5b9060005260206000209060030201600091509150508060000154908060010154908060020154905083565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154905085565b60065481565b6106c6611fad565b73ffffffffffffffffffffffffffffffffffffffff166106e46111fa565b73ffffffffffffffffffffffffffffffffffffffff161461073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073190613112565b60405180910390fd5b60026001541415610780576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610777906131d2565b60405180910390fd5b6002600181905550600060026000858152602001908152602001600020905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663654c9ece866040518263ffffffff1660e01b81526004016107fa919061322d565b60206040518083038186803b15801561081257600080fd5b505afa158015610826573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084a9190612a87565b9050600061085a86836000611fb5565b90508260040154858261086d9190613322565b11156108ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a5906130f2565b60405180910390fd5b848360040160008282546108c29190613403565b925050819055507f000000000000000000000000000000000000000000000000000000000000000061093e5761093984867f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166122ca9092919063ffffffff16565b6109ec565b60008473ffffffffffffffffffffffffffffffffffffffff168660405161096490612f71565b60006040518083038185875af1925050503d80600081146109a1576040519150601f19603f3d011682016040523d82523d6000602084013e6109a6565b606091505b50509050806109ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e1906130d2565b60405180910390fd5b505b50505060018081905550505050565b610a03611fad565b73ffffffffffffffffffffffffffffffffffffffff16610a216111fa565b73ffffffffffffffffffffffffffffffffffffffff1614610a77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6e90613112565b60405180910390fd5b600060036000858152602001908152602001600020905060006002600086815260200190815260200160002090507f0000000000000000000000000000000000000000000000000000000000000000828054905010610b0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0290613192565b60405180910390fd5b600082805490501480610b525750428260018480549050610b2c9190613403565b81548110610b3d57610b3c6135ae565b5b90600052602060002090600302016001015410155b610b91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8890613132565b60405180910390fd5b600082805490501480610bd75750838260018480549050610bb29190613403565b81548110610bc357610bc26135ae565b5b906000526020600020906003020160010154105b610c16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0d90613172565b60405180910390fd5b600080838054905014610c5d578260018480549050610c359190613403565b81548110610c4657610c456135ae565b5b906000526020600020906003020160010154610c63565b81600101545b905060008186610c739190613403565b905060008582610c8391906133a9565b90507f0000000000000000000000000000000000000000000000000000000000000000610cfc57610cf73330837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661241f909392919063ffffffff16565b610d3f565b803414610d3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d35906131f2565b60405180910390fd5b5b80846004016000828254610d539190613322565b92505081905550846040518060600160405280858152602001898152602001888152509080600181540180825580915050600190039060005260206000209060030201600090919091909150600082015181600001556020820151816001015560408201518160020155505060018580549050610dd09190613403565b887fad90731bd0d97445f5af66088f3adebf343c520c20e033cc42f93b124258cdc28989604051610e02929190613248565b60405180910390a35050505050505050565b6000610e208242612577565b9050919050565b610e2f611fad565b73ffffffffffffffffffffffffffffffffffffffff16610e4d6111fa565b73ffffffffffffffffffffffffffffffffffffffff1614610ea3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9a90613112565b60405180910390fd5b6000600260008581526020019081526020016000206002015414610efc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef390613152565b60405180910390fd5b8160066000828254610f0e9190613322565b925050819055506040518060a001604052806000815260200182815260200182815260200183815260200160008152506002600085815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050506004839080600181540180825580915050600190039060005260206000200160009091909190915055827fa6b36ea399c1eae2ba98a011138f78722b48f46ad93349269348ccc6e8f1cced83604051610fdf919061322d565b60405180910390a2505050565b610ff4612928565b6002600154141561103a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611031906131d2565b60405180910390fd5b600260018190555061104b826118ad565b905060018081905550919050565b6002600154141561109f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611096906131d2565b60405180910390fd5b60026001819055506110af6126cb565b60018081905550565b600481815481106110c857600080fd5b906000526020600020016000915090505481565b6110e4611fad565b73ffffffffffffffffffffffffffffffffffffffff166111026111fa565b73ffffffffffffffffffffffffffffffffffffffff1614611158576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114f90613112565b60405180910390fd5b611162600061271d565b565b6000818410158061117457508284115b1561118257600090506111ab565b81831161119c5783836111959190613403565b90506111ab565b83826111a89190613403565b90505b9392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6005602052816000526040600020602052806000526040600020600091509150508060000154908060010154905082565b600061126082426127e1565b9050919050565b61126f611fad565b73ffffffffffffffffffffffffffffffffffffffff1661128d6111fa565b73ffffffffffffffffffffffffffffffffffffffff16146112e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112da90613112565b60405180910390fd5b600060075414156113045762015180426112fd9190613322565b6007819055505b42600754116113415761133833828473ffffffffffffffffffffffffffffffffffffffff166122ca9092919063ffffffff16565b60006007819055505b5050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ca906130b2565b60405180910390fd5b60026001541415611419576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611410906131d2565b60405180910390fd5b6002600181905550600061142c846118ad565b905060006005600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000807f0000000000000000000000000000000000000000000000000000000000000000156114b35747905061155f565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161150c9190612f86565b60206040518083038186803b15801561152457600080fd5b505afa158015611538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155c9190612a87565b90505b6000836000015411156117ff5782600101547f0000000000000000000000000000000000000000000000000000000000000000856000015185600001546115a691906133a9565b6115b09190613378565b6115ba9190613403565b915060008211156117fe577f00000000000000000000000000000000000000000000000000000000000000001561175857808211156116a55760008673ffffffffffffffffffffffffffffffffffffffff168260405161161990612f71565b60006040518083038185875af1925050503d8060008114611656576040519150601f19603f3d011682016040523d82523d6000602084013e61165b565b606091505b505090508061169f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169690613092565b60405180910390fd5b50611753565b60008673ffffffffffffffffffffffffffffffffffffffff16836040516116cb90612f71565b60006040518083038185875af1925050503d8060008114611708576040519150601f19603f3d011682016040523d82523d6000602084013e61170d565b606091505b5050905080611751576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174890613092565b60405180910390fd5b505b6117fd565b808211156117b0576117ab86827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166122ca9092919063ffffffff16565b6117fc565b6117fb86837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166122ca9092919063ffffffff16565b5b5b5b5b8483600001819055507f00000000000000000000000000000000000000000000000000000000000000008460000151846000015461183d91906133a9565b6118479190613378565b83600101819055508573ffffffffffffffffffffffffffffffffffffffff167fd1072bb52c3131d0c96197b73fb8a45637e30f8b6664fc142310cc9b242859b483604051611895919061322d565b60405180910390a25050505060018081905550505050565b6118b5612928565b600260008381526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509050600060036000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561198c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250508152602001906001019061193c565b505050509050816040015142116119a35750611ca8565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663654c9ece856040518263ffffffff1660e01b81526004016119fe919061322d565b60206040518083038186803b158015611a1657600080fd5b505afa158015611a2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4e9190612a87565b90506000811415611ac057611a6384426127e1565b421115611ab95742836040018181525050837f3be3541fc42237d611b30329040bfa4569541d156560acdbbae57640d20b8f468460400151838660000151604051611ab093929190613271565b60405180910390a25b5050611ca8565b60005b8251811015611c17576000611afb856040015142868581518110611aea57611ae96135ae565b5b602002602001015160200151611164565b90506000811415611b0c5750611c06565b838281518110611b1f57611b1e6135ae565b5b602002602001015160200151421115611b5f57838281518110611b4557611b446135ae565b5b602002602001015160200151856040018181525050611b6a565b428560400181815250505b60006006548660600151868581518110611b8757611b866135ae565b5b60200260200101516040015184611b9e91906133a9565b611ba891906133a9565b611bb29190613378565b9050837f000000000000000000000000000000000000000000000000000000000000000082611be191906133a9565b611beb9190613378565b86600001818151611bfc9190613322565b9150818152505050505b80611c1090613507565b9050611ac3565b5082600260008681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040155905050837f3be3541fc42237d611b30329040bfa4569541d156560acdbbae57640d20b8f468460400151838660000151604051611c9d93929190613271565b60405180910390a250505b919050565b611cb5611fad565b73ffffffffffffffffffffffffffffffffffffffff16611cd36111fa565b73ffffffffffffffffffffffffffffffffffffffff1614611d29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2090613112565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611d99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9090613072565b60405180910390fd5b611da28161271d565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b60075481565b6000611e82836005600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001546005600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154611fb5565b905092915050565b600080823b905060008111915050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1663313ce56760e01b604051602401604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611f319190612f5a565b600060405180830381855afa9150503d8060008114611f6c576040519150601f19603f3d011682016040523d82523d6000602084013e611f71565b606091505b5091509150818015611f84575060208151145b611f8f576012611fa4565b80806020019051810190611fa39190612c2d565b5b92505050919050565b600033905090565b600080600260008681526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509050600060036000878152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561208f578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250508152602001906001019061203f565b50505050905060008260000151905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663654c9ece896040518263ffffffff1660e01b81526004016120f9919061322d565b60206040518083038186803b15801561211157600080fd5b505afa158015612125573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121499190612a87565b905083604001514211801561215f575060008114155b1561227b5760008460400151905060005b84518110156122785760006121a48342888581518110612193576121926135ae565b5b602002602001015160200151611164565b905060008114156121b55750612267565b8582815181106121c8576121c76135ae565b5b6020026020010151602001519250600060065488606001518885815181106121f3576121f26135ae565b5b6020026020010151604001518461220a91906133a9565b61221491906133a9565b61221e9190613378565b9050847f00000000000000000000000000000000000000000000000000000000000000008261224d91906133a9565b6122579190613378565b866122629190613322565b955050505b8061227190613507565b9050612170565b50505b857f000000000000000000000000000000000000000000000000000000000000000083896122a991906133a9565b6122b39190613378565b6122bd9190613403565b9450505050509392505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b85856040516024016122ff929190612fd8565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516123699190612f5a565b6000604051808303816000865af19150503d80600081146123a6576040519150601f19603f3d011682016040523d82523d6000602084013e6123ab565b606091505b50915091508180156123d957506000815114806123d85750808060200190518101906123d79190612a2d565b5b5b612418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240f90613052565b60405180910390fd5b5050505050565b6000808573ffffffffffffffffffffffffffffffffffffffff166323b872dd60e01b86868660405160240161245693929190612fa1565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516124c09190612f5a565b6000604051808303816000865af19150503d80600081146124fd576040519150601f19603f3d011682016040523d82523d6000602084013e612502565b606091505b5091509150818015612530575060008151148061252f57508080602001905181019061252e9190612a2d565b5b5b61256f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612566906131b2565b60405180910390fd5b505050505050565b60008060036000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156125fd57838290600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050815260200190600101906125ad565b5050505090506000600260008681526020019081526020016000209050600082519050600081141561263557600093505050506126c5565b60005b818110156126bc57838181518110612653576126526135ae565b5b60200260200101516020015186116126ab5760065483600301548583815181106126805761267f6135ae565b5b60200260200101516040015161269691906133a9565b6126a09190613378565b9450505050506126c5565b806126b590613507565b9050612638565b50600093505050505b92915050565b6000600480549050905060005b8181101561271957612707600482815481106126f7576126f66135ae565b5b90600052602060002001546118ad565b508061271290613507565b90506126d8565b5050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008060036000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156128675783829060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505081526020019060010190612817565b505050509050600081519050600081141561288757600092505050612922565b60005b818110156128f1578281815181106128a5576128a46135ae565b5b60200260200101516020015185116128e0578281815181106128ca576128c96135ae565b5b6020026020010151602001519350505050612922565b806128ea90613507565b905061288a565b50816001826129009190613403565b81518110612911576129106135ae565b5b602002602001015160200151925050505b92915050565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60008135905061296681613979565b92915050565b60008151905061297b81613990565b92915050565b600081359050612990816139a7565b92915050565b6000815190506129a5816139a7565b92915050565b6000815190506129ba816139be565b92915050565b6000602082840312156129d6576129d56135dd565b5b60006129e484828501612957565b91505092915050565b60008060408385031215612a0457612a036135dd565b5b6000612a1285828601612957565b9250506020612a2385828601612981565b9150509250929050565b600060208284031215612a4357612a426135dd565b5b6000612a518482850161296c565b91505092915050565b600060208284031215612a7057612a6f6135dd565b5b6000612a7e84828501612981565b91505092915050565b600060208284031215612a9d57612a9c6135dd565b5b6000612aab84828501612996565b91505092915050565b60008060408385031215612acb57612aca6135dd565b5b6000612ad985828601612981565b9250506020612aea85828601612957565b9150509250929050565b600080600060608486031215612b0d57612b0c6135dd565b5b6000612b1b86828701612981565b9350506020612b2c86828701612957565b9250506040612b3d86828701612981565b9150509250925092565b60008060408385031215612b5e57612b5d6135dd565b5b6000612b6c85828601612981565b9250506020612b7d85828601612981565b9150509250929050565b600080600060608486031215612ba057612b9f6135dd565b5b6000612bae86828701612981565b9350506020612bbf86828701612981565b9250506040612bd086828701612957565b9150509250925092565b600080600060608486031215612bf357612bf26135dd565b5b6000612c0186828701612981565b9350506020612c1286828701612981565b9250506040612c2386828701612981565b9150509250925092565b600060208284031215612c4357612c426135dd565b5b6000612c51848285016129ab565b91505092915050565b612c6381613437565b82525050565b612c7281613449565b82525050565b6000612c83826132fb565b612c8d8185613306565b9350612c9d8185602086016134d4565b80840191505092915050565b612cb28161348c565b82525050565b612cc18161349e565b82525050565b6000612cd4601c83613311565b9150612cdf826135e2565b602082019050919050565b6000612cf7602683613311565b9150612d028261360b565b604082019050919050565b6000612d1a600f83613311565b9150612d258261365a565b602082019050919050565b6000612d3d604283613311565b9150612d4882613683565b606082019050919050565b6000612d60602983613311565b9150612d6b826136f8565b604082019050919050565b6000612d83603283613311565b9150612d8e82613747565b604082019050919050565b6000612da6602083613311565b9150612db182613796565b602082019050919050565b6000612dc9602483613311565b9150612dd4826137bf565b604082019050919050565b6000612dec601383613311565b9150612df78261380e565b602082019050919050565b6000612e0f602583613311565b9150612e1a82613837565b604082019050919050565b6000612e32600083613306565b9150612e3d82613886565b600082019050919050565b6000612e55603583613311565b9150612e6082613889565b604082019050919050565b6000612e78602083613311565b9150612e83826138d8565b602082019050919050565b6000612e9b601f83613311565b9150612ea682613901565b602082019050919050565b6000612ebe602d83613311565b9150612ec98261392a565b604082019050919050565b60a082016000820151612eea6000850182612f3c565b506020820151612efd6020850182612f3c565b506040820151612f106040850182612f3c565b506060820151612f236060850182612f3c565b506080820151612f366080850182612f3c565b50505050565b612f4581613475565b82525050565b612f5481613475565b82525050565b6000612f668284612c78565b915081905092915050565b6000612f7c82612e25565b9150819050919050565b6000602082019050612f9b6000830184612c5a565b92915050565b6000606082019050612fb66000830186612c5a565b612fc36020830185612c5a565b612fd06040830184612f4b565b949350505050565b6000604082019050612fed6000830185612c5a565b612ffa6020830184612f4b565b9392505050565b60006020820190506130166000830184612c69565b92915050565b60006020820190506130316000830184612ca9565b92915050565b600060208201905061304c6000830184612cb8565b92915050565b6000602082019050818103600083015261306b81612cc7565b9050919050565b6000602082019050818103600083015261308b81612cea565b9050919050565b600060208201905081810360008301526130ab81612d0d565b9050919050565b600060208201905081810360008301526130cb81612d30565b9050919050565b600060208201905081810360008301526130eb81612d53565b9050919050565b6000602082019050818103600083015261310b81612d76565b9050919050565b6000602082019050818103600083015261312b81612d99565b9050919050565b6000602082019050818103600083015261314b81612dbc565b9050919050565b6000602082019050818103600083015261316b81612ddf565b9050919050565b6000602082019050818103600083015261318b81612e02565b9050919050565b600060208201905081810360008301526131ab81612e48565b9050919050565b600060208201905081810360008301526131cb81612e6b565b9050919050565b600060208201905081810360008301526131eb81612e8e565b9050919050565b6000602082019050818103600083015261320b81612eb1565b9050919050565b600060a0820190506132276000830184612ed4565b92915050565b60006020820190506132426000830184612f4b565b92915050565b600060408201905061325d6000830185612f4b565b61326a6020830184612f4b565b9392505050565b60006060820190506132866000830186612f4b565b6132936020830185612f4b565b6132a06040830184612f4b565b949350505050565b600060a0820190506132bd6000830188612f4b565b6132ca6020830187612f4b565b6132d76040830186612f4b565b6132e46060830185612f4b565b6132f16080830184612f4b565b9695505050505050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600061332d82613475565b915061333883613475565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561336d5761336c613550565b5b828201905092915050565b600061338382613475565b915061338e83613475565b92508261339e5761339d61357f565b5b828204905092915050565b60006133b482613475565b91506133bf83613475565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156133f8576133f7613550565b5b828202905092915050565b600061340e82613475565b915061341983613475565b92508282101561342c5761342b613550565b5b828203905092915050565b600061344282613455565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000613497826134b0565b9050919050565b60006134a9826134b0565b9050919050565b60006134bb826134c2565b9050919050565b60006134cd82613455565b9050919050565b60005b838110156134f25780820151818401526020810190506134d7565b83811115613501576000848401525b50505050565b600061351282613475565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561354557613544613550565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b7f426f72696e6745524332303a205472616e73666572206661696c656400000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f5472616e73666572206661696c65640000000000000000000000000000000000600082015250565b7f6f6e6c794469737472696275746f7256323a206f6e6c79205374656c6c61446960008201527f737472696275746f7256322063616e2063616c6c20746869732066756e63746960208201527f6f6e000000000000000000000000000000000000000000000000000000000000604082015250565b7f656d657267656e6379207265776172642077697468647261773a206661696c6560008201527f6420746f2073656e640000000000000000000000000000000000000000000000602082015250565b7f656d657267656e6379207265776172642077697468647261773a206e6f74206560008201527f6e6f7567682072657761726420746f6b656e0000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f6164642072657761726420696e666f3a2072657761726420706572696f64206560008201527f6e64656400000000000000000000000000000000000000000000000000000000602082015250565b7f706f6f6c20616c72656164792065786973747300000000000000000000000000600082015250565b7f6164642072657761726420696e666f3a20626164206e657720656e6454696d6560008201527f7374616d70000000000000000000000000000000000000000000000000000000602082015250565b50565b7f6164642072657761726420696e666f3a2072657761726420696e666f206c656e60008201527f677468206578636565647320746865206c696d69740000000000000000000000602082015250565b7f426f72696e6745524332303a205472616e7366657246726f6d206661696c6564600082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b7f6164642072657761726420696e666f3a206e6f7420656e6f7567682066756e6460008201527f7320746f207472616e7366657200000000000000000000000000000000000000602082015250565b61398281613437565b811461398d57600080fd5b50565b61399981613449565b81146139a457600080fd5b50565b6139b081613475565b81146139bb57600080fd5b50565b6139c78161347f565b81146139d257600080fd5b5056fea2646970667358221220d7374f05811b70b7cfdea4821755c439d375e8778e60c91911789c2bb3062d1964736f6c634300080700330000000000000000000000008ece0d14d619fe26e2c14c4a92c2f9e8634a039e000000000000000000000000f3a5454496e26ac57da879bf3285fa85debf03880000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101655760003560e01c806372333631116100d1578063c6d758cb1161008a578063f2fde38b11610064578063f2fde38b1461055b578063f7c618c114610584578063f98b03ca146105af578063ffcd4263146105da57610165565b8063c6d758cb146104cc578063cea2ba8b146104f5578063d4aa89b51461051e57610165565b8063723336311461039357806373cfc6b2146103d05780637d0d9d5f146103fb5780638da5cb5b1461042657806393f1a40b146104515780639e494bee1461048f57610165565b8063465e81ec11610123578063465e81ec14610285578063505fb46c146102c257806351eb05a6146102eb578063630b5ba11461032857806369883b4e1461033f578063715018a61461037c57610165565b8062d748501461016a5780630832cfbf146101955780631526fe27146101d457806317caf6f1146102155780631d123131146102405780632ea807c514610269575b600080fd5b34801561017657600080fd5b5061017f610617565b60405161018c919061322d565b60405180910390f35b3480156101a157600080fd5b506101bc60048036038101906101b79190612b47565b61063b565b6040516101cb93929190613271565b60405180910390f35b3480156101e057600080fd5b506101fb60048036038101906101f69190612a5a565b610682565b60405161020c9594939291906132a8565b60405180910390f35b34801561022157600080fd5b5061022a6106b8565b604051610237919061322d565b60405180910390f35b34801561024c57600080fd5b5061026760048036038101906102629190612b87565b6106be565b005b610283600480360381019061027e9190612bda565b6109fb565b005b34801561029157600080fd5b506102ac60048036038101906102a79190612a5a565b610e14565b6040516102b9919061322d565b60405180910390f35b3480156102ce57600080fd5b506102e960048036038101906102e49190612bda565b610e27565b005b3480156102f757600080fd5b50610312600480360381019061030d9190612a5a565b610fec565b60405161031f9190613212565b60405180910390f35b34801561033457600080fd5b5061033d611059565b005b34801561034b57600080fd5b5061036660048036038101906103619190612a5a565b6110b8565b604051610373919061322d565b60405180910390f35b34801561038857600080fd5b506103916110dc565b005b34801561039f57600080fd5b506103ba60048036038101906103b59190612bda565b611164565b6040516103c7919061322d565b60405180910390f35b3480156103dc57600080fd5b506103e56111b2565b6040516103f29190613001565b60405180910390f35b34801561040757600080fd5b506104106111d6565b60405161041d9190613037565b60405180910390f35b34801561043257600080fd5b5061043b6111fa565b6040516104489190612f86565b60405180910390f35b34801561045d57600080fd5b5061047860048036038101906104739190612ab4565b611223565b604051610486929190613248565b60405180910390f35b34801561049b57600080fd5b506104b660048036038101906104b19190612a5a565b611254565b6040516104c3919061322d565b60405180910390f35b3480156104d857600080fd5b506104f360048036038101906104ee91906129ed565b611267565b005b34801561050157600080fd5b5061051c60048036038101906105179190612af4565b611345565b005b34801561052a57600080fd5b5061054560048036038101906105409190612a5a565b6118ad565b6040516105529190613212565b60405180910390f35b34801561056757600080fd5b50610582600480360381019061057d91906129c0565b611cad565b005b34801561059057600080fd5b50610599611da5565b6040516105a6919061301c565b60405180910390f35b3480156105bb57600080fd5b506105c4611dc9565b6040516105d1919061322d565b60405180910390f35b3480156105e657600080fd5b5061060160048036038101906105fc9190612ab4565b611dcf565b60405161060e919061322d565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000003481565b6003602052816000526040600020818154811061065757600080fd5b9060005260206000209060030201600091509150508060000154908060010154908060020154905083565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154905085565b60065481565b6106c6611fad565b73ffffffffffffffffffffffffffffffffffffffff166106e46111fa565b73ffffffffffffffffffffffffffffffffffffffff161461073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073190613112565b60405180910390fd5b60026001541415610780576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610777906131d2565b60405180910390fd5b6002600181905550600060026000858152602001908152602001600020905060007f000000000000000000000000f3a5454496e26ac57da879bf3285fa85debf038873ffffffffffffffffffffffffffffffffffffffff1663654c9ece866040518263ffffffff1660e01b81526004016107fa919061322d565b60206040518083038186803b15801561081257600080fd5b505afa158015610826573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084a9190612a87565b9050600061085a86836000611fb5565b90508260040154858261086d9190613322565b11156108ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a5906130f2565b60405180910390fd5b848360040160008282546108c29190613403565b925050819055507f000000000000000000000000000000000000000000000000000000000000000061093e5761093984867f0000000000000000000000008ece0d14d619fe26e2c14c4a92c2f9e8634a039e73ffffffffffffffffffffffffffffffffffffffff166122ca9092919063ffffffff16565b6109ec565b60008473ffffffffffffffffffffffffffffffffffffffff168660405161096490612f71565b60006040518083038185875af1925050503d80600081146109a1576040519150601f19603f3d011682016040523d82523d6000602084013e6109a6565b606091505b50509050806109ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e1906130d2565b60405180910390fd5b505b50505060018081905550505050565b610a03611fad565b73ffffffffffffffffffffffffffffffffffffffff16610a216111fa565b73ffffffffffffffffffffffffffffffffffffffff1614610a77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6e90613112565b60405180910390fd5b600060036000858152602001908152602001600020905060006002600086815260200190815260200160002090507f0000000000000000000000000000000000000000000000000000000000000034828054905010610b0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0290613192565b60405180910390fd5b600082805490501480610b525750428260018480549050610b2c9190613403565b81548110610b3d57610b3c6135ae565b5b90600052602060002090600302016001015410155b610b91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8890613132565b60405180910390fd5b600082805490501480610bd75750838260018480549050610bb29190613403565b81548110610bc357610bc26135ae565b5b906000526020600020906003020160010154105b610c16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0d90613172565b60405180910390fd5b600080838054905014610c5d578260018480549050610c359190613403565b81548110610c4657610c456135ae565b5b906000526020600020906003020160010154610c63565b81600101545b905060008186610c739190613403565b905060008582610c8391906133a9565b90507f0000000000000000000000000000000000000000000000000000000000000000610cfc57610cf73330837f0000000000000000000000008ece0d14d619fe26e2c14c4a92c2f9e8634a039e73ffffffffffffffffffffffffffffffffffffffff1661241f909392919063ffffffff16565b610d3f565b803414610d3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d35906131f2565b60405180910390fd5b5b80846004016000828254610d539190613322565b92505081905550846040518060600160405280858152602001898152602001888152509080600181540180825580915050600190039060005260206000209060030201600090919091909150600082015181600001556020820151816001015560408201518160020155505060018580549050610dd09190613403565b887fad90731bd0d97445f5af66088f3adebf343c520c20e033cc42f93b124258cdc28989604051610e02929190613248565b60405180910390a35050505050505050565b6000610e208242612577565b9050919050565b610e2f611fad565b73ffffffffffffffffffffffffffffffffffffffff16610e4d6111fa565b73ffffffffffffffffffffffffffffffffffffffff1614610ea3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9a90613112565b60405180910390fd5b6000600260008581526020019081526020016000206002015414610efc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef390613152565b60405180910390fd5b8160066000828254610f0e9190613322565b925050819055506040518060a001604052806000815260200182815260200182815260200183815260200160008152506002600085815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050506004839080600181540180825580915050600190039060005260206000200160009091909190915055827fa6b36ea399c1eae2ba98a011138f78722b48f46ad93349269348ccc6e8f1cced83604051610fdf919061322d565b60405180910390a2505050565b610ff4612928565b6002600154141561103a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611031906131d2565b60405180910390fd5b600260018190555061104b826118ad565b905060018081905550919050565b6002600154141561109f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611096906131d2565b60405180910390fd5b60026001819055506110af6126cb565b60018081905550565b600481815481106110c857600080fd5b906000526020600020016000915090505481565b6110e4611fad565b73ffffffffffffffffffffffffffffffffffffffff166111026111fa565b73ffffffffffffffffffffffffffffffffffffffff1614611158576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114f90613112565b60405180910390fd5b611162600061271d565b565b6000818410158061117457508284115b1561118257600090506111ab565b81831161119c5783836111959190613403565b90506111ab565b83826111a89190613403565b90505b9392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000f3a5454496e26ac57da879bf3285fa85debf038881565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6005602052816000526040600020602052806000526040600020600091509150508060000154908060010154905082565b600061126082426127e1565b9050919050565b61126f611fad565b73ffffffffffffffffffffffffffffffffffffffff1661128d6111fa565b73ffffffffffffffffffffffffffffffffffffffff16146112e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112da90613112565b60405180910390fd5b600060075414156113045762015180426112fd9190613322565b6007819055505b42600754116113415761133833828473ffffffffffffffffffffffffffffffffffffffff166122ca9092919063ffffffff16565b60006007819055505b5050565b7f000000000000000000000000f3a5454496e26ac57da879bf3285fa85debf038873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ca906130b2565b60405180910390fd5b60026001541415611419576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611410906131d2565b60405180910390fd5b6002600181905550600061142c846118ad565b905060006005600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000807f0000000000000000000000000000000000000000000000000000000000000000156114b35747905061155f565b7f0000000000000000000000008ece0d14d619fe26e2c14c4a92c2f9e8634a039e73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161150c9190612f86565b60206040518083038186803b15801561152457600080fd5b505afa158015611538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155c9190612a87565b90505b6000836000015411156117ff5782600101547f000000000000000000000000000000000000000000000000000000e8d4a51000856000015185600001546115a691906133a9565b6115b09190613378565b6115ba9190613403565b915060008211156117fe577f00000000000000000000000000000000000000000000000000000000000000001561175857808211156116a55760008673ffffffffffffffffffffffffffffffffffffffff168260405161161990612f71565b60006040518083038185875af1925050503d8060008114611656576040519150601f19603f3d011682016040523d82523d6000602084013e61165b565b606091505b505090508061169f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169690613092565b60405180910390fd5b50611753565b60008673ffffffffffffffffffffffffffffffffffffffff16836040516116cb90612f71565b60006040518083038185875af1925050503d8060008114611708576040519150601f19603f3d011682016040523d82523d6000602084013e61170d565b606091505b5050905080611751576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174890613092565b60405180910390fd5b505b6117fd565b808211156117b0576117ab86827f0000000000000000000000008ece0d14d619fe26e2c14c4a92c2f9e8634a039e73ffffffffffffffffffffffffffffffffffffffff166122ca9092919063ffffffff16565b6117fc565b6117fb86837f0000000000000000000000008ece0d14d619fe26e2c14c4a92c2f9e8634a039e73ffffffffffffffffffffffffffffffffffffffff166122ca9092919063ffffffff16565b5b5b5b5b8483600001819055507f000000000000000000000000000000000000000000000000000000e8d4a510008460000151846000015461183d91906133a9565b6118479190613378565b83600101819055508573ffffffffffffffffffffffffffffffffffffffff167fd1072bb52c3131d0c96197b73fb8a45637e30f8b6664fc142310cc9b242859b483604051611895919061322d565b60405180910390a25050505060018081905550505050565b6118b5612928565b600260008381526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509050600060036000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561198c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250508152602001906001019061193c565b505050509050816040015142116119a35750611ca8565b60007f000000000000000000000000f3a5454496e26ac57da879bf3285fa85debf038873ffffffffffffffffffffffffffffffffffffffff1663654c9ece856040518263ffffffff1660e01b81526004016119fe919061322d565b60206040518083038186803b158015611a1657600080fd5b505afa158015611a2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4e9190612a87565b90506000811415611ac057611a6384426127e1565b421115611ab95742836040018181525050837f3be3541fc42237d611b30329040bfa4569541d156560acdbbae57640d20b8f468460400151838660000151604051611ab093929190613271565b60405180910390a25b5050611ca8565b60005b8251811015611c17576000611afb856040015142868581518110611aea57611ae96135ae565b5b602002602001015160200151611164565b90506000811415611b0c5750611c06565b838281518110611b1f57611b1e6135ae565b5b602002602001015160200151421115611b5f57838281518110611b4557611b446135ae565b5b602002602001015160200151856040018181525050611b6a565b428560400181815250505b60006006548660600151868581518110611b8757611b866135ae565b5b60200260200101516040015184611b9e91906133a9565b611ba891906133a9565b611bb29190613378565b9050837f000000000000000000000000000000000000000000000000000000e8d4a5100082611be191906133a9565b611beb9190613378565b86600001818151611bfc9190613322565b9150818152505050505b80611c1090613507565b9050611ac3565b5082600260008681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040155905050837f3be3541fc42237d611b30329040bfa4569541d156560acdbbae57640d20b8f468460400151838660000151604051611c9d93929190613271565b60405180910390a250505b919050565b611cb5611fad565b73ffffffffffffffffffffffffffffffffffffffff16611cd36111fa565b73ffffffffffffffffffffffffffffffffffffffff1614611d29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2090613112565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611d99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9090613072565b60405180910390fd5b611da28161271d565b50565b7f0000000000000000000000008ece0d14d619fe26e2c14c4a92c2f9e8634a039e81565b60075481565b6000611e82836005600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001546005600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154611fb5565b905092915050565b600080823b905060008111915050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1663313ce56760e01b604051602401604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611f319190612f5a565b600060405180830381855afa9150503d8060008114611f6c576040519150601f19603f3d011682016040523d82523d6000602084013e611f71565b606091505b5091509150818015611f84575060208151145b611f8f576012611fa4565b80806020019051810190611fa39190612c2d565b5b92505050919050565b600033905090565b600080600260008681526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509050600060036000878152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561208f578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250508152602001906001019061203f565b50505050905060008260000151905060007f000000000000000000000000f3a5454496e26ac57da879bf3285fa85debf038873ffffffffffffffffffffffffffffffffffffffff1663654c9ece896040518263ffffffff1660e01b81526004016120f9919061322d565b60206040518083038186803b15801561211157600080fd5b505afa158015612125573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121499190612a87565b905083604001514211801561215f575060008114155b1561227b5760008460400151905060005b84518110156122785760006121a48342888581518110612193576121926135ae565b5b602002602001015160200151611164565b905060008114156121b55750612267565b8582815181106121c8576121c76135ae565b5b6020026020010151602001519250600060065488606001518885815181106121f3576121f26135ae565b5b6020026020010151604001518461220a91906133a9565b61221491906133a9565b61221e9190613378565b9050847f000000000000000000000000000000000000000000000000000000e8d4a510008261224d91906133a9565b6122579190613378565b866122629190613322565b955050505b8061227190613507565b9050612170565b50505b857f000000000000000000000000000000000000000000000000000000e8d4a5100083896122a991906133a9565b6122b39190613378565b6122bd9190613403565b9450505050509392505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b85856040516024016122ff929190612fd8565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516123699190612f5a565b6000604051808303816000865af19150503d80600081146123a6576040519150601f19603f3d011682016040523d82523d6000602084013e6123ab565b606091505b50915091508180156123d957506000815114806123d85750808060200190518101906123d79190612a2d565b5b5b612418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240f90613052565b60405180910390fd5b5050505050565b6000808573ffffffffffffffffffffffffffffffffffffffff166323b872dd60e01b86868660405160240161245693929190612fa1565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516124c09190612f5a565b6000604051808303816000865af19150503d80600081146124fd576040519150601f19603f3d011682016040523d82523d6000602084013e612502565b606091505b5091509150818015612530575060008151148061252f57508080602001905181019061252e9190612a2d565b5b5b61256f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612566906131b2565b60405180910390fd5b505050505050565b60008060036000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156125fd57838290600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050815260200190600101906125ad565b5050505090506000600260008681526020019081526020016000209050600082519050600081141561263557600093505050506126c5565b60005b818110156126bc57838181518110612653576126526135ae565b5b60200260200101516020015186116126ab5760065483600301548583815181106126805761267f6135ae565b5b60200260200101516040015161269691906133a9565b6126a09190613378565b9450505050506126c5565b806126b590613507565b9050612638565b50600093505050505b92915050565b6000600480549050905060005b8181101561271957612707600482815481106126f7576126f66135ae565b5b90600052602060002001546118ad565b508061271290613507565b90506126d8565b5050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008060036000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156128675783829060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505081526020019060010190612817565b505050509050600081519050600081141561288757600092505050612922565b60005b818110156128f1578281815181106128a5576128a46135ae565b5b60200260200101516020015185116128e0578281815181106128ca576128c96135ae565b5b6020026020010151602001519350505050612922565b806128ea90613507565b905061288a565b50816001826129009190613403565b81518110612911576129106135ae565b5b602002602001015160200151925050505b92915050565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60008135905061296681613979565b92915050565b60008151905061297b81613990565b92915050565b600081359050612990816139a7565b92915050565b6000815190506129a5816139a7565b92915050565b6000815190506129ba816139be565b92915050565b6000602082840312156129d6576129d56135dd565b5b60006129e484828501612957565b91505092915050565b60008060408385031215612a0457612a036135dd565b5b6000612a1285828601612957565b9250506020612a2385828601612981565b9150509250929050565b600060208284031215612a4357612a426135dd565b5b6000612a518482850161296c565b91505092915050565b600060208284031215612a7057612a6f6135dd565b5b6000612a7e84828501612981565b91505092915050565b600060208284031215612a9d57612a9c6135dd565b5b6000612aab84828501612996565b91505092915050565b60008060408385031215612acb57612aca6135dd565b5b6000612ad985828601612981565b9250506020612aea85828601612957565b9150509250929050565b600080600060608486031215612b0d57612b0c6135dd565b5b6000612b1b86828701612981565b9350506020612b2c86828701612957565b9250506040612b3d86828701612981565b9150509250925092565b60008060408385031215612b5e57612b5d6135dd565b5b6000612b6c85828601612981565b9250506020612b7d85828601612981565b9150509250929050565b600080600060608486031215612ba057612b9f6135dd565b5b6000612bae86828701612981565b9350506020612bbf86828701612981565b9250506040612bd086828701612957565b9150509250925092565b600080600060608486031215612bf357612bf26135dd565b5b6000612c0186828701612981565b9350506020612c1286828701612981565b9250506040612c2386828701612981565b9150509250925092565b600060208284031215612c4357612c426135dd565b5b6000612c51848285016129ab565b91505092915050565b612c6381613437565b82525050565b612c7281613449565b82525050565b6000612c83826132fb565b612c8d8185613306565b9350612c9d8185602086016134d4565b80840191505092915050565b612cb28161348c565b82525050565b612cc18161349e565b82525050565b6000612cd4601c83613311565b9150612cdf826135e2565b602082019050919050565b6000612cf7602683613311565b9150612d028261360b565b604082019050919050565b6000612d1a600f83613311565b9150612d258261365a565b602082019050919050565b6000612d3d604283613311565b9150612d4882613683565b606082019050919050565b6000612d60602983613311565b9150612d6b826136f8565b604082019050919050565b6000612d83603283613311565b9150612d8e82613747565b604082019050919050565b6000612da6602083613311565b9150612db182613796565b602082019050919050565b6000612dc9602483613311565b9150612dd4826137bf565b604082019050919050565b6000612dec601383613311565b9150612df78261380e565b602082019050919050565b6000612e0f602583613311565b9150612e1a82613837565b604082019050919050565b6000612e32600083613306565b9150612e3d82613886565b600082019050919050565b6000612e55603583613311565b9150612e6082613889565b604082019050919050565b6000612e78602083613311565b9150612e83826138d8565b602082019050919050565b6000612e9b601f83613311565b9150612ea682613901565b602082019050919050565b6000612ebe602d83613311565b9150612ec98261392a565b604082019050919050565b60a082016000820151612eea6000850182612f3c565b506020820151612efd6020850182612f3c565b506040820151612f106040850182612f3c565b506060820151612f236060850182612f3c565b506080820151612f366080850182612f3c565b50505050565b612f4581613475565b82525050565b612f5481613475565b82525050565b6000612f668284612c78565b915081905092915050565b6000612f7c82612e25565b9150819050919050565b6000602082019050612f9b6000830184612c5a565b92915050565b6000606082019050612fb66000830186612c5a565b612fc36020830185612c5a565b612fd06040830184612f4b565b949350505050565b6000604082019050612fed6000830185612c5a565b612ffa6020830184612f4b565b9392505050565b60006020820190506130166000830184612c69565b92915050565b60006020820190506130316000830184612ca9565b92915050565b600060208201905061304c6000830184612cb8565b92915050565b6000602082019050818103600083015261306b81612cc7565b9050919050565b6000602082019050818103600083015261308b81612cea565b9050919050565b600060208201905081810360008301526130ab81612d0d565b9050919050565b600060208201905081810360008301526130cb81612d30565b9050919050565b600060208201905081810360008301526130eb81612d53565b9050919050565b6000602082019050818103600083015261310b81612d76565b9050919050565b6000602082019050818103600083015261312b81612d99565b9050919050565b6000602082019050818103600083015261314b81612dbc565b9050919050565b6000602082019050818103600083015261316b81612ddf565b9050919050565b6000602082019050818103600083015261318b81612e02565b9050919050565b600060208201905081810360008301526131ab81612e48565b9050919050565b600060208201905081810360008301526131cb81612e6b565b9050919050565b600060208201905081810360008301526131eb81612e8e565b9050919050565b6000602082019050818103600083015261320b81612eb1565b9050919050565b600060a0820190506132276000830184612ed4565b92915050565b60006020820190506132426000830184612f4b565b92915050565b600060408201905061325d6000830185612f4b565b61326a6020830184612f4b565b9392505050565b60006060820190506132866000830186612f4b565b6132936020830185612f4b565b6132a06040830184612f4b565b949350505050565b600060a0820190506132bd6000830188612f4b565b6132ca6020830187612f4b565b6132d76040830186612f4b565b6132e46060830185612f4b565b6132f16080830184612f4b565b9695505050505050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600061332d82613475565b915061333883613475565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561336d5761336c613550565b5b828201905092915050565b600061338382613475565b915061338e83613475565b92508261339e5761339d61357f565b5b828204905092915050565b60006133b482613475565b91506133bf83613475565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156133f8576133f7613550565b5b828202905092915050565b600061340e82613475565b915061341983613475565b92508282101561342c5761342b613550565b5b828203905092915050565b600061344282613455565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000613497826134b0565b9050919050565b60006134a9826134b0565b9050919050565b60006134bb826134c2565b9050919050565b60006134cd82613455565b9050919050565b60005b838110156134f25780820151818401526020810190506134d7565b83811115613501576000848401525b50505050565b600061351282613475565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561354557613544613550565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b7f426f72696e6745524332303a205472616e73666572206661696c656400000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f5472616e73666572206661696c65640000000000000000000000000000000000600082015250565b7f6f6e6c794469737472696275746f7256323a206f6e6c79205374656c6c61446960008201527f737472696275746f7256322063616e2063616c6c20746869732066756e63746960208201527f6f6e000000000000000000000000000000000000000000000000000000000000604082015250565b7f656d657267656e6379207265776172642077697468647261773a206661696c6560008201527f6420746f2073656e640000000000000000000000000000000000000000000000602082015250565b7f656d657267656e6379207265776172642077697468647261773a206e6f74206560008201527f6e6f7567682072657761726420746f6b656e0000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f6164642072657761726420696e666f3a2072657761726420706572696f64206560008201527f6e64656400000000000000000000000000000000000000000000000000000000602082015250565b7f706f6f6c20616c72656164792065786973747300000000000000000000000000600082015250565b7f6164642072657761726420696e666f3a20626164206e657720656e6454696d6560008201527f7374616d70000000000000000000000000000000000000000000000000000000602082015250565b50565b7f6164642072657761726420696e666f3a2072657761726420696e666f206c656e60008201527f677468206578636565647320746865206c696d69740000000000000000000000602082015250565b7f426f72696e6745524332303a205472616e7366657246726f6d206661696c6564600082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b7f6164642072657761726420696e666f3a206e6f7420656e6f7567682066756e6460008201527f7320746f207472616e7366657200000000000000000000000000000000000000602082015250565b61398281613437565b811461398d57600080fd5b50565b61399981613449565b81146139a457600080fd5b50565b6139b081613475565b81146139bb57600080fd5b50565b6139c78161347f565b81146139d257600080fd5b5056fea2646970667358221220d7374f05811b70b7cfdea4821755c439d375e8778e60c91911789c2bb3062d1964736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000008ece0d14d619fe26e2c14c4a92c2f9e8634a039e000000000000000000000000f3a5454496e26ac57da879bf3285fa85debf03880000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _rewardToken (address): 0x8ECE0D14d619fE26e2C14C4a92c2F9E8634A039E
Arg [1] : _distributorV2 (address): 0xF3a5454496E26ac57da879bf3285Fa85DEBF0388
Arg [2] : _isNative (bool): False
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000008ece0d14d619fe26e2c14c4a92c2f9e8634a039e
Arg [1] : 000000000000000000000000f3a5454496e26ac57da879bf3285fa85debf0388
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
OVERVIEW
Rewarder contract for Dual Farms having BCMC token.Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.