Source Code
Latest 25 from a total of 145 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Claim | 12798226 | 1709 days ago | IN | 0 ETH | 0.00071767 | ||||
| Claim Deposits | 12787254 | 1711 days ago | IN | 0 ETH | 0.00248165 | ||||
| Claim | 12783697 | 1711 days ago | IN | 0 ETH | 0.00218136 | ||||
| Unstake | 12769705 | 1714 days ago | IN | 0 ETH | 0.00420364 | ||||
| Claim | 12769703 | 1714 days ago | IN | 0 ETH | 0.00127505 | ||||
| Stake | 12760934 | 1715 days ago | IN | 0 ETH | 0.00419461 | ||||
| Stake | 12734409 | 1719 days ago | IN | 0 ETH | 0.00530625 | ||||
| Claim | 12685568 | 1727 days ago | IN | 0 ETH | 0.00203938 | ||||
| Unstake | 12685524 | 1727 days ago | IN | 0 ETH | 0.01021414 | ||||
| Stake | 12678879 | 1728 days ago | IN | 0 ETH | 0.00306 | ||||
| Stake | 12674759 | 1728 days ago | IN | 0 ETH | 0.00323418 | ||||
| Claim Deposits | 12669723 | 1729 days ago | IN | 0 ETH | 0.00051506 | ||||
| Unstake | 12650026 | 1732 days ago | IN | 0 ETH | 0.00299535 | ||||
| Claim Deposits | 12637697 | 1734 days ago | IN | 0 ETH | 0.00075618 | ||||
| Stake | 12614300 | 1738 days ago | IN | 0 ETH | 0.01095428 | ||||
| Unstake | 12607015 | 1739 days ago | IN | 0 ETH | 0.00334611 | ||||
| Claim | 12606984 | 1739 days ago | IN | 0 ETH | 0.00117697 | ||||
| Stake | 12601778 | 1740 days ago | IN | 0 ETH | 0.00925575 | ||||
| Claim Deposits | 12566323 | 1745 days ago | IN | 0 ETH | 0.00197441 | ||||
| Claim | 12556374 | 1747 days ago | IN | 0 ETH | 0.00240745 | ||||
| Unstake | 12542019 | 1749 days ago | IN | 0 ETH | 0.0058279 | ||||
| Claim | 12541932 | 1749 days ago | IN | 0 ETH | 0.00126992 | ||||
| Unstake | 12540420 | 1749 days ago | IN | 0 ETH | 0.00397059 | ||||
| Stake | 12524934 | 1752 days ago | IN | 0 ETH | 0.0082248 | ||||
| Claim Deposits | 12383137 | 1774 days ago | IN | 0 ETH | 0.00508705 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| - | 11620526 | 1891 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
RewardsType5
Compiler Version
v0.6.2+commit.bacdbe57
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.6.0;
import "./RewardsV2.sol";
import "./ReferralRewardsType5.sol";
contract RewardsType5 is RewardsV2 {
event WithdrawRequested(
address indexed user,
uint256 id,
uint256 amount,
uint256 timelock
);
struct Request {
uint256 timelock; // Wnen the unstake can be executed
uint256 amount; // Amount to be withdrawn
Status status; // Request status
}
enum Status {NONE, PENDING, EXECUTED} // Unstake request status
mapping(address => Request[]) public unstakeRequests; // Requests list per each user
mapping(address => uint256) public requestHead; // The first pending unstake request in the user's requests list
/// @dev Constructor that initializes the most important configurations.
/// @param _token Token to be staked and harvested.
/// @param _rewards Old main farming contract.
/// @param _referralTree Contract with referral's tree.
constructor(
IMintableBurnableERC20 _token,
IRewards _rewards,
IReferralTree _referralTree
) public RewardsV2(_token, 0, 57870370370) {
ReferralRewardsType5 newRreferralRewards =
new ReferralRewardsType5(
_token,
_referralTree,
_rewards,
IRewardsV2(address(this)),
[uint256(5000 * 1e18), 2000 * 1e18, 100 * 1e18],
[[uint256(0), 0, 0], [uint256(0), 0, 0], [uint256(0), 0, 0]],
[
[uint256(6 * 1e16), 2 * 1e16, 1 * 1e16],
[uint256(5 * 1e16), 15 * 1e15, 75 * 1e14],
[uint256(4 * 1e16), 1 * 1e16, 5 * 1e15]
]
);
newRreferralRewards.transferOwnership(_msgSender());
referralRewards = IReferralRewardsV2(address(newRreferralRewards));
}
/// @dev Allows to unstake deposit amount.
/// @param _amount Amount to be unstaked.
function unstake(uint256 _amount) public {
updateStakingReward(msg.sender);
UserInfo storage user = userInfo[msg.sender];
if (_amount == 0) {
_amount = user.amount;
}
user.amount = user.amount.sub(_amount);
user.unfrozen = user.unfrozen.add(_amount);
totalStake = totalStake.sub(_amount);
uint256 id = unstakeRequests[msg.sender].length;
unstakeRequests[msg.sender].push(
Request({
timelock: now + 3 days,
amount: _amount,
status: Status.PENDING
})
);
emit WithdrawRequested(msg.sender, id, _amount, now + 3 days);
referralRewards.handleDepositEnd(msg.sender, _amount);
}
/// @dev Executes unstake requests if timelock passed.
/// @param _user Address of the user.
/// @param _count How many deposits to claim.
function executeUnstakes(address _user, uint256 _count) internal override {
_count = (_count == 0)
? unstakeRequests[_user].length
: Math.min(
unstakeRequests[_user].length,
requestHead[_user].add(_count)
);
for (
uint256 requestId = requestHead[_user];
requestId < _count;
requestId++
) {
Request storage request = unstakeRequests[_user][requestId];
if (request.timelock < now && request.status == Status.PENDING) {
request.status = Status.EXECUTED;
UserInfo storage user = userInfo[_user];
user.unfrozen = user.unfrozen.sub(request.amount);
safeTokenTransfer(_user, request.amount);
emit Withdraw(_user, requestId, request.amount, 0, now);
requestHead[_user] = requestHead[_user].add(1);
}
}
}
/// @dev Returns user's unclaimed reward.
/// @param _includeDeposit Should the finnished deposits be included into calculations.
/// @return _reward User's reward.
function getPendingReward(address _user, bool _includeDeposit)
public
view
override
returns (uint256 _reward)
{
UserInfo storage user = userInfo[_user];
_reward = user.claimable.add(
now.sub(user.lastUpdate).mul(user.amount).mul(rewardPerSec).div(
1e18
)
);
if (_includeDeposit) {
for (
uint256 requestId = requestHead[_user];
requestId < unstakeRequests[_user].length;
requestId++
) {
Request storage request = unstakeRequests[_user][requestId];
if (
request.timelock < now && request.status == Status.PENDING
) {
_reward = _reward.add(request.amount);
}
}
}
}
// /// @dev Returns user's unstake requests length.
// /// @param _user Address of the user.
// /// @return Number of unstake requests.
function getRequestsLength(address _user) public view returns (uint256) {
return unstakeRequests[_user].length;
}
/// @dev Returns unclaimed rewardsV2.
/// @return All unclaimed rewardsV2.
function getTotalPendingRewards() public view returns (uint256) {
return now.sub(lastUpdate).mul(totalStake).mul(rewardPerSec).div(1e18);
}
/// @dev Returns assessed rewardsV2.
/// @return All assessed rewardsV2.
function getTotalRewards() public view returns (uint256) {
return
totalClaimed.add(getTotalPendingRewards()).sub(totalClaimed).div(
1e18
);
}
/// @dev Returns user's ended deposits.
/// @param _user Address of the user.
/// @return _count Number of the deposit's that can be withdrawn.
function getEndedDepositsCount(address _user)
public
view
override
returns (uint256 _count)
{
for (
uint256 requestId = requestHead[_user];
requestId < unstakeRequests[_user].length;
requestId++
) {
Request storage request = unstakeRequests[_user][requestId];
if (request.timelock < now && request.status == Status.PENDING) {
_count = _count.add(1);
}
}
}
}pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "./ReferralRewardsV2.sol";
contract ReferralRewardsType5 is ReferralRewardsV2 {
/// @dev Constructor that initializes the most important configurations.
/// @param _token Token to be staked and harvested.
/// @param _referralTree Contract with referral's tree.
/// @param _rewards Old farming contract.
/// @param _rewardsV2 Main farming contract.
/// @param _depositBounds Limits of referral's stake used to determine the referral rate.
/// @param _depositRate Referral rates based on referral's deplth and stake received from deposit.
/// @param _stakingRate Referral rates based on referral's deplth and stake received from staking.
constructor(
IMintableBurnableERC20 _token,
IReferralTree _referralTree,
IRewards _rewards,
IRewardsV2 _rewardsV2,
uint256[amtLevels] memory _depositBounds,
uint256[referDepth][amtLevels] memory _depositRate,
uint256[referDepth][amtLevels] memory _stakingRate
)
public
ReferralRewardsV2(
_token,
_referralTree,
_rewards,
_rewardsV2,
_depositBounds,
_depositRate,
_stakingRate
)
{}
/// @dev Allows the main farming contract to assess referral deposit rewardsV2.
/// @param _referrer Address of the referred user.
/// @param _referral Address of the user.
/// @param _amount Amount of new deposit.
function proccessDeposit(
address _referrer,
address _referral,
uint256 _amount
) external override {
require(
msg.sender == address(rewardsV2),
"assessReferalDepositReward: bad role"
);
referralTree.setReferral(_referrer, _referral);
referralReward[_referrer].totalDeposit = referralReward[_referrer]
.totalDeposit
.add(_amount);
address[] memory referrals =
referralTree.getReferrals(_referrer, referDepth);
for (uint256 i = 0; i < referrals.length; i++) {
if (referrals[i] == address(0)) {
continue;
}
accumulateReward(referrals[i]);
ReferralInfo storage referralInfo = referralReward[referrals[i]];
referralInfo.amounts[i] = referralInfo.amounts[i].add(_amount);
}
}
}pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/math/Math.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/IMintableBurnableERC20.sol";
import "./interfaces/IReferralTree.sol";
import "./interfaces/IRewardsV2.sol";
import "./interfaces/IRewards.sol";
contract ReferralRewardsV2 is Ownable {
using SafeMath for uint256;
event ReferralDepositReward(
address indexed refferer,
address indexed refferal,
uint256 indexed level,
uint256 amount
);
event ReferralRewardPaid(address indexed user, uint256 amount);
// Info of each referral
struct ReferralInfo {
uint256 totalDeposit; // Ammount of own deposits
uint256 reward; // Ammount of collected deposit rewardsV2
uint256 lastUpdate; // Last time the referral claimed rewardsV2
uint256[amtLevels] amounts; // Amounts that generate rewardsV2 on each referral level
}
uint256 public constant amtLevels = 3; // Number of levels by total staked amount that determine referral reward's rate
uint256 public constant referDepth = 3; // Number of referral levels that can receive dividends
IMintableBurnableERC20 public token; // Harvested token contract
IReferralTree public referralTree; // Contract with referral's tree
IRewardsV2 rewardsV2; // Main farming contract
IRewards rewards; // Main farming contract
uint256[amtLevels] public depositBounds; // Limits of referral's stake used to determine the referral rate
uint256[referDepth][amtLevels] public depositRate; // Referral rates based on referral's deplth and stake received from deposit
uint256[referDepth][amtLevels] public stakingRate; // Referral rates based on referral's deplth and stake received from staking
mapping(address => ReferralInfo) public referralReward; // Info per each referral
/// @dev Constructor that initializes the most important configurations.
/// @param _token Token to be staked and harvested.
/// @param _referralTree Contract with referral's tree.
/// @param _rewards Main farming contract.
/// @param _depositBounds Limits of referral's stake used to determine the referral rate.
/// @param _depositRate Referral rates based on referral's deplth and stake received from deposit.
/// @param _stakingRate Referral rates based on referral's deplth and stake received from staking.
constructor(
IMintableBurnableERC20 _token,
IReferralTree _referralTree,
IRewards _rewards,
IRewardsV2 _rewardsV2,
uint256[amtLevels] memory _depositBounds,
uint256[referDepth][amtLevels] memory _depositRate,
uint256[referDepth][amtLevels] memory _stakingRate
) public Ownable() {
token = _token;
referralTree = _referralTree;
depositBounds = _depositBounds;
depositRate = _depositRate;
stakingRate = _stakingRate;
rewardsV2 = _rewardsV2;
rewards = _rewards;
}
/// @dev Allows an owner to update bounds.
/// @param _depositBounds Limits of referral's stake used to determine the referral rate.
function setBounds(uint256[amtLevels] memory _depositBounds)
public
onlyOwner
{
depositBounds = _depositBounds;
}
/// @dev Allows an owner to update deposit rates.
/// @param _depositRate Referral rates based on referral's deplth and stake received from deposit.
function setDepositRate(uint256[referDepth][amtLevels] memory _depositRate)
public
onlyOwner
{
depositRate = _depositRate;
}
/// @dev Allows an owner to update staking rates.
/// @param _stakingRate Referral rates based on referral's deplth and stake received from staking.
function setStakingRate(uint256[referDepth][amtLevels] memory _stakingRate)
public
onlyOwner
{
stakingRate = _stakingRate;
}
/// @dev Allows the main farming contract to assess referral deposit rewardsV2.
/// @param _referrer Address of the referred user.
/// @param _referral Address of the user.
/// @param _amount Amount of new deposit.
function proccessDeposit(
address _referrer,
address _referral,
uint256 _amount
) external virtual {
require(
msg.sender == address(rewardsV2),
"assessReferalDepositReward: bad role"
);
referralTree.setReferral(_referrer, _referral);
referralReward[_referrer].totalDeposit = referralReward[_referrer]
.totalDeposit
.add(_amount);
address[] memory referrals =
referralTree.getReferrals(_referrer, referDepth);
uint256[] memory referralStakes = rewards.getReferralStakes(referrals);
for (uint256 level = 0; level < referrals.length; level++) {
if (referrals[level] == address(0)) {
continue;
}
accumulateReward(referrals[level]);
ReferralInfo storage referralInfo =
referralReward[referrals[level]];
referralInfo.amounts[level] = referralInfo.amounts[level].add(
_amount
);
uint256 percent =
getDepositRate(
referralInfo.totalDeposit.add(referralStakes[level]),
level
);
if (percent == 0) {
continue;
}
uint256 depositReward = _amount.mul(percent);
if (depositReward > 0) {
referralInfo.reward = referralInfo.reward.add(depositReward);
emit ReferralDepositReward(
_referrer,
referrals[level],
level,
depositReward
);
}
}
}
/// @dev Allows the main farming contract to assess referral deposit rewardsV2.
/// @param _referrer Address of the referred user.
/// @param _amount Amount of new deposit.
function handleDepositEnd(address _referrer, uint256 _amount)
external
virtual
{
require(msg.sender == address(rewardsV2), "handleDepositEnd: bad role");
referralReward[_referrer].totalDeposit = referralReward[_referrer]
.totalDeposit
.sub(_amount);
address[] memory referrals =
referralTree.getReferrals(_referrer, referDepth);
for (uint256 level = 0; level < referrals.length; level++) {
if (referrals[level] == address(0)) {
continue;
}
accumulateReward(referrals[level]);
ReferralInfo storage referralInfo =
referralReward[referrals[level]];
referralInfo.amounts[level] = referralInfo.amounts[level].sub(
_amount
);
}
}
/// @dev Allows a user to claim his dividends.
function claimDividends() public {
claimUserDividends(msg.sender);
}
/// @dev Allows a referral tree to claim all the dividends.
/// @param _referral Address of user that claims his dividends.
function claimAllDividends(address _referral) public {
require(
msg.sender == address(referralTree),
"claimAllDividends: bad role"
);
claimUserDividends(_referral);
}
/// @dev Update the staking referral reward for _user.
/// @param _user Address of the referral.
function accumulateReward(address _user) internal {
ReferralInfo storage referralInfo = referralReward[_user];
if (referralInfo.lastUpdate > now) {
return;
}
uint256 rewardPerSec = rewardsV2.rewardPerSec();
uint256 referralPrevStake = rewards.getReferralStake(_user);
uint256[referDepth] memory rates =
getStakingRateRange(
referralInfo.totalDeposit.add(referralPrevStake)
);
if (referralInfo.lastUpdate > 0) {
for (uint256 i = 0; i < referralInfo.amounts.length; i++) {
uint256 reward =
now
.sub(referralInfo.lastUpdate)
.mul(referralInfo.amounts[i])
.mul(rewardPerSec)
.mul(rates[i])
.div(1e18);
if (reward > 0) {
referralInfo.reward = referralInfo.reward.add(reward);
}
}
}
referralInfo.lastUpdate = now;
}
/// @dev Asses and distribute claimed dividends.
/// @param _user Address of user that claims dividends.
function claimUserDividends(address _user) internal {
accumulateReward(_user);
ReferralInfo storage referralInfo = referralReward[_user];
uint256 amount = referralInfo.reward.div(1e18);
if (amount > 0) {
uint256 scaledReward = amount.mul(1e18);
referralInfo.reward = referralInfo.reward.sub(scaledReward);
token.mint(_user, amount);
emit ReferralRewardPaid(_user, amount);
}
}
/// @dev Returns referral reward.
/// @param _user Address of referral.
/// @return Referral reward.
function getReferralReward(address _user) external view returns (uint256) {
ReferralInfo storage referralInfo = referralReward[_user];
uint256 rewardPerSec = rewardsV2.rewardPerSec();
uint256 referralPrevStake = rewards.getReferralStake(_user);
uint256[referDepth] memory rates =
getStakingRateRange(
referralInfo.totalDeposit.add(referralPrevStake)
);
uint256 _reward = referralInfo.reward;
if (referralInfo.lastUpdate > 0) {
for (uint256 i = 0; i < referralInfo.amounts.length; i++) {
_reward = _reward.add(
now
.sub(referralInfo.lastUpdate)
.mul(referralInfo.amounts[i])
.mul(rewardPerSec)
.mul(rates[i])
.div(1e18)
);
}
}
return _reward.div(1e18);
}
/// @dev Returns direct user referral.
/// @param _user Address of referrer.
/// @return Direct user referral.
function getReferral(address _user) public view returns (address) {
return referralTree.referrals(_user);
}
/// @dev Returns stakong rate for the spesific referral stake.
/// @param _referralStake Amount staked by referral.
/// @return _rates Array of stakong rates by referral level.
function getStakingRateRange(uint256 _referralStake)
public
view
returns (uint256[referDepth] memory _rates)
{
for (uint256 i = 0; i < depositBounds.length; i++) {
if (_referralStake >= depositBounds[i]) {
return stakingRate[i];
}
}
}
/// @dev Returns deposit rate based on the spesific referral stake and referral level.
/// @param _referralStake Amount staked by referrals.
/// @param _level Level of the referral.
/// @return _rate Deposit rates by referral level.
function getDepositRate(uint256 _referralStake, uint256 _level)
public
view
returns (uint256 _rate)
{
for (uint256 j = 0; j < depositBounds.length; j++) {
if (_referralStake >= depositBounds[j]) {
return depositRate[j][_level];
}
}
}
/// @dev Returns limits of referral's stake used to determine the referral rate.
/// @return Array of deposit bounds.
function getDepositBounds()
public
view
returns (uint256[referDepth] memory)
{
return depositBounds;
}
/// @dev Returns referral rates based on referral's deplth and stake received from staking.
/// @return Array of staking rates.
function getStakingRates()
public
view
returns (uint256[referDepth][amtLevels] memory)
{
return stakingRate;
}
/// @dev Returns referral rates based on referral's deplth and stake received from deposit.
/// @return Array of deposit rates.
function getDepositRates()
public
view
returns (uint256[referDepth][amtLevels] memory)
{
return depositRate;
}
/// @dev Returns amounts that generate reward for referral bu levels.
/// @param _user Address of referral.
/// @return Returns amounts that generate reward for referral bu levels.
function getReferralAmounts(address _user)
public
view
returns (uint256[amtLevels] memory)
{
ReferralInfo memory referralInfo = referralReward[_user];
return referralInfo.amounts;
}
}pragma solidity ^0.6.0;
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/math/Math.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/IMintableBurnableERC20.sol";
import "./interfaces/IReferralRewardsV2.sol";
abstract contract RewardsV2 is Ownable {
using SafeMath for uint256;
event Deposit(
address indexed user,
uint256 indexed id,
uint256 amount,
uint256 start,
uint256 end
);
event Withdraw(
address indexed user,
uint256 indexed id,
uint256 amount,
uint256 ended,
uint256 time
);
event RewardPaid(address indexed user, uint256 amount);
// Info of each deposit made by the user
struct DepositInfo {
uint256 amount; // Amount of deposited LP tokens
uint256 time; // Wnen the deposit is ended
}
// Info of each user
struct UserInfo {
uint256 amount; // Total deposited amount
uint256 unfrozen; // Amount of token to be unstaked
uint256 reward; // Ammount of claimed rewards
uint256 claimable; // Ammount of claimable rewards
uint256 lastUpdate; // Last time the user claimed rewards
uint256 depositHead; // The start index in the deposit's list
uint256 depositTail; // The end index in the deposit's list
mapping(uint256 => DepositInfo) deposits; // User's dposits
}
IMintableBurnableERC20 public token; // Harvested token contract
IReferralRewardsV2 public referralRewards; // Contract that manages referral rewards
uint256 public duration; // How long the deposit works
uint256 public rewardPerSec; // Reward rate generated each second
uint256 public totalStake; // Amount of all staked LP tokens
uint256 public totalClaimed; // Amount of all distributed rewards
uint256 public lastUpdate; // Last time someone received rewards
bool public isActive; // If the deposits are allowed
mapping(address => UserInfo) public userInfo; // Info per each user
/// @dev Constructor that initializes the most important configurations.
/// @param _token Token to be staked and harvested.
/// @param _duration How long the deposit works.
/// @param _rewardPerSec Reward rate generated each second.
constructor(
IMintableBurnableERC20 _token,
uint256 _duration,
uint256 _rewardPerSec
) public Ownable() {
token = _token;
duration = _duration;
rewardPerSec = _rewardPerSec;
isActive = true;
}
/// @dev Allows an owner to stop or countinue deposits.
/// @param _isActive Whether the deposits are allowed.
function setActive(bool _isActive) public onlyOwner {
isActive = _isActive;
}
/// @dev Allows an owner to update referral rewardsV2 module.
/// @param _referralRewards Contract that manages referral rewardsV2.
function setReferralRewards(IReferralRewardsV2 _referralRewards)
public
onlyOwner
{
referralRewards = _referralRewards;
}
/// @dev Allows an owner to update duration of the deposits.
/// @param _duration How long the deposit works.
function setDuration(uint256 _duration) public onlyOwner {
duration = _duration;
}
/// @dev Allows an owner to update reward rate per sec.
/// @param _rewardPerSec Reward rate generated each second.
function setRewardPerSec(uint256 _rewardPerSec) public onlyOwner {
rewardPerSec = _rewardPerSec;
}
/// @dev Allows to stake for the specific user.
/// @param _user Deposit receiver.
/// @param _amount Amount of deposit.
function stakeFor(address _user, uint256 _amount) public {
require(
referralRewards.getReferral(_user) != address(0),
"stakeFor: referral isn't set"
);
proccessStake(_user, _amount, address(0), 0);
}
/// @dev Allows to stake for themselves.
/// @param _amount Amount of deposit.
/// @param _refferal Referral address that will be set in case of the first stake.
/// @param _reinvest Whether the tokens should be reinvested.
function stake(
uint256 _amount,
address _refferal,
uint256 _reinvest
) public {
proccessStake(msg.sender, _amount, _refferal, _reinvest);
}
/// @dev Allows to stake for themselves.
/// @param _count Max amount of claimed deposits.
function claimDeposits(uint256 _count) public {
executeUnstakes(msg.sender, _count);
}
/// @dev Allows to stake for themselves.
/// @param _amount Max amount of claimed deposits.
function claim(uint256 _amount) public {
updateStakingReward(msg.sender);
proccessClaim(msg.sender, _amount, false);
}
/// @dev Proccess the stake.
/// @param _receiver Deposit receiver.
/// @param _amount Amount of deposit.
/// @param _refferal Referral address that will be set in case of the first stake.
/// @param _reinvest Whether the tokens should be reinvested.
function proccessStake(
address _receiver,
uint256 _amount,
address _refferal,
uint256 _reinvest
) internal virtual {
require(isActive, "stake: is paused");
updateStakingReward(_receiver);
if (_amount > 0) {
token.transferFrom(msg.sender, address(this), _amount);
addDeposit(_receiver, _amount, _refferal);
}
if (_reinvest > 0) {
proccessClaim(_receiver, _reinvest, true);
}
}
/// @dev Proccess the stake.
/// @param _receiver Deposit receiver.
/// @param _amount Amount of deposit.
/// @param _reinvest Whether the tokens should be reinvested.
function proccessClaim(
address _receiver,
uint256 _amount,
bool _reinvest
) internal virtual {
UserInfo storage user = userInfo[_receiver];
if (_amount == 0) {
_amount = user.claimable;
}
require(user.claimable >= _amount, "claim: insufficient rewards");
user.claimable = user.claimable.sub(_amount);
user.reward = user.reward.add(_amount);
totalClaimed = totalClaimed.add(_amount);
emit RewardPaid(_receiver, _amount);
if (_reinvest) {
token.mint(address(this), _amount);
addDeposit(_receiver, _amount, address(0));
} else {
token.mint(_receiver, _amount);
}
}
/// @dev Assess new reward.
/// @param _user Address of the user.
function updateStakingReward(address _user) internal {
UserInfo storage user = userInfo[_user];
if (user.lastUpdate >= now) {
return;
}
uint256 scaledReward =
now.sub(user.lastUpdate).mul(user.amount).mul(rewardPerSec);
uint256 reward = scaledReward.div(1e18);
lastUpdate = now;
user.claimable = user.claimable.add(reward);
user.lastUpdate = now;
}
/// @dev Add the deposit.
/// @param _receiver Deposit receiver.
/// @param _amount Amount of deposit.
/// @param _refferal Referral address that will be set in case of the first stake.
function addDeposit(
address _receiver,
uint256 _amount,
address _refferal
) internal virtual {
UserInfo storage user = userInfo[_receiver];
user.amount = user.amount.add(_amount);
totalStake = totalStake.add(_amount);
user.deposits[user.depositTail] = DepositInfo({
amount: _amount,
time: now + duration
});
emit Deposit(_receiver, user.depositTail, _amount, now, now + duration);
user.depositTail = user.depositTail.add(1);
referralRewards.proccessDeposit(_receiver, _refferal, _amount);
}
/// @dev Accumulate new reward and remove old deposits.
/// @param _user Address of the user.
/// @param _count How many deposits to claim.
function executeUnstakes(address _user, uint256 _count) internal virtual {
UserInfo storage user = userInfo[_user];
_count = (_count == 0)
? user.depositTail
: Math.min(user.depositTail, user.depositHead.add(_count));
uint256 endedDepositAmount = 0;
for (uint256 i = user.depositHead; i < _count; i++) {
DepositInfo memory deposit = user.deposits[i];
if (deposit.time < now) {
endedDepositAmount = endedDepositAmount.add(deposit.amount);
delete user.deposits[i];
user.depositHead = user.depositHead.add(1);
emit Withdraw(_user, 0, deposit.amount, deposit.time, now);
}
}
if (endedDepositAmount > 0) {
user.amount = user.amount.sub(endedDepositAmount);
totalStake = totalStake.sub(endedDepositAmount);
referralRewards.handleDepositEnd(_user, endedDepositAmount);
safeTokenTransfer(_user, endedDepositAmount);
}
}
/// @dev Safe token transfer.
/// @param _to Address of the receiver.
/// @param _amount Amount of the tokens to be sent.
function safeTokenTransfer(address _to, uint256 _amount) internal {
uint256 tokenBal = token.balanceOf(address(this));
if (_amount > tokenBal) {
token.transfer(_to, tokenBal);
} else {
token.transfer(_to, _amount);
}
}
/// @dev Returns user's unclaimed reward.
/// @param _user Address of the user.
/// @param _includeDeposit Should the finnished deposits be included into calculations.
/// @return _reward User's reward.
function getPendingReward(address _user, bool _includeDeposit)
public
view
virtual
returns (uint256 _reward)
{
UserInfo storage user = userInfo[_user];
_reward = user.claimable.add(
now.sub(user.lastUpdate).mul(user.amount).mul(rewardPerSec).div(
1e18
)
);
if (_includeDeposit) {
for (uint256 i = user.depositHead; i < user.depositTail; i++) {
DepositInfo memory deposit = user.deposits[i];
if (deposit.time < now) {
_reward = _reward.add(deposit.amount);
}
}
}
}
/// @dev Returns claimed and unclaimed user's reward.
/// @param _user Address of the user.
/// @return _reward User's reward.
function getReward(address _user)
public
view
virtual
returns (uint256 _reward)
{
UserInfo storage user = userInfo[_user];
_reward = user.reward.add(getPendingReward(_user, false));
}
/// @dev Returns approximate reward assessed in the future.
/// @param _delta Time to estimate.
/// @return Predicted rewardsV2.
function getEstimated(uint256 _delta) public view returns (uint256) {
return
(now + _delta)
.sub(lastUpdate)
.mul(totalStake)
.mul(rewardPerSec)
.div(1e18);
}
/// @dev Returns user's deposit by id.
/// @param _user Address of user.
/// @param _id Deposit id.
/// @return Deposited amount and deposit end time.
function getDeposit(address _user, uint256 _id)
public
view
returns (uint256, uint256)
{
DepositInfo memory deposit = userInfo[_user].deposits[_id];
return (deposit.amount, deposit.time);
}
/// @dev Returns user's ended deposits.
/// @param _user Address of the user.
/// @return _count Number of the deposit's that can be withdrawn.
function getEndedDepositsCount(address _user)
public
view
virtual
returns (uint256 _count)
{
UserInfo storage user = userInfo[_user];
for (uint256 i = user.depositHead; i < user.depositTail; i++) {
DepositInfo memory deposit = user.deposits[i];
if (deposit.time < now) {
_count = _count.add(1);
}
}
}
}pragma solidity ^0.6.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol";
interface IMintableBurnableERC20 is IERC20 {
function burn(uint256 amount) external;
function burnFrom(address account, uint256 amount) external;
function mint(address _to, uint256 _amount) external;
}pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
interface IReferralRewards {
struct DepositInfo {
address referrer;
uint256 depth;
uint256 amount;
uint256 time;
uint256 lastUpdatedTime;
}
struct ReferralInfo {
uint256 reward;
uint256 lastUpdate;
uint256 depositHead;
uint256 depositTail;
uint256[3] amounts;
mapping(uint256 => DepositInfo) deposits;
}
function setBounds(uint256[3] calldata _depositBounds) external;
function setDepositRate(uint256[3][3] calldata _depositRate) external;
function setStakingRate(uint256[3][3] calldata _stakingRate) external;
function assessReferalDepositReward(address _referrer, uint256 _amount)
external;
function claimDividends() external;
function claimAllDividends(address _referral) external;
function removeDepositReward(address _referrer, uint256 _amount) external;
function getReferralReward(address _user) external view;
function getReferral(address _user) external view returns (address);
function getStakingRateRange(uint256 _referralStake)
external
view
returns (uint256[3] memory _rates);
function getDepositRate(uint256[] calldata _referralStakes)
external
view
returns (uint256[] memory _rates);
function getDepositBounds() external view returns (uint256[3] memory);
function getStakingRates() external view returns (uint256[3][3] memory);
function getDepositRates() external view returns (uint256[3][3] memory);
function getReferralAmounts(address _user)
external
view
returns (uint256[3] memory);
}pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
interface IReferralRewardsV2 {
struct ReferralInfo {
uint256 totalDeposit;
uint256 reward;
uint256 lastUpdate;
uint256[3] amounts;
}
function setBounds(uint256[3] calldata _depositBounds) external;
function setDepositRate(uint256[3][3] calldata _depositRate) external;
function setStakingRate(uint256[3][3] calldata _stakingRate) external;
function setReferral(address _referrer, address _referral) external;
function assessReferalDepositReward(address _referrer, uint256 _amount)
external;
function transferOwnership(address newOwner) external;
function claimDividends() external;
function claimAllDividends(address _referral) external;
function proccessDeposit(
address _referrer,
address _referral,
uint256 _amount
) external;
function handleDepositEnd(address _referrer, uint256 _amount) external;
function getReferralReward(address _user) external view;
function getReferral(address _user) external view returns (address);
function getStakingRateRange(uint256 _referralStake)
external
view
returns (uint256[3] memory _rates);
function getDepositRate(uint256[] calldata _referralStakes)
external
view
returns (uint256[] memory _rates);
function getDepositBounds() external view returns (uint256[3] memory);
function getStakingRates() external view returns (uint256[3][3] memory);
function getDepositRates() external view returns (uint256[3][3] memory);
function getReferralAmounts(address _user)
external
view
returns (uint256[3] memory);
}pragma solidity ^0.6.0;
import "./IReferralRewards.sol";
interface IReferralTree {
function changeAdmin(address _newAdmin) external;
function setReferral(address _referrer, address _referral) external;
function removeReferralReward(IReferralRewards _referralRewards) external;
function addReferralReward(IReferralRewards _referralRewards) external;
function claimAllDividends() external;
function getReferrals(address _referrer, uint256 _referDepth)
external
view
returns (address[] memory);
function referrals(address _referrer) external view returns (address);
function getReferrers(address _referral)
external
view
returns (address[] memory);
function getUserReferralReward(address _user)
external
view
returns (uint256);
function getReferralRewards()
external
view
returns (IReferralRewards[] memory);
}pragma solidity ^0.6.0;
// import "./dANT.sol";
import "./IReferralRewards.sol";
interface IRewards {
struct DepositInfo {
uint256 amount;
uint256 time;
}
struct UserInfo {
uint256 amount;
uint256 unfrozen;
uint256 reward;
uint256 lastUpdate;
uint256 depositHead;
uint256 depositTail;
mapping(uint256 => DepositInfo) deposits;
}
function setActive(bool _isActive) external;
function setReferralRewards(IReferralRewards _referralRewards) external;
function setDuration(uint256 _duration) external;
function setRewardPerSec(uint256 _rewardPerSec) external;
function stakeFor(address _user, uint256 _amount) external;
function stake(uint256 _amount, address _refferal) external;
function getPendingReward(address _user, bool _includeDeposit)
external
view
returns (uint256 _reward);
function getReward(address _user) external view returns (uint256 _reward);
function getReferralStakes(address[] calldata _referrals)
external
view
returns (uint256[] memory _stakes);
function getReferralStake(address _referral)
external
view
returns (uint256);
function getEstimated(uint256 _delta) external view returns (uint256);
function getDeposit(address _user, uint256 _id)
external
view
returns (uint256, uint256);
}pragma solidity ^0.6.0;
// import "./dANT.sol";
import "./IReferralRewards.sol";
interface IRewardsV2 {
struct DepositInfo {
uint256 amount;
uint256 time;
}
struct UserInfo {
uint256 amount;
uint256 unfrozen;
uint256 reward;
uint256 lastUpdate;
uint256 depositHead;
uint256 depositTail;
mapping(uint256 => DepositInfo) deposits;
}
function setActive(bool _isActive) external;
function setReferralRewards(IReferralRewards _referralRewards) external;
function setDuration(uint256 _duration) external;
function setRewardPerSec(uint256 _rewardPerSec) external;
function stakeFor(address _user, uint256 _amount) external;
function stake(uint256 _amount, address _refferal) external;
function getPendingReward(address _user, bool _includeDeposit)
external
view
returns (uint256 _reward);
function rewardPerSec() external view returns (uint256);
function getReward(address _user) external view returns (uint256 _reward);
function getReferralStake(address _referral)
external
view
returns (uint256);
function getEstimated(uint256 _delta) external view returns (uint256);
function getDeposit(address _user, uint256 _id)
external
view
returns (uint256, uint256);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <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 GSN 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 payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../GSN/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 () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view 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 {
emit OwnershipTransferred(_owner, address(0));
_owner = 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");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow, so we distribute
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../../GSN/Context.sol";
import "./IERC20.sol";
import "../../math/SafeMath.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of returning `false` on failure. This behavior is nonetheless conventional
* and does not conflict with the expectations of ERC20 applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20 {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
/**
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with
* a default value of 18.
*
* To select a different value for {decimals}, use {_setupDecimals}.
*
* All three of these values are immutable: they can only be set once during
* construction.
*/
constructor (string memory name_, string memory symbol_) public {
_name = name_;
_symbol = symbol_;
_decimals = 18;
}
/**
* @dev Returns the name of the token.
*/
function name() public view returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
* called.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view returns (uint8) {
return _decimals;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `to` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Sets {decimals} to a value other than the default one of 18.
*
* WARNING: This function should only be called from the constructor. Most
* applications that interact with token contracts will not expect
* {decimals} to ever change, and may work incorrectly if it does.
*/
function _setupDecimals(uint8 decimals_) internal {
_decimals = decimals_;
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../../GSN/Context.sol";
import "./ERC20.sol";
/**
* @dev Extension of {ERC20} that allows token holders to destroy both their own
* tokens and those that they have an allowance for, in a way that can be
* recognized off-chain (via event analysis).
*/
abstract contract ERC20Burnable is Context, ERC20 {
using SafeMath for uint256;
/**
* @dev Destroys `amount` tokens from the caller.
*
* See {ERC20-_burn}.
*/
function burn(uint256 amount) public virtual {
_burn(_msgSender(), amount);
}
/**
* @dev Destroys `amount` tokens from `account`, deducting from the caller's
* allowance.
*
* See {ERC20-_burn} and {ERC20-allowance}.
*
* Requirements:
*
* - the caller must have allowance for ``accounts``'s tokens of at least
* `amount`.
*/
function burnFrom(address account, uint256 amount) public virtual {
uint256 decreasedAllowance = allowance(account, _msgSender()).sub(amount, "ERC20: burn amount exceeds allowance");
_approve(account, _msgSender(), decreasedAllowance);
_burn(account, amount);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}{
"remappings": [],
"optimizer": {
"enabled": false,
"runs": 200
},
"evmVersion": "istanbul",
"libraries": {},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IMintableBurnableERC20","name":"_token","type":"address"},{"internalType":"contract IRewards","name":"_rewards","type":"address"},{"internalType":"contract IReferralTree","name":"_referralTree","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"start","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"end","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ended","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timelock","type":"uint256"}],"name":"WithdrawRequested","type":"event"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"claimDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getEndedDepositsCount","outputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_delta","type":"uint256"}],"name":"getEstimated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"bool","name":"_includeDeposit","type":"bool"}],"name":"getPendingReward","outputs":[{"internalType":"uint256","name":"_reward","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getRequestsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getReward","outputs":[{"internalType":"uint256","name":"_reward","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalPendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referralRewards","outputs":[{"internalType":"contract IReferralRewardsV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"requestHead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerSec","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_isActive","type":"bool"}],"name":"setActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"setDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IReferralRewardsV2","name":"_referralRewards","type":"address"}],"name":"setReferralRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardPerSec","type":"uint256"}],"name":"setRewardPerSec","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_refferal","type":"address"},{"internalType":"uint256","name":"_reinvest","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IMintableBurnableERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStake","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":"_amount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"unstakeRequests","outputs":[{"internalType":"uint256","name":"timelock","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum RewardsType5.Status","name":"status","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unfrozen","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"claimable","type":"uint256"},{"internalType":"uint256","name":"lastUpdate","type":"uint256"},{"internalType":"uint256","name":"depositHead","type":"uint256"},{"internalType":"uint256","name":"depositTail","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405162006a7c38038062006a7c833981810160405260608110156200003757600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050826000640d7957c642600062000077620005a660201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35082600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600381905550806004819055506001600860006101000a81548160ff021916908315150217905550505050600083828430604051806060016040528069010f0cf064dd592000008152602001686c6b935b8bbd400000815260200168056bc75e2d631000008152506040518060600160405280604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280600081526020016000815260200160008152508152506040518060600160405280604051806060016040528066d529ae9e860000815260200166470de4df8200008152602001662386f26fc100008152508152602001604051806060016040528066b1a2bc2ec50000815260200166354a6ba7a180008152602001661aa535d3d0c00081525081526020016040518060600160405280668e1bc9bf0400008152602001662386f26fc1000081526020016611c37937e08000815250815250604051620002e790620005ae565b808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184600360200280838360005b83811015620003d9578082015181840152602081019050620003bc565b505050509050018360036000925b81841015620004315782846020020151600360200280838360005b838110156200041f57808201518184015260208101905062000402565b505050509050019260010192620003e7565b925050508260036000925b81841015620004865782846020020151600360200280838360005b838110156200047457808201518184015260208101905062000457565b5050505090500192600101926200043c565b92505050975050505050505050604051809103906000f080158015620004b0573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b620004df620005a660201b60201c565b6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156200054257600080fd5b505af115801562000557573d6000803e3d6000fd5b5050505080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050620005bc565b600033905090565b6135f3806200348983390190565b612ebd80620005cc6000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c8063715018a61161010f578063c00007b0116100a2578063eeb58da511610071578063eeb58da514610879578063f2fde38b146108bd578063f6be71d114610901578063fc0c546a1461092f576101e5565b8063c00007b0146107c7578063c04637111461081f578063d54ad2a11461083d578063e627f2db1461085b576101e5565b8063abdc8054116100de578063abdc8054146106cf578063acec338a14610711578063adcfa77314610741578063b43b6d481461076f576101e5565b8063715018a6146106135780638b0e9f3f1461061d5780638da5cb5b1461063b578063995deaba14610685576101e5565b80632ee40908116101875780634da63f8f116101565780634da63f8f146104bb5780634f41e95d1461051f57806366442a061461053d5780636e9c931c146105bb576101e5565b80632ee40908146103b9578063379607f5146104075780634709384f146104355780634d597e7614610463576101e5565b80631e9b3a92116101c35780631e9b3a92146102e257806322f3e2d4146103005780632726b506146103225780632e17de781461038b576101e5565b80630fb5a6b4146101ea57806316ad0f6d146102085780631959a00214610260575b600080fd5b6101f2610979565b6040518082815260200191505060405180910390f35b61024a6004803603602081101561021e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061097f565b6040518082815260200191505060405180910390f35b6102a26004803603602081101561027657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109cb565b6040518088815260200187815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390f35b6102ea610a0d565b6040518082815260200191505060405180910390f35b610308610a6b565b604051808215151515815260200191505060405180910390f35b61036e6004803603604081101561033857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a7e565b604051808381526020018281526020019250505060405180910390f35b6103b7600480360360208110156103a157600080fd5b8101908080359060200190929190505050610b13565b005b610405600480360360408110156103cf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e0c565b005b6104336004803603602081101561041d57600080fd5b8101908080359060200190929190505050610f99565b005b6104616004803603602081101561044b57600080fd5b8101908080359060200190929190505050610fb1565b005b6104a56004803603602081101561047957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fbe565b6040518082815260200191505060405180910390f35b610509600480360360408110156104d157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050610fd6565b6040518082815260200191505060405180910390f35b6105276111ee565b6040518082815260200191505060405180910390f35b6105896004803603604081101561055357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506111f4565b604051808481526020018381526020018260028111156105a557fe5b60ff168152602001935050505060405180910390f35b610611600480360360608110156105d157600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611245565b005b61061b611256565b005b6106256113de565b6040518082815260200191505060405180910390f35b6106436113e4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61068d61140d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106fb600480360360208110156106e557600080fd5b8101908080359060200190929190505050611433565b6040518082815260200191505060405180910390f35b61073f6004803603602081101561072757600080fd5b81019080803515159060200190929190505050611495565b005b61076d6004803603602081101561075757600080fd5b810190808035906020019092919050505061157b565b005b6107b16004803603602081101561078557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061164e565b6040518082815260200191505060405180910390f35b610809600480360360208110156107dd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117a4565b6040518082815260200191505060405180910390f35b610827611811565b6040518082815260200191505060405180910390f35b610845611817565b6040518082815260200191505060405180910390f35b61086361181d565b6040518082815260200191505060405180910390f35b6108bb6004803603602081101561088f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061186e565b005b6108ff600480360360208110156108d357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061197b565b005b61092d6004803603602081101561091757600080fd5b8101908080359060200190929190505050611b88565b005b610937611c5b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60035481565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b60096020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154905087565b6000610a66670de0b6b3a7640000610a58600454610a4a600554610a3c60075442611c8190919063ffffffff16565b611ccb90919063ffffffff16565b611ccb90919063ffffffff16565b611d5190919063ffffffff16565b905090565b600860009054906101000a900460ff1681565b600080610a89612e26565b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060070160008581526020019081526020016000206040518060400160405290816000820154815260200160018201548152505090508060000151816020015192509250509250929050565b610b1c33611d9b565b6000600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000821415610b7057806000015491505b610b87828260000154611c8190919063ffffffff16565b8160000181905550610ba6828260010154611e8990919063ffffffff16565b8160010181905550610bc382600554611c8190919063ffffffff16565b6005819055506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180606001604052806203f4804201815260200185815260200160016002811115610c7857fe5b8152509080600181540180825580915050600190039060005260206000209060030201600090919091909150600082015181600001556020820151816001015560408201518160020160006101000a81548160ff02191690836002811115610cdc57fe5b021790555050503373ffffffffffffffffffffffffffffffffffffffff167f7a64d79878509820925daa6339976afdd4e1c50dc32bfae6820dd5792bd306a782856203f480420160405180848152602001838152602001828152602001935050505060405180910390a2600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634dc0d7c733856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015610def57600080fd5b505af1158015610e03573d6000803e3d6000fd5b50505050505050565b600073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b0f0f2f846040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610ec357600080fd5b505afa158015610ed7573d6000803e3d6000fd5b505050506040513d6020811015610eed57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161415610f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f7374616b65466f723a20726566657272616c2069736e2774207365740000000081525060200191505060405180910390fd5b610f958282600080611f11565b5050565b610fa233611d9b565b610fae338260006120e6565b50565b610fbb33826123fb565b50565b600b6020528060005260406000206000915090505481565b600080600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061108b611078670de0b6b3a764000061106a60045461105c866000015461104e886004015442611c8190919063ffffffff16565b611ccb90919063ffffffff16565b611ccb90919063ffffffff16565b611d5190919063ffffffff16565b8260030154611e8990919063ffffffff16565b915082156111e7576000600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110156111e5576000600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061116e57fe5b906000526020600020906003020190504281600001541080156111b857506001600281111561119957fe5b8160020160009054906101000a900460ff1660028111156111b657fe5b145b156111d7576111d4816001015485611e8990919063ffffffff16565b93505b5080806001019150506110d8565b505b5092915050565b60045481565b600a602052816000526040600020818154811061120d57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900460ff16905083565b61125133848484611f11565b505050565b61125e61277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461131f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60055481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061148e670de0b6b3a7640000611480600454611472600554611464600754894201611c8190919063ffffffff16565b611ccb90919063ffffffff16565b611ccb90919063ffffffff16565b611d5190919063ffffffff16565b9050919050565b61149d61277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461155e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600860006101000a81548160ff02191690831515021790555050565b61158361277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611644576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8060048190555050565b600080600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905081101561179e576000600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061172a57fe5b9060005260206000209060030201905042816000015410801561177457506001600281111561175557fe5b8160020160009054906101000a900460ff16600281111561177257fe5b145b156117905761178d600184611e8990919063ffffffff16565b92505b508080600101915050611694565b50919050565b600080600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506118096117f6846000610fd6565b8260020154611e8990919063ffffffff16565b915050919050565b60075481565b60065481565b6000611869670de0b6b3a764000061185b60065461184d61183c610a0d565b600654611e8990919063ffffffff16565b611c8190919063ffffffff16565b611d5190919063ffffffff16565b905090565b61187661277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611937576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61198361277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611a44576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611aca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612e416026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611b9061277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8060038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611cc383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612784565b905092915050565b600080831415611cde5760009050611d4b565b6000828402905082848281611cef57fe5b0414611d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612e676021913960400191505060405180910390fd5b809150505b92915050565b6000611d9383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612844565b905092915050565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905042816004015410611def5750611e86565b6000611e32600454611e248460000154611e16866004015442611c8190919063ffffffff16565b611ccb90919063ffffffff16565b611ccb90919063ffffffff16565b90506000611e51670de0b6b3a764000083611d5190919063ffffffff16565b905042600781905550611e71818460030154611e8990919063ffffffff16565b83600301819055504283600401819055505050505b50565b600080828401905083811015611f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600860009054906101000a900460ff16611f93576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f7374616b653a206973207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b611f9c84611d9b565b60008311156120ca57600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561208257600080fd5b505af1158015612096573d6000803e3d6000fd5b505050506040513d60208110156120ac57600080fd5b8101908080519060200190929190505050506120c984848461290a565b5b60008111156120e0576120df848260016120e6565b5b50505050565b6000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600083141561213a57806003015492505b82816003015410156121b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f636c61696d3a20696e73756666696369656e742072657761726473000000000081525060200191505060405180910390fd5b6121cb838260030154611c8190919063ffffffff16565b81600301819055506121ea838260020154611e8990919063ffffffff16565b816002018190555061220783600654611e8990919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486846040518082815260200191505060405180910390a2811561233357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561230a57600080fd5b505af115801561231e573d6000803e3d6000fd5b5050505061232e8484600061290a565b6123f5565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1985856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156123dc57600080fd5b505af11580156123f0573d6000803e3d6000fd5b505050505b50505050565b600081146124a5576124a0600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905061249b83600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611e8990919063ffffffff16565b612b52565b6124e9565b600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490505b90506000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b81811015612777576000600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061258457fe5b906000526020600020906003020190504281600001541080156125ce5750600160028111156125af57fe5b8160020160009054906101000a900460ff1660028111156125cc57fe5b145b156127695760028160020160006101000a81548160ff021916908360028111156125f457fe5b02179055506000600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061265782600101548260010154611c8190919063ffffffff16565b816001018190555061266d858360010154612b6b565b828573ffffffffffffffffffffffffffffffffffffffff167fe08737ac48a1dab4b1a46c7dc9398bd5bfc6d7ad6fabb7cd8caa254de14def35846001015460004260405180848152602001838152602001828152602001935050505060405180910390a36127246001600b60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611e8990919063ffffffff16565b600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b508080600101915050612530565b505050565b600033905090565b6000838311158290612831576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156127f65780820151818401526020810190506127db565b50505050905090810190601f1680156128235780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080831182906128f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156128b557808201518184015260208101905061289a565b50505050905090810190601f1680156128e25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816128fc57fe5b049050809150509392505050565b6000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050612964838260000154611e8990919063ffffffff16565b816000018190555061298183600554611e8990919063ffffffff16565b6005819055506040518060400160405280848152602001600354420181525081600701600083600601548152602001908152602001600020600082015181600001556020820151816001015590505080600601548473ffffffffffffffffffffffffffffffffffffffff167f7162984403f6c73c8639375d45a9187dfd04602231bd8e587c415718b5f7e5f98542600354420160405180848152602001838152602001828152602001935050505060405180910390a3612a4f60018260060154611e8990919063ffffffff16565b8160060181905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a6535fd28584866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015612b3457600080fd5b505af1158015612b48573d6000803e3d6000fd5b5050505050505050565b6000818310612b615781612b63565b825b905092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612c0c57600080fd5b505afa158015612c20573d6000803e3d6000fd5b505050506040513d6020811015612c3657600080fd5b8101908080519060200190929190505050905080821115612d3b57600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612cfa57600080fd5b505af1158015612d0e573d6000803e3d6000fd5b505050506040513d6020811015612d2457600080fd5b810190808051906020019092919050505050612e21565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612de457600080fd5b505af1158015612df8573d6000803e3d6000fd5b505050506040513d6020811015612e0e57600080fd5b8101908080519060200190929190505050505b505050565b60405180604001604052806000815260200160008152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220bde1651ceae600efa54b41620e732efc1fffc64dd202082d681d275315bf356f64736f6c6343000602003360806040523480156200001157600080fd5b50604051620035f3380380620035f3833981810160405262000037919081019062000586565b868686868686866000620000506200024260201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35086600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826005906003620001839291906200024a565b50816008906003620001979291906200028f565b50806011906003620001ab9291906200028f565b5083600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050505050505050505050620007dc565b600033905090565b82600381019282156200027c579160200282015b828111156200027b5782518255916020019190600101906200025e565b5b5090506200028b9190620002e6565b5090565b82600380028101928215620002d3579160200282015b82811115620002d257825182906003620002c19291906200030e565b5091602001919060030190620002a5565b5b509050620002e2919062000353565b5090565b6200030b91905b8082111562000307576000816000905550600101620002ed565b5090565b90565b826003810192821562000340579160200282015b828111156200033f57825182559160200191906001019062000322565b5b5090506200034f9190620002e6565b5090565b6200038191905b808211156200037d576000818162000373919062000384565b506003016200035a565b5090565b90565b50600081556001016000815560010160009055565b600082601f830112620003ab57600080fd5b6003620003c2620003bc8262000663565b62000635565b91508183856060840282011115620003d957600080fd5b60005b838110156200040d5781620003f2888262000417565b845260208401935060608301925050600181019050620003dc565b5050505092915050565b600082601f8301126200042957600080fd5b6003620004406200043a8262000686565b62000635565b915081838560208402820111156200045757600080fd5b60005b838110156200048b57816200047088826200056f565b8452602084019350602083019250506001810190506200045a565b5050505092915050565b600082601f830112620004a757600080fd5b6003620004be620004b882620006a9565b62000635565b91508183856020840282011115620004d557600080fd5b60005b83811015620005095781620004ee88826200056f565b845260208401935060208301925050600181019050620004d8565b5050505092915050565b60008151905062000524816200075a565b92915050565b6000815190506200053b8162000774565b92915050565b60008151905062000552816200078e565b92915050565b6000815190506200056981620007a8565b92915050565b6000815190506200058081620007c2565b92915050565b6000806000806000806000610320888a031215620005a357600080fd5b6000620005b38a828b0162000513565b9750506020620005c68a828b016200052a565b9650506040620005d98a828b0162000558565b9550506060620005ec8a828b0162000541565b9450506080620005ff8a828b0162000495565b93505060e0620006128a828b0162000399565b925050610200620006268a828b0162000399565b91505092959891949750929550565b6000604051905081810181811067ffffffffffffffff821117156200065957600080fd5b8060405250919050565b600067ffffffffffffffff8211156200067b57600080fd5b602082029050919050565b600067ffffffffffffffff8211156200069e57600080fd5b602082029050919050565b600067ffffffffffffffff821115620006c157600080fd5b602082029050919050565b6000620006d98262000730565b9050919050565b6000620006ed82620006cc565b9050919050565b60006200070182620006cc565b9050919050565b60006200071582620006cc565b9050919050565b60006200072982620006cc565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6200076581620006e0565b81146200077157600080fd5b50565b6200077f81620006f4565b81146200078b57600080fd5b50565b620007998162000708565b8114620007a557600080fd5b50565b620007b3816200071c565b8114620007bf57600080fd5b50565b620007cd8162000750565b8114620007d957600080fd5b50565b612e0780620007ec6000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c80636e18b6db116100de578063a6a9fcfa11610097578063e7e2fe1911610071578063e7e2fe1914610485578063f2fde38b146104a3578063f3c13a12146104bf578063fc0c546a146104ef5761018e565b8063a6a9fcfa14610409578063ad35710114610439578063c72b50fd146104695761018e565b80636e18b6db14610333578063715018a614610365578063767bd4ba1461036f5780638da5cb5b1461039f57806393af7adc146103bd578063a6535fd2146103ed5761018e565b80633a294ba31161014b5780634dc0d7c7116101255780634dc0d7c7146102d157806353d4e7f5146102ed578063668038e01461030b5780636dcc2b3a146103155761018e565b80633a294ba3146102555780633b0f0f2f14610271578063414eff13146102a15761018e565b80630342e122146101935780630b3cb9d2146101c3578063168b85cf146101e157806319aaff86146101fd578063396fe62714610219578063397f669014610237575b600080fd5b6101ad60048036036101a89190810190612528565b61050d565b6040516101ba9190612b2b565b60405180910390f35b6101cb61056e565b6040516101d89190612b2b565b60405180910390f35b6101fb60048036036101f691908101906124ad565b610573565b005b61021760048036036102129190810190612365565b61061e565b005b6102216106ba565b60405161022e91906129bc565b60405180910390f35b61023f61073d565b60405161024c9190612a0e565b60405180910390f35b61026f600480360361026a9190810190612483565b610763565b005b61028b60048036036102869190810190612365565b61080e565b604051610298919061294f565b60405180910390f35b6102bb60048036036102b69190810190612365565b6108c2565b6040516102c89190612b2b565b60405180910390f35b6102eb60048036036102e69190810190612406565b610b78565b005b6102f5610e74565b60405161030291906129bc565b60405180910390f35b610313610ef7565b005b61031d610f02565b60405161032a9190612b2b565b60405180910390f35b61034d60048036036103489190810190612365565b610f07565b60405161035c93929190612b46565b60405180910390f35b61036d610f31565b005b610389600480360361038491908101906124d6565b611086565b6040516103969190612b2b565b60405180910390f35b6103a761109e565b6040516103b4919061294f565b60405180910390f35b6103d760048036036103d291908101906124d6565b6110c7565b6040516103e491906129d8565b60405180910390f35b610407600480360361040291908101906123b7565b61115c565b005b610423600480360361041e9190810190612365565b6114e8565b60405161043091906129d8565b60405180910390f35b610453600480360361044e9190810190612528565b6115b4565b6040516104609190612b2b565b60405180910390f35b610483600480360361047e9190810190612483565b6115dc565b005b61048d611687565b60405161049a91906129d8565b60405180910390f35b6104bd60048036036104b89190810190612365565b6116d2565b005b6104d960048036036104d49190810190612528565b611896565b6040516104e69190612b2b565b60405180910390f35b6104f76118be565b60405161050491906129f3565b60405180910390f35b600080600090505b6003811015610566576005816003811061052b57fe5b01548410610559576008816003811061054057fe5b60030201836003811061054f57fe5b0154915050610568565b8080600101915050610515565b505b92915050565b600381565b61057b6118e4565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610609576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060090612acb565b60405180910390fd5b80600590600361061a929190611f5d565b5050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a590612aeb565b60405180910390fd5b6106b7816118ec565b50565b6106c2611f9d565b6011600380602002604051908101604052809291906000905b8282101561073457838260030201600380602002604051908101604052809291908260038015610720576020028201915b81548152602001906001019080831161070c575b5050505050815260200190600101906106db565b50505050905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61076b6118e4565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f090612acb565b60405180910390fd5b80601190600361080a929190611fca565b5050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639ca423b3836040518263ffffffff1660e01b815260040161086b919061294f565b60206040518083038186803b15801561088357600080fd5b505afa158015610897573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108bb919081019061238e565b9050919050565b600080601a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f41e95d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561097057600080fd5b505afa158015610984573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109a891908101906124ff565b90506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631b1ace25866040518263ffffffff1660e01b8152600401610a07919061294f565b60206040518083038186803b158015610a1f57600080fd5b505afa158015610a33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a5791908101906124ff565b9050610a6161201a565b610a80610a7b838660000154611a8690919063ffffffff16565b6110c7565b9050600084600101549050600085600201541115610b515760008090505b6003811015610b4f57610b40610b31670de0b6b3a7640000610b23868560038110610ac557fe5b6020020151610b158a610b078d6003018960038110610ae057fe5b0154610af98f6002015442611adb90919063ffffffff16565b611b2590919063ffffffff16565b611b2590919063ffffffff16565b611b2590919063ffffffff16565b611b9590919063ffffffff16565b83611a8690919063ffffffff16565b91508080600101915050610a9e565b505b610b6c670de0b6b3a764000082611b9590919063ffffffff16565b95505050505050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bff90612a4b565b60405180910390fd5b610c5d81601a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154611adb90919063ffffffff16565b601a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055506060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166332a00d8e8460036040518363ffffffff1660e01b8152600401610d03929190612993565b60006040518083038186803b158015610d1b57600080fd5b505afa158015610d2f573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610d589190810190612442565b905060008090505b8151811015610e6e57600073ffffffffffffffffffffffffffffffffffffffff16828281518110610d8d57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff161415610db657610e61565b610dd2828281518110610dc557fe5b6020026020010151611bdf565b6000601a6000848481518110610de457fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050610e4b84826003018460038110610e3b57fe5b0154611adb90919063ffffffff16565b816003018360038110610e5a57fe5b0181905550505b8080600101915050610d60565b50505050565b610e7c611f9d565b6008600380602002604051908101604052809291906000905b82821015610eee57838260030201600380602002604051908101604052809291908260038015610eda576020028201915b815481526020019060010190808311610ec6575b505050505081526020019060010190610e95565b50505050905090565b610f00336118ec565b565b600381565b601a6020528060005260406000206000915090508060000154908060010154908060020154905083565b610f396118e4565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fbe90612acb565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6005816003811061109357fe5b016000915090505481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6110cf61201a565b60008090505b600381101561115557600581600381106110eb57fe5b01548310611148576011816003811061110057fe5b6003020160038060200260405190810160405280929190826003801561113b576020028201915b815481526020019060010190808311611127575b5050505050915050611157565b80806001019150506110d5565b505b919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e390612b0b565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637543e3f084846040518363ffffffff1660e01b815260040161124992919061296a565b600060405180830381600087803b15801561126357600080fd5b505af1158015611277573d6000803e3d6000fd5b505050506112d081601a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154611a8690919063ffffffff16565b601a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055506060600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166332a00d8e8560036040518363ffffffff1660e01b8152600401611376929190612993565b60006040518083038186803b15801561138e57600080fd5b505afa1580156113a2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506113cb9190810190612442565b905060008090505b81518110156114e157600073ffffffffffffffffffffffffffffffffffffffff1682828151811061140057fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff161415611429576114d4565b61144582828151811061143857fe5b6020026020010151611bdf565b6000601a600084848151811061145757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506114be848260030184600381106114ae57fe5b0154611a8690919063ffffffff16565b8160030183600381106114cd57fe5b0181905550505b80806001019150506113d3565b5050505050565b6114f061201a565b6114f861203c565b601a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820160038060200260405190810160405280929190826003801561159c576020028201915b815481526020019060010190808311611588575b50505050508152505090508060600151915050919050565b601182600381106115c157fe5b6003020181600381106115d057fe5b01600091509150505481565b6115e46118e4565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166990612acb565b60405180910390fd5b806008906003611683929190611fca565b5050565b61168f61201a565b60056003806020026040519081016040528092919082600380156116c8576020028201915b8154815260200190600101908083116116b4575b5050505050905090565b6116da6118e4565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611768576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175f90612acb565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156117d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117cf90612a6b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600882600381106118a357fe5b6003020181600381106118b257fe5b01600091509150505481565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600033905090565b6118f581611bdf565b6000601a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000611959670de0b6b3a76400008360010154611b9590919063ffffffff16565b90506000811115611a81576000611981670de0b6b3a764000083611b2590919063ffffffff16565b905061199a818460010154611adb90919063ffffffff16565b8360010181905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1985846040518363ffffffff1660e01b81526004016119ff929190612993565b600060405180830381600087803b158015611a1957600080fd5b505af1158015611a2d573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff167f04b20935b234f45fda390d2df59d92b7bb8bed322d3bc8764e826cfff50007d583604051611a779190612b2b565b60405180910390a2505b505050565b600080828401905083811015611ad1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac890612a8b565b60405180910390fd5b8091505092915050565b6000611b1d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611ea1565b905092915050565b600080831415611b385760009050611b8f565b6000828402905082848281611b4957fe5b0414611b8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b8190612aab565b60405180910390fd5b809150505b92915050565b6000611bd783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611efc565b905092915050565b6000601a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090504281600201541115611c345750611e9e565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f41e95d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c9e57600080fd5b505afa158015611cb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611cd691908101906124ff565b90506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631b1ace25856040518263ffffffff1660e01b8152600401611d35919061294f565b60206040518083038186803b158015611d4d57600080fd5b505afa158015611d61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d8591908101906124ff565b9050611d8f61201a565b611dae611da9838660000154611a8690919063ffffffff16565b6110c7565b9050600084600201541115611e905760008090505b6003811015611e8e576000611e55670de0b6b3a7640000611e47858560038110611de957fe5b6020020151611e3989611e2b8c6003018960038110611e0457fe5b0154611e1d8e6002015442611adb90919063ffffffff16565b611b2590919063ffffffff16565b611b2590919063ffffffff16565b611b2590919063ffffffff16565b611b9590919063ffffffff16565b90506000811115611e8057611e77818760010154611a8690919063ffffffff16565b86600101819055505b508080600101915050611dc3565b505b428460020181905550505050505b50565b6000838311158290611ee9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee09190612a29565b60405180910390fd5b5060008385039050809150509392505050565b60008083118290611f43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3a9190612a29565b60405180910390fd5b506000838581611f4f57fe5b049050809150509392505050565b8260038101928215611f8c579160200282015b82811115611f8b578251825591602001919060010190611f70565b5b509050611f99919061206a565b5090565b60405180606001604052806003905b611fb461208f565b815260200190600190039081611fac5790505090565b82600380028101928215612009579160200282015b8281111561200857825182906003611ff89291906120b1565b5091602001919060030190611fdf565b5b50905061201691906120f1565b5090565b6040518060600160405280600390602082028038833980820191505090505090565b604051806080016040528060008152602001600081526020016000815260200161206461208f565b81525090565b61208c91905b80821115612088576000816000905550600101612070565b5090565b90565b6040518060600160405280600390602082028038833980820191505090505090565b82600381019282156120e0579160200282015b828111156120df5782518255916020019190600101906120c4565b5b5090506120ed919061206a565b5090565b61211a91905b80821115612116576000818161210d919061211d565b506003016120f7565b5090565b90565b50600081556001016000815560010160009055565b60008135905061214181612da3565b92915050565b60008151905061215681612da3565b92915050565b600082601f83011261216d57600080fd5b815161218061217b82612baa565b612b7d565b915081818352602084019350602081019050838560208402820111156121a557600080fd5b60005b838110156121d557816121bb8882612147565b8452602084019350602083019250506001810190506121a8565b5050505092915050565b600082601f8301126121f057600080fd5b60036122036121fe82612bd2565b612b7d565b9150818385606084028201111561221957600080fd5b60005b83811015612249578161222f8882612253565b84526020840193506060830192505060018101905061221c565b5050505092915050565b600082601f83011261226457600080fd5b600361227761227282612bf4565b612b7d565b9150818385602084028201111561228d57600080fd5b60005b838110156122bd57816122a3888261233b565b845260208401935060208301925050600181019050612290565b5050505092915050565b600082601f8301126122d857600080fd5b60036122eb6122e682612c16565b612b7d565b9150818385602084028201111561230157600080fd5b60005b838110156123315781612317888261233b565b845260208401935060208301925050600181019050612304565b5050505092915050565b60008135905061234a81612dba565b92915050565b60008151905061235f81612dba565b92915050565b60006020828403121561237757600080fd5b600061238584828501612132565b91505092915050565b6000602082840312156123a057600080fd5b60006123ae84828501612147565b91505092915050565b6000806000606084860312156123cc57600080fd5b60006123da86828701612132565b93505060206123eb86828701612132565b92505060406123fc8682870161233b565b9150509250925092565b6000806040838503121561241957600080fd5b600061242785828601612132565b92505060206124388582860161233b565b9150509250929050565b60006020828403121561245457600080fd5b600082015167ffffffffffffffff81111561246e57600080fd5b61247a8482850161215c565b91505092915050565b6000610120828403121561249657600080fd5b60006124a4848285016121df565b91505092915050565b6000606082840312156124bf57600080fd5b60006124cd848285016122c7565b91505092915050565b6000602082840312156124e857600080fd5b60006124f68482850161233b565b91505092915050565b60006020828403121561251157600080fd5b600061251f84828501612350565b91505092915050565b6000806040838503121561253b57600080fd5b60006125498582860161233b565b925050602061255a8582860161233b565b9150509250929050565b60006125708383612651565b60608301905092915050565b60006125888383612931565b60208301905092915050565b61259d81612cdb565b82525050565b6125ac81612c56565b6125b68184612ca9565b92506125c182612c38565b8060005b838110156125f25781516125d98782612564565b96506125e483612c82565b9250506001810190506125c5565b505050505050565b61260381612c6c565b61260d8184612cbf565b925061261882612c4c565b8060005b83811015612649578151612630878261257c565b965061263b83612c9c565b92505060018101905061261c565b505050505050565b61265a81612c61565b6126648184612cb4565b925061266f82612c42565b8060005b838110156126a0578151612687878261257c565b965061269283612c8f565b925050600181019050612673565b505050505050565b6126b181612d17565b82525050565b6126c081612d3b565b82525050565b60006126d182612c77565b6126db8185612cca565b93506126eb818560208601612d5f565b6126f481612d92565b840191505092915050565b600061270c601a83612cca565b91507f68616e646c654465706f736974456e643a2062616420726f6c650000000000006000830152602082019050919050565b600061274c602683612cca565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006127b2601b83612cca565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b60006127f2602183612cca565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612858602083612cca565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000612898601b83612cca565b91507f636c61696d416c6c4469766964656e64733a2062616420726f6c6500000000006000830152602082019050919050565b60006128d8602483612cca565b91507f6173736573735265666572616c4465706f7369745265776172643a206261642060008301527f726f6c65000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b61293a81612d0d565b82525050565b61294981612d0d565b82525050565b60006020820190506129646000830184612594565b92915050565b600060408201905061297f6000830185612594565b61298c6020830184612594565b9392505050565b60006040820190506129a86000830185612594565b6129b56020830184612940565b9392505050565b6000610120820190506129d260008301846125a3565b92915050565b60006060820190506129ed60008301846125fa565b92915050565b6000602082019050612a0860008301846126a8565b92915050565b6000602082019050612a2360008301846126b7565b92915050565b60006020820190508181036000830152612a4381846126c6565b905092915050565b60006020820190508181036000830152612a64816126ff565b9050919050565b60006020820190508181036000830152612a848161273f565b9050919050565b60006020820190508181036000830152612aa4816127a5565b9050919050565b60006020820190508181036000830152612ac4816127e5565b9050919050565b60006020820190508181036000830152612ae48161284b565b9050919050565b60006020820190508181036000830152612b048161288b565b9050919050565b60006020820190508181036000830152612b24816128cb565b9050919050565b6000602082019050612b406000830184612940565b92915050565b6000606082019050612b5b6000830186612940565b612b686020830185612940565b612b756040830184612940565b949350505050565b6000604051905081810181811067ffffffffffffffff82111715612ba057600080fd5b8060405250919050565b600067ffffffffffffffff821115612bc157600080fd5b602082029050602081019050919050565b600067ffffffffffffffff821115612be957600080fd5b602082029050919050565b600067ffffffffffffffff821115612c0b57600080fd5b602082029050919050565b600067ffffffffffffffff821115612c2d57600080fd5b602082029050919050565b6000819050919050565b6000819050919050565b6000819050919050565b600060039050919050565b600060039050919050565b600060039050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600081905092915050565b600081905092915050565b600082825260208201905092915050565b6000612ce682612ced565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000612d2282612d29565b9050919050565b6000612d3482612ced565b9050919050565b6000612d4682612d4d565b9050919050565b6000612d5882612ced565b9050919050565b60005b83811015612d7d578082015181840152602081019050612d62565b83811115612d8c576000848401525b50505050565b6000601f19601f8301169050919050565b612dac81612cdb565b8114612db757600080fd5b50565b612dc381612d0d565b8114612dce57600080fd5b5056fea2646970667358221220b11dce3d30a8fbdbf1e272ace4d6f82da3671ebd3fc7734db9a49ccbba9feda164736f6c63430006020033000000000000000000000000be3c393fb670f0a29c3f3e660ffb113200e366760000000000000000000000003c58b7e291454e749b242f23a7a6a8a9f4dddde9000000000000000000000000e5c23851bbde700414beb3ab2d2ae7063c8d9c72
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101e55760003560e01c8063715018a61161010f578063c00007b0116100a2578063eeb58da511610071578063eeb58da514610879578063f2fde38b146108bd578063f6be71d114610901578063fc0c546a1461092f576101e5565b8063c00007b0146107c7578063c04637111461081f578063d54ad2a11461083d578063e627f2db1461085b576101e5565b8063abdc8054116100de578063abdc8054146106cf578063acec338a14610711578063adcfa77314610741578063b43b6d481461076f576101e5565b8063715018a6146106135780638b0e9f3f1461061d5780638da5cb5b1461063b578063995deaba14610685576101e5565b80632ee40908116101875780634da63f8f116101565780634da63f8f146104bb5780634f41e95d1461051f57806366442a061461053d5780636e9c931c146105bb576101e5565b80632ee40908146103b9578063379607f5146104075780634709384f146104355780634d597e7614610463576101e5565b80631e9b3a92116101c35780631e9b3a92146102e257806322f3e2d4146103005780632726b506146103225780632e17de781461038b576101e5565b80630fb5a6b4146101ea57806316ad0f6d146102085780631959a00214610260575b600080fd5b6101f2610979565b6040518082815260200191505060405180910390f35b61024a6004803603602081101561021e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061097f565b6040518082815260200191505060405180910390f35b6102a26004803603602081101561027657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109cb565b6040518088815260200187815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390f35b6102ea610a0d565b6040518082815260200191505060405180910390f35b610308610a6b565b604051808215151515815260200191505060405180910390f35b61036e6004803603604081101561033857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a7e565b604051808381526020018281526020019250505060405180910390f35b6103b7600480360360208110156103a157600080fd5b8101908080359060200190929190505050610b13565b005b610405600480360360408110156103cf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e0c565b005b6104336004803603602081101561041d57600080fd5b8101908080359060200190929190505050610f99565b005b6104616004803603602081101561044b57600080fd5b8101908080359060200190929190505050610fb1565b005b6104a56004803603602081101561047957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fbe565b6040518082815260200191505060405180910390f35b610509600480360360408110156104d157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050610fd6565b6040518082815260200191505060405180910390f35b6105276111ee565b6040518082815260200191505060405180910390f35b6105896004803603604081101561055357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506111f4565b604051808481526020018381526020018260028111156105a557fe5b60ff168152602001935050505060405180910390f35b610611600480360360608110156105d157600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611245565b005b61061b611256565b005b6106256113de565b6040518082815260200191505060405180910390f35b6106436113e4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61068d61140d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106fb600480360360208110156106e557600080fd5b8101908080359060200190929190505050611433565b6040518082815260200191505060405180910390f35b61073f6004803603602081101561072757600080fd5b81019080803515159060200190929190505050611495565b005b61076d6004803603602081101561075757600080fd5b810190808035906020019092919050505061157b565b005b6107b16004803603602081101561078557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061164e565b6040518082815260200191505060405180910390f35b610809600480360360208110156107dd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117a4565b6040518082815260200191505060405180910390f35b610827611811565b6040518082815260200191505060405180910390f35b610845611817565b6040518082815260200191505060405180910390f35b61086361181d565b6040518082815260200191505060405180910390f35b6108bb6004803603602081101561088f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061186e565b005b6108ff600480360360208110156108d357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061197b565b005b61092d6004803603602081101561091757600080fd5b8101908080359060200190929190505050611b88565b005b610937611c5b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60035481565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b60096020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154905087565b6000610a66670de0b6b3a7640000610a58600454610a4a600554610a3c60075442611c8190919063ffffffff16565b611ccb90919063ffffffff16565b611ccb90919063ffffffff16565b611d5190919063ffffffff16565b905090565b600860009054906101000a900460ff1681565b600080610a89612e26565b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060070160008581526020019081526020016000206040518060400160405290816000820154815260200160018201548152505090508060000151816020015192509250509250929050565b610b1c33611d9b565b6000600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000821415610b7057806000015491505b610b87828260000154611c8190919063ffffffff16565b8160000181905550610ba6828260010154611e8990919063ffffffff16565b8160010181905550610bc382600554611c8190919063ffffffff16565b6005819055506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180606001604052806203f4804201815260200185815260200160016002811115610c7857fe5b8152509080600181540180825580915050600190039060005260206000209060030201600090919091909150600082015181600001556020820151816001015560408201518160020160006101000a81548160ff02191690836002811115610cdc57fe5b021790555050503373ffffffffffffffffffffffffffffffffffffffff167f7a64d79878509820925daa6339976afdd4e1c50dc32bfae6820dd5792bd306a782856203f480420160405180848152602001838152602001828152602001935050505060405180910390a2600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634dc0d7c733856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015610def57600080fd5b505af1158015610e03573d6000803e3d6000fd5b50505050505050565b600073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b0f0f2f846040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610ec357600080fd5b505afa158015610ed7573d6000803e3d6000fd5b505050506040513d6020811015610eed57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161415610f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f7374616b65466f723a20726566657272616c2069736e2774207365740000000081525060200191505060405180910390fd5b610f958282600080611f11565b5050565b610fa233611d9b565b610fae338260006120e6565b50565b610fbb33826123fb565b50565b600b6020528060005260406000206000915090505481565b600080600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061108b611078670de0b6b3a764000061106a60045461105c866000015461104e886004015442611c8190919063ffffffff16565b611ccb90919063ffffffff16565b611ccb90919063ffffffff16565b611d5190919063ffffffff16565b8260030154611e8990919063ffffffff16565b915082156111e7576000600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110156111e5576000600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061116e57fe5b906000526020600020906003020190504281600001541080156111b857506001600281111561119957fe5b8160020160009054906101000a900460ff1660028111156111b657fe5b145b156111d7576111d4816001015485611e8990919063ffffffff16565b93505b5080806001019150506110d8565b505b5092915050565b60045481565b600a602052816000526040600020818154811061120d57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900460ff16905083565b61125133848484611f11565b505050565b61125e61277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461131f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60055481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061148e670de0b6b3a7640000611480600454611472600554611464600754894201611c8190919063ffffffff16565b611ccb90919063ffffffff16565b611ccb90919063ffffffff16565b611d5190919063ffffffff16565b9050919050565b61149d61277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461155e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600860006101000a81548160ff02191690831515021790555050565b61158361277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611644576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8060048190555050565b600080600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905081101561179e576000600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061172a57fe5b9060005260206000209060030201905042816000015410801561177457506001600281111561175557fe5b8160020160009054906101000a900460ff16600281111561177257fe5b145b156117905761178d600184611e8990919063ffffffff16565b92505b508080600101915050611694565b50919050565b600080600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506118096117f6846000610fd6565b8260020154611e8990919063ffffffff16565b915050919050565b60075481565b60065481565b6000611869670de0b6b3a764000061185b60065461184d61183c610a0d565b600654611e8990919063ffffffff16565b611c8190919063ffffffff16565b611d5190919063ffffffff16565b905090565b61187661277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611937576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61198361277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611a44576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611aca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612e416026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611b9061277c565b73ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8060038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611cc383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612784565b905092915050565b600080831415611cde5760009050611d4b565b6000828402905082848281611cef57fe5b0414611d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612e676021913960400191505060405180910390fd5b809150505b92915050565b6000611d9383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612844565b905092915050565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905042816004015410611def5750611e86565b6000611e32600454611e248460000154611e16866004015442611c8190919063ffffffff16565b611ccb90919063ffffffff16565b611ccb90919063ffffffff16565b90506000611e51670de0b6b3a764000083611d5190919063ffffffff16565b905042600781905550611e71818460030154611e8990919063ffffffff16565b83600301819055504283600401819055505050505b50565b600080828401905083811015611f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600860009054906101000a900460ff16611f93576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f7374616b653a206973207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b611f9c84611d9b565b60008311156120ca57600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561208257600080fd5b505af1158015612096573d6000803e3d6000fd5b505050506040513d60208110156120ac57600080fd5b8101908080519060200190929190505050506120c984848461290a565b5b60008111156120e0576120df848260016120e6565b5b50505050565b6000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600083141561213a57806003015492505b82816003015410156121b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f636c61696d3a20696e73756666696369656e742072657761726473000000000081525060200191505060405180910390fd5b6121cb838260030154611c8190919063ffffffff16565b81600301819055506121ea838260020154611e8990919063ffffffff16565b816002018190555061220783600654611e8990919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486846040518082815260200191505060405180910390a2811561233357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561230a57600080fd5b505af115801561231e573d6000803e3d6000fd5b5050505061232e8484600061290a565b6123f5565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1985856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b1580156123dc57600080fd5b505af11580156123f0573d6000803e3d6000fd5b505050505b50505050565b600081146124a5576124a0600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905061249b83600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611e8990919063ffffffff16565b612b52565b6124e9565b600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490505b90506000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b81811015612777576000600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061258457fe5b906000526020600020906003020190504281600001541080156125ce5750600160028111156125af57fe5b8160020160009054906101000a900460ff1660028111156125cc57fe5b145b156127695760028160020160006101000a81548160ff021916908360028111156125f457fe5b02179055506000600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061265782600101548260010154611c8190919063ffffffff16565b816001018190555061266d858360010154612b6b565b828573ffffffffffffffffffffffffffffffffffffffff167fe08737ac48a1dab4b1a46c7dc9398bd5bfc6d7ad6fabb7cd8caa254de14def35846001015460004260405180848152602001838152602001828152602001935050505060405180910390a36127246001600b60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611e8990919063ffffffff16565b600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b508080600101915050612530565b505050565b600033905090565b6000838311158290612831576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156127f65780820151818401526020810190506127db565b50505050905090810190601f1680156128235780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080831182906128f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156128b557808201518184015260208101905061289a565b50505050905090810190601f1680156128e25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816128fc57fe5b049050809150509392505050565b6000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050612964838260000154611e8990919063ffffffff16565b816000018190555061298183600554611e8990919063ffffffff16565b6005819055506040518060400160405280848152602001600354420181525081600701600083600601548152602001908152602001600020600082015181600001556020820151816001015590505080600601548473ffffffffffffffffffffffffffffffffffffffff167f7162984403f6c73c8639375d45a9187dfd04602231bd8e587c415718b5f7e5f98542600354420160405180848152602001838152602001828152602001935050505060405180910390a3612a4f60018260060154611e8990919063ffffffff16565b8160060181905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a6535fd28584866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015612b3457600080fd5b505af1158015612b48573d6000803e3d6000fd5b5050505050505050565b6000818310612b615781612b63565b825b905092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612c0c57600080fd5b505afa158015612c20573d6000803e3d6000fd5b505050506040513d6020811015612c3657600080fd5b8101908080519060200190929190505050905080821115612d3b57600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612cfa57600080fd5b505af1158015612d0e573d6000803e3d6000fd5b505050506040513d6020811015612d2457600080fd5b810190808051906020019092919050505050612e21565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612de457600080fd5b505af1158015612df8573d6000803e3d6000fd5b505050506040513d6020811015612e0e57600080fd5b8101908080519060200190929190505050505b505050565b60405180604001604052806000815260200160008152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220bde1651ceae600efa54b41620e732efc1fffc64dd202082d681d275315bf356f64736f6c63430006020033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000be3c393fb670f0a29c3f3e660ffb113200e366760000000000000000000000003c58b7e291454e749b242f23a7a6a8a9f4dddde9000000000000000000000000e5c23851bbde700414beb3ab2d2ae7063c8d9c72
-----Decoded View---------------
Arg [0] : _token (address): 0xbE3c393Fb670f0A29C3F3E660FFB113200e36676
Arg [1] : _rewards (address): 0x3C58B7E291454e749B242F23A7A6a8A9f4dddDe9
Arg [2] : _referralTree (address): 0xe5C23851Bbde700414BeB3Ab2D2aE7063c8D9C72
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000be3c393fb670f0a29c3f3e660ffb113200e36676
Arg [1] : 0000000000000000000000003c58b7e291454e749b242f23a7a6a8a9f4dddde9
Arg [2] : 000000000000000000000000e5c23851bbde700414beb3ab2d2ae7063c8d9c72
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.