ERC-20
Overview
Max Total Supply
1,000,000,000 FBTC
Holders
7
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 8 Decimals)
Balance
30,010,000 FBTCValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
FBTC
Compiler Version
v0.5.13+commit.5b0b510c
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.5.13; import "./StakeableToken.sol"; import "openzeppelin-solidity/contracts/access/Roles.sol"; contract FBTC is StakeableToken { using Roles for Roles.Role; Roles.Role private _minters; constructor() public { globals.shareRate = uint40(1 * SHARE_RATE_SCALE); _minters.add(ORIGIN_ADDR); _mint(FAUCET_ADDR, FAUCET_MINT); _mint(LLC_ADDR, LLC_MINT); _mint(XP_ADDR, XP_MINT); _mint(BAC_ADDR, BAY_MINT); } function mint(address to, uint256 amount) public { // Only minters can mint require(_minters.has(msg.sender), "DOES_NOT_HAVE_MINTER_ROLE"); _mint(to, amount); } }
pragma solidity ^0.5.13; import "./GlobalsAndUtility.sol"; contract StakeableToken is GlobalsAndUtility { /** * @dev PUBLIC FACING: Open a stake. * @param newStakedHearts Number of Hearts to stake * @param newStakedDays Number of days to stake */ function stakeStart(uint256 newStakedHearts, uint256 newStakedDays) external { GlobalsCache memory g; GlobalsCache memory gSnapshot; _globalsLoad(g, gSnapshot); /* Enforce the minimum stake time */ require(newStakedDays >= MIN_STAKE_DAYS, "FREE: newStakedDays lower than minimum"); /* Check if log data needs to be updated */ _dailyDataUpdateAuto(g); _stakeStart(g, newStakedHearts, newStakedDays); /* Remove staked Hearts from balance of staker */ _burn(msg.sender, newStakedHearts); _globalsSync(g, gSnapshot); } /** * @dev PUBLIC FACING: Unlocks a completed stake, distributing the proceeds of any penalty * immediately. The staker must still call stakeEnd() to retrieve their stake return (if any). * @param stakerAddr Address of staker * @param stakeIndex Index of stake within stake list * @param stakeIdParam The stake's id */ function stakeGoodAccounting(address stakerAddr, uint256 stakeIndex, uint40 stakeIdParam) external { GlobalsCache memory g; GlobalsCache memory gSnapshot; _globalsLoad(g, gSnapshot); /* require() is more informative than the default assert() */ require(stakeLists[stakerAddr].length != 0, "FREE: Empty stake list"); require(stakeIndex < stakeLists[stakerAddr].length, "FREE: stakeIndex invalid"); StakeStore storage stRef = stakeLists[stakerAddr][stakeIndex]; /* Get stake copy */ StakeCache memory st; _stakeLoad(stRef, stakeIdParam, st); /* Stake must have served full term */ require(g._currentDay >= st._lockedDay + st._stakedDays, "FREE: Stake not fully served"); /* Stake must still be locked */ require(st._unlockedDay == 0, "FREE: Stake already unlocked"); /* Check if log data needs to be updated */ _dailyDataUpdateAuto(g); /* Unlock the completed stake */ _stakeUnlock(g, st); /* stakeReturn value is unused here */ (, uint256 payout, uint256 penalty, uint256 cappedPenalty) = _stakePerformance( g, st, st._stakedDays ); _emitStakeGoodAccounting( stakerAddr, stakeIdParam, st._stakedHearts, st._stakeShares, payout, penalty ); if (cappedPenalty != 0) { _splitPenaltyProceeds(g, cappedPenalty); } /* st._unlockedDay has changed */ _stakeUpdate(stRef, st); _globalsSync(g, gSnapshot); } /** * @dev PUBLIC FACING: Closes a stake. The order of the stake list can change so * a stake id is used to reject stale indexes. * @param stakeIndex Index of stake within stake list * @param stakeIdParam The stake's id */ function stakeEnd(uint256 stakeIndex, uint40 stakeIdParam) external { GlobalsCache memory g; GlobalsCache memory gSnapshot; _globalsLoad(g, gSnapshot); StakeStore[] storage stakeListRef = stakeLists[msg.sender]; /* require() is more informative than the default assert() */ require(stakeListRef.length != 0, "FREE: Empty stake list"); require(stakeIndex < stakeListRef.length, "FREE: stakeIndex invalid"); /* Get stake copy */ StakeCache memory st; _stakeLoad(stakeListRef[stakeIndex], stakeIdParam, st); /* Check if log data needs to be updated */ _dailyDataUpdateAuto(g); uint256 servedDays = 0; bool prevUnlocked = (st._unlockedDay != 0); uint256 stakeReturn; uint256 payout = 0; uint256 penalty = 0; uint256 cappedPenalty = 0; if (g._currentDay >= st._lockedDay) { if (prevUnlocked) { /* Previously unlocked in stakeGoodAccounting(), so must have served full term */ servedDays = st._stakedDays; } else { _stakeUnlock(g, st); servedDays = g._currentDay - st._lockedDay; if (servedDays > st._stakedDays) { servedDays = st._stakedDays; } } (stakeReturn, payout, penalty, cappedPenalty) = _stakePerformance(g, st, servedDays); } else { /* Stake hasn't been added to the total yet, so no penalties or rewards apply */ g._nextStakeSharesTotal -= st._stakeShares; stakeReturn = st._stakedHearts; } _emitStakeEnd( stakeIdParam, st._stakedHearts, st._stakeShares, payout, penalty, servedDays, prevUnlocked ); if (cappedPenalty != 0 && !prevUnlocked) { /* Split penalty proceeds only if not previously unlocked by stakeGoodAccounting() */ _splitPenaltyProceeds(g, cappedPenalty); } /* Pay the stake return, if any, to the staker */ if (stakeReturn != 0) { _mint(msg.sender, stakeReturn); /* Update the share rate if necessary */ _shareRateUpdate(g, st, stakeReturn); } g._lockedHeartsTotal -= st._stakedHearts; _stakeRemove(stakeListRef, stakeIndex); _globalsSync(g, gSnapshot); } /** * @dev PUBLIC FACING: Return the current stake count for a staker address * @param stakerAddr Address of staker */ function stakeCount(address stakerAddr) external view returns (uint256) { return stakeLists[stakerAddr].length; } /** * @dev Open a stake. * @param g Cache of stored globals * @param newStakedHearts Number of Hearts to stake * @param newStakedDays Number of days to stake */ function _stakeStart( GlobalsCache memory g, uint256 newStakedHearts, uint256 newStakedDays ) internal { /* Enforce the maximum stake time */ require(newStakedDays <= MAX_STAKE_DAYS, "FREE: newStakedDays higher than maximum"); uint256 bonusHearts = _stakeStartBonusHearts(newStakedHearts, newStakedDays); uint256 newStakeShares = (newStakedHearts + bonusHearts) * SHARE_RATE_SCALE / g._shareRate; /* Ensure newStakedHearts is enough for at least one stake share */ require(newStakeShares != 0, "FREE: newStakedHearts must be at least minimum shareRate"); /* The stakeStart timestamp will always be part-way through the current day, so it needs to be rounded-up to the next day to ensure all stakes align with the same fixed calendar days. The current day is already rounded-down, so rounded-up is current day + 1. */ uint256 newLockedDay = g._currentDay + 1; /* Create Stake */ uint40 newStakeId = ++g._latestStakeId; _stakeAdd( stakeLists[msg.sender], newStakeId, newStakedHearts, newStakeShares, newLockedDay, newStakedDays ); _emitStakeStart(newStakeId, newStakedHearts, newStakeShares, newStakedDays); /* Stake is added to total in the next round, not the current round */ g._nextStakeSharesTotal += newStakeShares; /* Track total staked Hearts for inflation calculations */ g._lockedHeartsTotal += newStakedHearts; } /** * @dev Calculates total stake payout including rewards for a multi-day range * @param stakeSharesParam Param from stake to calculate bonuses for * @param beginDay First day to calculate bonuses for * @param endDay Last day (non-inclusive) of range to calculate bonuses for * @return Payout in Hearts */ function _calcPayoutRewards( uint256 stakeSharesParam, uint256 beginDay, uint256 endDay ) private view returns (uint256 payout) { for (uint256 day = beginDay; day < endDay; day++) { payout += dailyData[day].dayPayoutTotal * stakeSharesParam / dailyData[day].dayStakeSharesTotal; } return payout; } /** * @dev Calculate bonus Hearts for a new stake, if any * @param newStakedHearts Number of Hearts to stake * @param newStakedDays Number of days to stake */ function _stakeStartBonusHearts(uint256 newStakedHearts, uint256 newStakedDays) private pure returns (uint256 bonusHearts) { /* LONGER PAYS BETTER: If longer than 1 day stake is committed to, each extra day gives bonus shares of approximately 0.0548%, which is approximately 20% extra per year of increased stake length committed to, but capped to a maximum of 200% extra. extraDays = stakedDays - 1 longerBonus% = (extraDays / 364) * 20% = (extraDays / 364) / 5 = extraDays / 1820 = extraDays / LPB extraDays = longerBonus% * 1820 extraDaysMax = longerBonusMax% * 1820 = 200% * 1820 = 3640 = LPB_MAX_DAYS BIGGER PAYS BETTER: Bonus percentage scaled 0% to 10% for the first 150M FREE of stake. biggerBonus% = (cappedHearts / BPB_MAX_HEARTS) * 10% = (cappedHearts / BPB_MAX_HEARTS) / 10 = cappedHearts / (BPB_MAX_HEARTS * 10) = cappedHearts / BPB COMBINED: combinedBonus% = longerBonus% + biggerBonus% cappedExtraDays cappedHearts = --------------- + ------------ LPB BPB cappedExtraDays * BPB cappedHearts * LPB = --------------------- + ------------------ LPB * BPB LPB * BPB cappedExtraDays * BPB + cappedHearts * LPB = -------------------------------------------- LPB * BPB bonusHearts = hearts * combinedBonus% = hearts * (cappedExtraDays * BPB + cappedHearts * LPB) / (LPB * BPB) */ uint256 cappedExtraDays = 0; /* Must be more than 1 day for Longer-Pays-Better */ if (newStakedDays > 1) { cappedExtraDays = newStakedDays <= LPB_MAX_DAYS ? newStakedDays - 1 : LPB_MAX_DAYS; } uint256 cappedStakedHearts = newStakedHearts <= BPB_MAX_HEARTS ? newStakedHearts : BPB_MAX_HEARTS; bonusHearts = cappedExtraDays * BPB + cappedStakedHearts * LPB; bonusHearts = newStakedHearts * bonusHearts / (LPB * BPB); return bonusHearts; } function _stakeUnlock(GlobalsCache memory g, StakeCache memory st) private pure { g._stakeSharesTotal -= st._stakeShares; st._unlockedDay = g._currentDay; } function _stakePerformance(GlobalsCache memory g, StakeCache memory st, uint256 servedDays) private view returns (uint256 stakeReturn, uint256 payout, uint256 penalty, uint256 cappedPenalty) { if (servedDays < st._stakedDays) { (payout, penalty) = _calcPayoutAndEarlyPenalty( g, st._lockedDay, st._stakedDays, servedDays, st._stakeShares ); stakeReturn = st._stakedHearts + payout; } else { // servedDays must == stakedDays here payout = _calcPayoutRewards( st._stakeShares, st._lockedDay, st._lockedDay + servedDays ); stakeReturn = st._stakedHearts + payout; penalty = _calcLatePenalty(st._lockedDay, st._stakedDays, st._unlockedDay, stakeReturn); } if (penalty != 0) { if (penalty > stakeReturn) { /* Cannot have a negative stake return */ cappedPenalty = stakeReturn; stakeReturn = 0; } else { /* Remove penalty from the stake return */ cappedPenalty = penalty; stakeReturn -= cappedPenalty; } } return (stakeReturn, payout, penalty, cappedPenalty); } function _calcPayoutAndEarlyPenalty( GlobalsCache memory g, uint256 lockedDayParam, uint256 stakedDaysParam, uint256 servedDays, uint256 stakeSharesParam ) private view returns (uint256 payout, uint256 penalty) { uint256 servedEndDay = lockedDayParam + servedDays; /* 50% of stakedDays (rounded up) with a minimum applied */ uint256 penaltyDays = (stakedDaysParam + 1) / 2; if (penaltyDays < EARLY_PENALTY_MIN_DAYS) { penaltyDays = EARLY_PENALTY_MIN_DAYS; } if (servedDays == 0) { /* Fill penalty days with the estimated average payout */ uint256 expected = _estimatePayoutRewardsDay(g, stakeSharesParam); penalty = expected * penaltyDays; return (payout, penalty); // Actual payout was 0 } if (penaltyDays < servedDays) { /* Simplified explanation of intervals where end-day is non-inclusive: penalty: [lockedDay ... penaltyEndDay) delta: [penaltyEndDay ... servedEndDay) payout: [lockedDay ....................... servedEndDay) */ uint256 penaltyEndDay = lockedDayParam + penaltyDays; penalty = _calcPayoutRewards(stakeSharesParam, lockedDayParam, penaltyEndDay); uint256 delta = _calcPayoutRewards(stakeSharesParam, penaltyEndDay, servedEndDay); payout = penalty + delta; return (payout, penalty); } /* penaltyDays >= servedDays */ payout = _calcPayoutRewards(stakeSharesParam, lockedDayParam, servedEndDay); if (penaltyDays == servedDays) { penalty = payout; } else { /* (penaltyDays > servedDays) means not enough days served, so fill the penalty days with the average payout from only the days that were served. */ penalty = payout * penaltyDays / servedDays; } return (payout, penalty); } function _calcLatePenalty( uint256 lockedDayParam, uint256 stakedDaysParam, uint256 unlockedDayParam, uint256 rawStakeReturn ) private pure returns (uint256) { /* Allow grace time before penalties accrue */ uint256 maxUnlockedDay = lockedDayParam + stakedDaysParam + LATE_PENALTY_GRACE_DAYS; if (unlockedDayParam <= maxUnlockedDay) { return 0; } /* Calculate penalty as a percentage of stake return based on time */ return rawStakeReturn * (unlockedDayParam - maxUnlockedDay) / LATE_PENALTY_SCALE_DAYS; } function _splitPenaltyProceeds(GlobalsCache memory g, uint256 penalty) private { /* Split a penalty 50:50 between Origin and stakePenaltyTotal */ uint256 splitPenalty = penalty / 2; if (splitPenalty != 0) { _mint(ORIGIN_ADDR, splitPenalty); } /* Use the other half of the penalty to account for an odd-numbered penalty */ splitPenalty = penalty - splitPenalty; g._stakePenaltyTotal += splitPenalty; } function _shareRateUpdate(GlobalsCache memory g, StakeCache memory st, uint256 stakeReturn) private { if (stakeReturn > st._stakedHearts) { /* Calculate the new shareRate that would yield the same number of shares if the user re-staked this stakeReturn, factoring in any bonuses they would receive in stakeStart(). */ uint256 bonusHearts = _stakeStartBonusHearts(stakeReturn, st._stakedDays); uint256 newShareRate = (stakeReturn + bonusHearts) * SHARE_RATE_SCALE / st._stakeShares; if (newShareRate > SHARE_RATE_MAX) { /* Realistically this can't happen, but there are contrived theoretical scenarios that can lead to extreme values of newShareRate, so it is capped to prevent them anyway. */ newShareRate = SHARE_RATE_MAX; } if (newShareRate > g._shareRate) { g._shareRate = newShareRate; _emitShareRateChange(newShareRate, st._stakeId); } } } function _emitStakeStart( uint40 stakeId, uint256 stakedHearts, uint256 stakeShares, uint256 stakedDays ) private { emit StakeStart( // (auto-generated event) uint256(uint40(block.timestamp)) | (uint256(uint72(stakedHearts)) << 40) | (uint256(uint72(stakeShares)) << 112) | (uint256(uint16(stakedDays)) << 184), msg.sender, stakeId ); } function _emitStakeGoodAccounting( address stakerAddr, uint40 stakeId, uint256 stakedHearts, uint256 stakeShares, uint256 payout, uint256 penalty ) private { emit StakeGoodAccounting( // (auto-generated event) uint256(uint40(block.timestamp)) | (uint256(uint72(stakedHearts)) << 40) | (uint256(uint72(stakeShares)) << 112) | (uint256(uint72(payout)) << 184), uint256(uint72(penalty)), stakerAddr, stakeId, msg.sender ); } function _emitStakeEnd( uint40 stakeId, uint256 stakedHearts, uint256 stakeShares, uint256 payout, uint256 penalty, uint256 servedDays, bool prevUnlocked ) private { emit StakeEnd( // (auto-generated event) uint256(uint40(block.timestamp)) | (uint256(uint72(stakedHearts)) << 40) | (uint256(uint72(stakeShares)) << 112) | (uint256(uint72(payout)) << 184), uint256(uint72(penalty)) | (uint256(uint16(servedDays)) << 72) | (prevUnlocked ? (1 << 88) : 0), msg.sender, stakeId ); } function _emitShareRateChange(uint256 shareRate, uint40 stakeId) private { emit ShareRateChange( // (auto-generated event) uint256(uint40(block.timestamp)) | (uint256(uint40(shareRate)) << 40), stakeId ); } }
pragma solidity ^0.5.0; /** * @title Roles * @dev Library for managing addresses assigned to a Role. */ library Roles { struct Role { mapping (address => bool) bearer; } /** * @dev Give an account access to this role. */ function add(Role storage role, address account) internal { require(!has(role, account), "Roles: account already has role"); role.bearer[account] = true; } /** * @dev Remove an account's access to this role. */ function remove(Role storage role, address account) internal { require(has(role, account), "Roles: account does not have role"); role.bearer[account] = false; } /** * @dev Check if an account has this role. * @return bool */ function has(Role storage role, address account) internal view returns (bool) { require(account != address(0), "Roles: account is the zero address"); return role.bearer[account]; } }
pragma solidity ^0.5.13; import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; contract GlobalsAndUtility is ERC20 { /* Define events */ /* DailyDataUpdate (auto-generated event) uint40 timestamp --> data0 [ 39: 0] uint16 beginDay --> data0 [ 55: 40] uint16 endDay --> data0 [ 71: 56] bool isAutoUpdate --> data0 [ 79: 72] address indexed updaterAddr */ event DailyDataUpdate( uint256 data0, address indexed updaterAddr ); /* StakeStart (auto-generated event) uint40 timestamp --> data0 [ 39: 0] address indexed stakerAddr uint40 indexed stakeId uint72 stakedHearts --> data0 [111: 40] uint72 stakeShares --> data0 [183:112] uint16 stakedDays --> data0 [199:184] */ event StakeStart( uint256 data0, address indexed stakerAddr, uint40 indexed stakeId ); /* StakeGoodAccounting(auto-generated event) uint40 timestamp --> data0 [ 39: 0] address indexed stakerAddr uint40 indexed stakeId uint72 stakedHearts --> data0 [111: 40] uint72 stakeShares --> data0 [183:112] uint72 payout --> data0 [255:184] uint72 penalty --> data1 [ 71: 0] address indexed senderAddr */ event StakeGoodAccounting( uint256 data0, uint256 data1, address indexed stakerAddr, uint40 indexed stakeId, address indexed senderAddr ); /* StakeEnd (auto-generated event) uint40 timestamp --> data0 [ 39: 0] address indexed stakerAddr uint40 indexed stakeId uint72 stakedHearts --> data0 [111: 40] uint72 stakeShares --> data0 [183:112] uint72 payout --> data0 [255:184] uint72 penalty --> data1 [ 71: 0] uint16 servedDays --> data1 [ 87: 72] bool prevUnlocked --> data1 [ 95: 88] */ event StakeEnd( uint256 data0, uint256 data1, address indexed stakerAddr, uint40 indexed stakeId ); /* ShareRateChange (auto-generated event) uint40 timestamp --> data0 [ 39: 0] uint40 shareRate --> data0 [ 79: 40] uint40 indexed stakeId */ event ShareRateChange( uint256 data0, uint40 indexed stakeId ); /* Origin address */ address internal constant ORIGIN_ADDR = 0xB8cF11B8De281560884b4A23Efd69D9aACBf3f4d; /* DIST addresses */ address internal constant FAUCET_ADDR = 0xc3D6E20cC4D492c4B0b84312Fb5d730D03278222; /* 50% */ address internal constant LLC_ADDR = 0xAef2989e6A23982D93d83F91378d17ec31662bd1; /* 40% */ address internal constant XP_ADDR = 0xB8cF11B8De281560884b4A23Efd69D9aACBf3f4d; /* 5% */ address internal constant BAC_ADDR = 0x2D38F017eC55858583d0dB5f6088acbfE0a39808; /* 5% */ /* 1B total initial distrubution */ uint256 internal constant FAUCET_MINT = 50000000000000000; uint256 internal constant LLC_MINT = 40000000000000000; uint256 internal constant XP_MINT = 5000000000000000; uint256 internal constant BAY_MINT = 5000000000000000; /* ERC20 constants */ string public constant name = "FreeBitcoins Token"; string public constant symbol = "FBTC"; uint8 public constant decimals = 8; /* Hearts per Satoshi = 10,000 * 1e8 / 1e8 = 1e4 */ uint256 private constant HEARTS_PER_FBTC = 10 ** uint256(decimals); // 1e8 /* Time of contract launch (2019-03-04T00:00:00Z) */ uint256 internal constant LAUNCH_TIME = 1627603200000; /* Size of a Hearts or Shares uint */ uint256 internal constant HEART_UINT_SIZE = 72; /* Stake timing parameters */ uint256 internal constant MIN_STAKE_DAYS = 1; uint256 internal constant MAX_STAKE_DAYS = 5555; // Approx 15 years uint256 internal constant EARLY_PENALTY_MIN_DAYS = 90; uint256 private constant LATE_PENALTY_GRACE_WEEKS = 2; uint256 internal constant LATE_PENALTY_GRACE_DAYS = LATE_PENALTY_GRACE_WEEKS * 7; uint256 private constant LATE_PENALTY_SCALE_WEEKS = 100; uint256 internal constant LATE_PENALTY_SCALE_DAYS = LATE_PENALTY_SCALE_WEEKS * 7; /* Stake shares Longer Pays Better bonus constants used by _stakeStartBonusHearts() */ uint256 private constant LPB_BONUS_PERCENT = 20; uint256 private constant LPB_BONUS_MAX_PERCENT = 200; uint256 internal constant LPB = 364 * 100 / LPB_BONUS_PERCENT; uint256 internal constant LPB_MAX_DAYS = LPB * LPB_BONUS_MAX_PERCENT / 100; /* Stake shares Bigger Pays Better bonus constants used by _stakeStartBonusHearts() */ uint256 private constant BPB_BONUS_PERCENT = 10; uint256 private constant BPB_MAX_FBTC = 150 * 1e6; uint256 internal constant BPB_MAX_HEARTS = BPB_MAX_FBTC * HEARTS_PER_FBTC; uint256 internal constant BPB = BPB_MAX_HEARTS * 100 / BPB_BONUS_PERCENT; /* Share rate is scaled to increase precision */ uint256 internal constant SHARE_RATE_SCALE = 1e5; /* Share rate max (after scaling) */ uint256 internal constant SHARE_RATE_UINT_SIZE = 40; uint256 internal constant SHARE_RATE_MAX = (1 << SHARE_RATE_UINT_SIZE) - 1; /* Globals expanded for memory (except _latestStakeId) and compact for storage */ struct GlobalsCache { // 1 uint256 _lockedHeartsTotal; uint256 _nextStakeSharesTotal; uint256 _shareRate; uint256 _stakePenaltyTotal; // 2 uint256 _dailyDataCount; uint256 _stakeSharesTotal; uint40 _latestStakeId; // uint256 _currentDay; } struct GlobalsStore { // 1 uint72 lockedHeartsTotal; uint72 nextStakeSharesTotal; uint40 shareRate; uint72 stakePenaltyTotal; // 2 uint16 dailyDataCount; uint72 stakeSharesTotal; uint40 latestStakeId; } GlobalsStore public globals; /* Daily data */ struct DailyDataStore { uint72 dayPayoutTotal; uint72 dayStakeSharesTotal; } mapping(uint256 => DailyDataStore) public dailyData; /* Stake expanded for memory (except _stakeId) and compact for storage */ struct StakeCache { uint40 _stakeId; uint256 _stakedHearts; uint256 _stakeShares; uint256 _lockedDay; uint256 _stakedDays; uint256 _unlockedDay; } struct StakeStore { uint40 stakeId; uint72 stakedHearts; uint72 stakeShares; uint16 lockedDay; uint16 stakedDays; uint16 unlockedDay; } mapping(address => StakeStore[]) public stakeLists; /* Temporary state for calculating daily rounds */ struct DailyRoundState { uint256 _allocSupplyCached; uint256 _payoutTotal; } /** * @dev PUBLIC FACING: Optionally update daily data for a smaller * range to reduce gas cost for a subsequent operation * @param beforeDay Only update days before this day number (optional; 0 for current day) */ function dailyDataUpdate(uint256 beforeDay) external { GlobalsCache memory g; GlobalsCache memory gSnapshot; _globalsLoad(g, gSnapshot); if (beforeDay != 0) { require(beforeDay <= g._currentDay, "FBTC: beforeDay cannot be in the future"); _dailyDataUpdate(g, beforeDay, false); } else { /* Default to updating before current day */ _dailyDataUpdate(g, g._currentDay, false); } _globalsSync(g, gSnapshot); } /** * @dev PUBLIC FACING: External helper to return multiple values of daily data with * a single call. Ugly implementation due to limitations of the standard ABI encoder. * @param beginDay First day of data range * @param endDay Last day (non-inclusive) of data range * @return Fixed array of packed values */ function dailyDataRange(uint256 beginDay, uint256 endDay) external view returns (uint256[] memory list) { require(beginDay < endDay && endDay <= globals.dailyDataCount, "FBTC: range invalid"); list = new uint256[](endDay - beginDay); uint256 src = beginDay; uint256 dst = 0; uint256 v; do { v = uint256(dailyData[src].dayStakeSharesTotal) << HEART_UINT_SIZE; v |= uint256(dailyData[src].dayPayoutTotal); list[dst++] = v; } while (++src < endDay); return list; } /** * @dev PUBLIC FACING: External helper to return most global info with a single call. * Ugly implementation due to limitations of the standard ABI encoder. * @return Fixed array of values */ function globalInfo() external view returns (uint256[9] memory) { return [ // 1 globals.lockedHeartsTotal, globals.nextStakeSharesTotal, globals.shareRate, globals.stakePenaltyTotal, // 2 globals.dailyDataCount, globals.stakeSharesTotal, globals.latestStakeId, // block.timestamp, totalSupply() ]; } /** * @dev PUBLIC FACING: ERC20 totalSupply() is the circulating supply and does not include any * staked Hearts. allocatedSupply() includes both. * @return Allocated Supply in Hearts */ function allocatedSupply() external view returns (uint256) { return totalSupply() + globals.lockedHeartsTotal; } /** * @dev PUBLIC FACING: External helper for the current day number since launch time * @return Current day number (zero-based) */ function getCurrentDay() external view returns (uint256) { return _getCurrentDay(); } function _getCurrentDay() internal view returns (uint256) { return (block.timestamp - LAUNCH_TIME) / 1 days; } function _dailyDataUpdateAuto(GlobalsCache memory g) internal { _dailyDataUpdate(g, g._currentDay, true); } function _globalsLoad(GlobalsCache memory g, GlobalsCache memory gSnapshot) internal view { // 1 g._lockedHeartsTotal = globals.lockedHeartsTotal; g._nextStakeSharesTotal = globals.nextStakeSharesTotal; g._shareRate = globals.shareRate; g._stakePenaltyTotal = globals.stakePenaltyTotal; // 2 g._dailyDataCount = globals.dailyDataCount; g._stakeSharesTotal = globals.stakeSharesTotal; g._latestStakeId = globals.latestStakeId; // g._currentDay = _currentDay(); _globalsCacheSnapshot(g, gSnapshot); } function _globalsCacheSnapshot(GlobalsCache memory g, GlobalsCache memory gSnapshot) internal pure { // 1 gSnapshot._lockedHeartsTotal = g._lockedHeartsTotal; gSnapshot._nextStakeSharesTotal = g._nextStakeSharesTotal; gSnapshot._shareRate = g._shareRate; gSnapshot._stakePenaltyTotal = g._stakePenaltyTotal; // 2 gSnapshot._dailyDataCount = g._dailyDataCount; gSnapshot._stakeSharesTotal = g._stakeSharesTotal; gSnapshot._latestStakeId = g._latestStakeId; } function _globalsSync(GlobalsCache memory g, GlobalsCache memory gSnapshot) internal { if (g._lockedHeartsTotal != gSnapshot._lockedHeartsTotal || g._nextStakeSharesTotal != gSnapshot._nextStakeSharesTotal || g._shareRate != gSnapshot._shareRate || g._stakePenaltyTotal != gSnapshot._stakePenaltyTotal) { // 1 globals.lockedHeartsTotal = uint72(g._lockedHeartsTotal); globals.nextStakeSharesTotal = uint72(g._nextStakeSharesTotal); globals.shareRate = uint40(g._shareRate); globals.stakePenaltyTotal = uint72(g._stakePenaltyTotal); } if (g._dailyDataCount != gSnapshot._dailyDataCount || g._stakeSharesTotal != gSnapshot._stakeSharesTotal || g._latestStakeId != gSnapshot._latestStakeId) { // 2 globals.dailyDataCount = uint16(g._dailyDataCount); globals.stakeSharesTotal = uint72(g._stakeSharesTotal); globals.latestStakeId = g._latestStakeId; } } function _stakeLoad(StakeStore storage stRef, uint40 stakeIdParam, StakeCache memory st) internal view { /* Ensure caller's stakeIndex is still current */ require(stakeIdParam == stRef.stakeId, "FBTC: stakeIdParam not in stake"); st._stakeId = stRef.stakeId; st._stakedHearts = stRef.stakedHearts; st._stakeShares = stRef.stakeShares; st._lockedDay = stRef.lockedDay; st._stakedDays = stRef.stakedDays; st._unlockedDay = stRef.unlockedDay; } function _stakeUpdate(StakeStore storage stRef, StakeCache memory st) internal { stRef.stakeId = st._stakeId; stRef.stakedHearts = uint72(st._stakedHearts); stRef.stakeShares = uint72(st._stakeShares); stRef.lockedDay = uint16(st._lockedDay); stRef.stakedDays = uint16(st._stakedDays); stRef.unlockedDay = uint16(st._unlockedDay); } function _stakeAdd( StakeStore[] storage stakeListRef, uint40 newStakeId, uint256 newStakedHearts, uint256 newStakeShares, uint256 newLockedDay, uint256 newStakedDays ) internal { stakeListRef.push( StakeStore( newStakeId, uint72(newStakedHearts), uint72(newStakeShares), uint16(newLockedDay), uint16(newStakedDays), uint16(0) // unlockedDay ) ); } /** * @dev Efficiently delete from an unordered array by moving the last element * to the "hole" and reducing the array length. Can change the order of the list * and invalidate previously held indexes. * @notice stakeListRef length and stakeIndex are already ensured valid in stakeEnd() * @param stakeListRef Reference to stakeLists[stakerAddr] array in storage * @param stakeIndex Index of the element to delete */ function _stakeRemove(StakeStore[] storage stakeListRef, uint256 stakeIndex) internal { uint256 lastIndex = stakeListRef.length - 1; /* Skip the copy if element to be removed is already the last element */ if (stakeIndex != lastIndex) { /* Copy last element to the requested element's "hole" */ stakeListRef[stakeIndex] = stakeListRef[lastIndex]; } /* Reduce the array length now that the array is contiguous. Surprisingly, 'pop()' uses less gas than 'stakeListRef.length = lastIndex' */ stakeListRef.pop(); } /** * @dev Estimate the stake payout for an incomplete day * @param g Cache of stored globals * @param stakeSharesParam Param from stake to calculate bonuses for * @return Payout in Hearts */ function _estimatePayoutRewardsDay(GlobalsCache memory g, uint256 stakeSharesParam) internal view returns (uint256 payout) { /* Prevent updating state for this estimation */ GlobalsCache memory gTmp; _globalsCacheSnapshot(g, gTmp); DailyRoundState memory rs; rs._allocSupplyCached = totalSupply() + g._lockedHeartsTotal; _dailyRoundCalc(gTmp, rs); /* Stake is no longer locked so it must be added to total as if it were */ gTmp._stakeSharesTotal += stakeSharesParam; payout = rs._payoutTotal * stakeSharesParam / gTmp._stakeSharesTotal; return payout; } function _dailyRoundCalc(GlobalsCache memory g, DailyRoundState memory rs) private pure { /* Calculate payout round Inflation of 10% inflation per 364 days (approx 1 year) dailyInterestRate = exp(log(1 + 10%) / 364) - 1 = exp(log(1 + 0.1) / 364) - 1 = exp(log(1.1) / 364) - 1 = 0.000261875 (approx) payout = allocSupply * dailyInterestRate = allocSupply / (1 / dailyInterestRate) = allocSupply / (1 / 0.000261875) = allocSupply / 3818.61575179 (approx) = allocSupply * 10000 / 38186157 (* 10000/10000 for int precision) */ rs._payoutTotal = rs._allocSupplyCached * 10000 / 38186157; if (g._stakePenaltyTotal != 0) { rs._payoutTotal += g._stakePenaltyTotal; g._stakePenaltyTotal = 0; } } function _dailyRoundCalcAndStore(GlobalsCache memory g, DailyRoundState memory rs, uint256 day) private { _dailyRoundCalc(g, rs); dailyData[day].dayPayoutTotal = uint72(rs._payoutTotal); dailyData[day].dayStakeSharesTotal = uint72(g._stakeSharesTotal); } /** * @dev PUBLIC FACING: External helper for the current day number since launch time * @return Current day number (zero-based) */ function currentDay() external view returns (uint256) { return _currentDay(); } function _currentDay() internal view returns (uint256) { return (block.timestamp - LAUNCH_TIME) / 1 days; } function _dailyDataUpdate(GlobalsCache memory g, uint256 beforeDay, bool isAutoUpdate) private { if (g._dailyDataCount >= beforeDay) { /* Already up-to-date */ return; } DailyRoundState memory rs; rs._allocSupplyCached = totalSupply() + g._lockedHeartsTotal; uint256 day = g._dailyDataCount; _dailyRoundCalcAndStore(g, rs, day); /* Stakes started during this day are added to the total the next day */ if (g._nextStakeSharesTotal != 0) { g._stakeSharesTotal += g._nextStakeSharesTotal; g._nextStakeSharesTotal = 0; } while (++day < beforeDay) { _dailyRoundCalcAndStore(g, rs, day); } _emitDailyDataUpdate(g._dailyDataCount, day, isAutoUpdate); g._dailyDataCount = day; } function _emitDailyDataUpdate(uint256 beginDay, uint256 endDay, bool isAutoUpdate) private { emit DailyDataUpdate( // (auto-generated event) uint256(uint40(block.timestamp)) | (uint256(uint16(beginDay)) << 40) | (uint256(uint16(endDay)) << 56) | (isAutoUpdate ? (1 << 72) : 0), msg.sender ); } }
pragma solidity ^0.5.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 {ERC20Mintable}. * * 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; /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view 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 returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public 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 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 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 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 { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _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 { require(account != address(0), "ERC20: mint to the zero address"); _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 { require(account != address(0), "ERC20: burn from the zero address"); _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 is 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 { 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 Destroys `amount` tokens from `account`.`amount` is then deducted * from the caller's allowance. * * See {_burn} and {_approve}. */ function _burnFrom(address account, uint256 amount) internal { _burn(account, amount); _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance")); } }
pragma solidity ^0.5.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. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
pragma solidity ^0.5.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ 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); }
pragma solidity ^0.5.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. * * _Available since v2.4.0._ */ 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. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 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. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"data0","type":"uint256"},{"indexed":true,"internalType":"address","name":"updaterAddr","type":"address"}],"name":"DailyDataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"data0","type":"uint256"},{"indexed":true,"internalType":"uint40","name":"stakeId","type":"uint40"}],"name":"ShareRateChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"data0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"data1","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakerAddr","type":"address"},{"indexed":true,"internalType":"uint40","name":"stakeId","type":"uint40"}],"name":"StakeEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"data0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"data1","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakerAddr","type":"address"},{"indexed":true,"internalType":"uint40","name":"stakeId","type":"uint40"},{"indexed":true,"internalType":"address","name":"senderAddr","type":"address"}],"name":"StakeGoodAccounting","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"data0","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakerAddr","type":"address"},{"indexed":true,"internalType":"uint40","name":"stakeId","type":"uint40"}],"name":"StakeStart","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[],"name":"allocatedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dailyData","outputs":[{"internalType":"uint72","name":"dayPayoutTotal","type":"uint72"},{"internalType":"uint72","name":"dayStakeSharesTotal","type":"uint72"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"beginDay","type":"uint256"},{"internalType":"uint256","name":"endDay","type":"uint256"}],"name":"dailyDataRange","outputs":[{"internalType":"uint256[]","name":"list","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"beforeDay","type":"uint256"}],"name":"dailyDataUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"globalInfo","outputs":[{"internalType":"uint256[9]","name":"","type":"uint256[9]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"globals","outputs":[{"internalType":"uint72","name":"lockedHeartsTotal","type":"uint72"},{"internalType":"uint72","name":"nextStakeSharesTotal","type":"uint72"},{"internalType":"uint40","name":"shareRate","type":"uint40"},{"internalType":"uint72","name":"stakePenaltyTotal","type":"uint72"},{"internalType":"uint16","name":"dailyDataCount","type":"uint16"},{"internalType":"uint72","name":"stakeSharesTotal","type":"uint72"},{"internalType":"uint40","name":"latestStakeId","type":"uint40"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"stakerAddr","type":"address"}],"name":"stakeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"stakeIndex","type":"uint256"},{"internalType":"uint40","name":"stakeIdParam","type":"uint40"}],"name":"stakeEnd","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"stakerAddr","type":"address"},{"internalType":"uint256","name":"stakeIndex","type":"uint256"},{"internalType":"uint40","name":"stakeIdParam","type":"uint40"}],"name":"stakeGoodAccounting","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakeLists","outputs":[{"internalType":"uint40","name":"stakeId","type":"uint40"},{"internalType":"uint72","name":"stakedHearts","type":"uint72"},{"internalType":"uint72","name":"stakeShares","type":"uint72"},{"internalType":"uint16","name":"lockedDay","type":"uint16"},{"internalType":"uint16","name":"stakedDays","type":"uint16"},{"internalType":"uint16","name":"unlockedDay","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newStakedHearts","type":"uint256"},{"internalType":"uint256","name":"newStakedDays","type":"uint256"}],"name":"stakeStart","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506003805464ffffffffff60901b1916740186a000000000000000000000000000000000000017905562000067600773b8cf11b8de281560884b4a23efd69d9aacbf3f4d6200012d602090811b6200260d17901c565b6200009773c3d6e20cc4d492c4b0b84312fb5d730d0327822266b1a2bc2ec500006001600160e01b03620001d416565b620000c773aef2989e6a23982d93d83f91378d17ec31662bd1668e1bc9bf0400006001600160e01b03620001d416565b620000f773b8cf11b8de281560884b4a23efd69d9aacbf3f4d6611c37937e080006001600160e01b03620001d416565b62000127732d38f017ec55858583d0db5f6088acbfe0a398086611c37937e080006001600160e01b03620001d416565b620003ee565b6200014282826001600160e01b03620002ef16565b15620001af57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b0382166200024a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b62000266816002546200037260201b62001b3b1790919060201c565b6002556001600160a01b038216600090815260208181526040909120546200029991839062001b3b62000372821b17901c565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60006001600160a01b03821662000352576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018062002cd36022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b600082820183811015620003e757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6128d580620003fe6000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c806352a438b8116100de57806390de687111610097578063a9059cbb11610071578063a9059cbb1461055f578063c31245251461058b578063dd62ed3e146105e7578063f04b5fa01461061557610173565b806390de6871146104e857806395d89b411461052b578063a457c2d71461053357610173565b806352a438b8146103d65780635c9302c9146103a257806365cf71b2146103f95780636a210a0e1461043257806370a08231146104a55780638f1c65c0146104cb57610173565b806333060d901161013057806333060d901461031c578063343009a214610342578063395093511461036e5780633a70a5ca1461039a5780633e6968b6146103a257806340c10f19146103aa57610173565b806306fdde0314610178578063095ea7b3146101f557806318160ddd1461023557806323b872dd1461024f5780632607443b14610285578063313ce567146102fe575b600080fd5b610180610656565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101ba5781810151838201526020016101a2565b50505050905090810190601f1680156101e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102216004803603604081101561020b57600080fd5b506001600160a01b038135169060200135610684565b604080519115158252519081900360200190f35b61023d6106a1565b60408051918252519081900360200190f35b6102216004803603606081101561026557600080fd5b506001600160a01b038135811691602081013590911690604001356106a7565b6102b16004803603604081101561029b57600080fd5b506001600160a01b038135169060200135610734565b6040805164ffffffffff90971687526001600160481b039586166020880152939094168584015261ffff9182166060860152811660808501529190911660a0830152519081900360c00190f35b6103066107a2565b6040805160ff9092168252519081900360200190f35b61023d6004803603602081101561033257600080fd5b50356001600160a01b03166107a7565b61036c6004803603604081101561035857600080fd5b508035906020013564ffffffffff166107c2565b005b6102216004803603604081101561038457600080fd5b506001600160a01b0381351690602001356109c4565b61023d610a18565b61023d610a35565b61036c600480360360408110156103c057600080fd5b506001600160a01b038135169060200135610a44565b61036c600480360360408110156103ec57600080fd5b5080359060200135610ab4565b61036c6004803603606081101561040f57600080fd5b5080356001600160a01b0316906020810135906040013564ffffffffff16610b3c565b6104556004803603604081101561044857600080fd5b5080359060200135610d91565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610491578181015183820152602001610479565b505050509050019250505060405180910390f35b61023d600480360360208110156104bb57600080fd5b50356001600160a01b0316610e97565b61036c600480360360208110156104e157600080fd5b5035610eb2565b610505600480360360208110156104fe57600080fd5b5035610f45565b604080516001600160481b03938416815291909216602082015281519081900390910190f35b610180610f6b565b6102216004803603604081101561054957600080fd5b506001600160a01b038135169060200135610f8b565b6102216004803603604081101561057557600080fd5b506001600160a01b038135169060200135610ff9565b61059361100d565b604080516001600160481b039889168152968816602088015264ffffffffff95861687820152938716606087015261ffff909216608086015290941660a0840152921660c082015290519081900360e00190f35b61023d600480360360408110156105fd57600080fd5b506001600160a01b0381358116916020013516611060565b61061d61108b565b604051808261012080838360005b8381101561064357818101518382015260200161062b565b5050505090500191505060405180910390f35b60405180604001604052806012815260200171233932b2a134ba31b7b4b739902a37b5b2b760711b81525081565b6000610698610691611125565b8484611129565b50600192915050565b60025490565b60006106b4848484611215565b61072a846106c0611125565b610725856040518060600160405280602881526020016127c8602891396001600160a01b038a166000908152600160205260408120906106fe611125565b6001600160a01b03168152602081019190915260400160002054919063ffffffff61137116565b611129565b5060019392505050565b6006602052816000526040600020818154811061074d57fe5b60009182526020909120015464ffffffffff811692506001600160481b03600160281b820481169250600160701b8204169061ffff600160b81b8204811691600160c81b8104821691600160d81b9091041686565b600881565b6001600160a01b031660009081526006602052604090205490565b6107ca61254b565b6107d261254b565b6107dc8282611408565b3360009081526006602052604090208054610837576040805162461bcd60e51b8152602060048201526016602482015275119491514e88115b5c1d1e481cdd185ad9481b1a5cdd60521b604482015290519081900360640190fd5b80548510610887576040805162461bcd60e51b8152602060048201526018602482015277119491514e881cdd185ad9525b99195e081a5b9d985b1a5960421b604482015290519081900360640190fd5b61088f612597565b6108af82878154811061089e57fe5b906000526020600020018683611488565b6108b88461154a565b60a0810151606082015160e08601516000921515918391829182918291116109315784156108ec5786608001519550610917565b6108f68a8861155d565b86606001518a60e00151039550866080015186111561091757866080015195505b6109228a888861157b565b9296509094509250905061094a565b60408701516020808c0180519290920390915287015193505b6109618b8860200151896040015186868b8b61161e565b801580159061096e575084155b1561097d5761097d8a826116e0565b83156109985761098d338561171b565b6109988a888661180b565b60208701518a51038a526109ac888d61187e565b6109b68a8a6119be565b505050505050505050505050565b60006106986109d1611125565b8461072585600160006109e2611125565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff611b3b16565b6003546000906001600160481b0316610a2f6106a1565b01905090565b6000610a3f611b9c565b905090565b610a5560073363ffffffff611bae16565b610aa6576040805162461bcd60e51b815260206004820152601960248201527f444f45535f4e4f545f484156455f4d494e5445525f524f4c4500000000000000604482015290519081900360640190fd5b610ab0828261171b565b5050565b610abc61254b565b610ac461254b565b610ace8282611408565b6001831015610b0e5760405162461bcd60e51b81526004018080602001828103825260268152602001806127a26026913960400191505060405180910390fd5b610b178261154a565b610b22828585611c15565b610b2c3385611d16565b610b3682826119be565b50505050565b610b4461254b565b610b4c61254b565b610b568282611408565b6001600160a01b038516600090815260066020526040902054610bb9576040805162461bcd60e51b8152602060048201526016602482015275119491514e88115b5c1d1e481cdd185ad9481b1a5cdd60521b604482015290519081900360640190fd5b6001600160a01b0385166000908152600660205260409020548410610c20576040805162461bcd60e51b8152602060048201526018602482015277119491514e881cdd185ad9525b99195e081a5b9d985b1a5960421b604482015290519081900360640190fd5b6001600160a01b0385166000908152600660205260408120805486908110610c4457fe5b906000526020600020019050610c58612597565b610c63828683611488565b80608001518160600151018460e001511015610cc6576040805162461bcd60e51b815260206004820152601c60248201527f465245453a205374616b65206e6f742066756c6c792073657276656400000000604482015290519081900360640190fd5b60a081015115610d1d576040805162461bcd60e51b815260206004820152601c60248201527f465245453a205374616b6520616c726561647920756e6c6f636b656400000000604482015290519081900360640190fd5b610d268461154a565b610d30848261155d565b6000806000610d448785866080015161157b565b93509350935050610d618a89866020015187604001518787611e12565b8015610d7157610d7187826116e0565b610d7b8585611eaf565b610d8587876119be565b50505050505050505050565b60608183108015610da8575060045461ffff168211155b610def576040805162461bcd60e51b815260206004820152601360248201527211909510ce881c985b99d9481a5b9d985b1a59606a1b604482015290519081900360640190fd5b828203604051908082528060200260200182016040528015610e1b578160200160208202803883390190505b509050826000805b5060008281526005602052604090205483516001830192600160481b830460481b71ffffffffffffffffff000000000000000000166001600160481b03909316929092179182918691908110610e7557fe5b602002602001018181525050848360010193508310610e235750505092915050565b6001600160a01b031660009081526020819052604090205490565b610eba61254b565b610ec261254b565b610ecc8282611408565b8215610f26578160e00151831115610f155760405162461bcd60e51b815260040180806020018281038252602781526020018061277b6027913960400191505060405180910390fd5b610f2182846000611f68565b610f36565b610f36828360e001516000611f68565b610f4082826119be565b505050565b6005602052600090815260409020546001600160481b0380821691600160481b90041682565b604051806040016040528060048152602001634642544360e01b81525081565b6000610698610f98611125565b846107258560405180606001604052806025815260200161287c6025913960016000610fc2611125565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61137116565b6000610698611006611125565b8484611215565b6003546004546001600160481b0380831692600160481b810482169264ffffffffff600160901b8304811693600160b81b90930483169261ffff83169262010000810490911691600160581b9091041687565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6110936125d4565b60408051610120810182526003546001600160481b038082168352600160481b82048116602084015264ffffffffff600160901b8304811694840194909452600160b81b9091048116606083015260045461ffff8116608084015262010000810490911660a0830152600160581b900490911660c08201524260e0820152610100810161111e6106a1565b9052905090565b3390565b6001600160a01b03831661116e5760405162461bcd60e51b81526004018080602001828103825260248152602001806128586024913960400191505060405180910390fd5b6001600160a01b0382166111b35760405162461bcd60e51b81526004018080602001828103825260228152602001806126fb6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661125a5760405162461bcd60e51b81526004018080602001828103825260258152602001806128336025913960400191505060405180910390fd5b6001600160a01b03821661129f5760405162461bcd60e51b815260040180806020018281038252602381526020018061268f6023913960400191505060405180910390fd5b6112e28160405180606001604052806026815260200161271d602691396001600160a01b038616600090815260208190526040902054919063ffffffff61137116565b6001600160a01b038085166000908152602081905260408082209390935590841681522054611317908263ffffffff611b3b16565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156114005760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156113c55781810151838201526020016113ad565b50505050905090810190601f1680156113f25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6003546001600160481b038082168452600160481b82048116602085015264ffffffffff600160901b830481166040860152600160b81b9092048116606085015260045461ffff8116608086015262010000810490911660a0850152600160581b90041660c0830152611479611b9c565b60e0830152610ab08282611ff2565b825464ffffffffff8381169116146114e7576040805162461bcd60e51b815260206004820152601f60248201527f464254433a207374616b654964506172616d206e6f7420696e207374616b6500604482015290519081900360640190fd5b915464ffffffffff811683526001600160481b03600160281b820481166020850152600160701b820416604084015261ffff600160b81b820481166060850152600160c81b820481166080850152600160d81b9091041660a09092019190915250565b61155a818260e001516001611f68565b50565b604081015160a080840180519290920390915260e090920151910152565b60008060008085608001518510156115b9576115a68787606001518860800151888a6040015161203a565b60208801518201955090935091506115f6565b604086015160608701516115d091908781016120df565b92508286602001510193506115f3866060015187608001518860a001518761212c565b91505b8115611615578382111561160d5750600092611615565b509182900391805b93509350935093565b8664ffffffffff16336001600160a01b03167f72d9c5a7ab13846e08d9c838f9e866a1bb4a66a2fd3ba3c9e7da3cf9e394dfd760b8876001600160481b0316901b6070896001600160481b0316901b60288b6001600160481b0316901b4264ffffffffff1617171784611692576000611698565b600160581b5b6bffffffffffffffffffffffff1660488761ffff16901b886001600160481b03161717604051808381526020018281526020019250505060405180910390a350505050505050565b6002810480156117085761170873b8cf11b8de281560884b4a23efd69d9aacbf3f4d8261171b565b6060909201805192909103919091019052565b6001600160a01b038216611776576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600254611789908263ffffffff611b3b16565b6002556001600160a01b0382166000908152602081905260409020546117b5908263ffffffff611b3b16565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b8160200151811115610f40576000611827828460800151612159565b905060008360400151620186a0838501028161183f57fe5b04905064ffffffffff811115611857575064ffffffffff5b8460400151811115611877576040850181905283516118779082906121cc565b5050505050565b81546000190181811461198d5782818154811061189757fe5b906000526020600020018383815481106118ad57fe5b6000918252602090912082549101805464ffffffffff191664ffffffffff9092169190911780825582546001600160481b03600160281b9182900481169091026dffffffffffffffffff000000000019909216919091178083558354600160701b9081900490921690910268ffffffffffffffffff60701b1990911617808255825461ffff600160b81b91829004811690910261ffff60b81b19909216919091178083558354600160c81b9081900483160261ffff60c81b19909116178083559254600160d81b908190049091160261ffff60d81b199092169190911790555b8280548061199757fe5b600082815260209020810160001990810180546001600160e81b0319169055019055505050565b805182511415806119d757508060200151826020015114155b806119ea57508060400151826040015114155b806119fd57508060600151826060015114155b15611a8b5781516003805460208501516040860151606087015168ffffffffffffffffff199093166001600160481b039586161768ffffffffffffffffff60481b1916600160481b928616929092029190911764ffffffffff60901b1916600160901b64ffffffffff90921691909102176001600160b81b0316600160b81b93909116929092029190911790555b80608001518260800151141580611aaa57508060a001518260a0015114155b80611acb57508060c0015164ffffffffff168260c0015164ffffffffff1614155b15610ab05760808201516004805460a085015160c086015164ffffffffff16600160581b0264ffffffffff60581b196001600160481b0390921662010000026affffffffffffffffff00001961ffff90961661ffff19909416939093179490941691909117169190911790555050565b600082820183811015611b95576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b620151804265017af4b5e7ff19010490565b60006001600160a01b038216611bf55760405162461bcd60e51b81526004018080602001828103825260228152602001806127f06022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b6115b3811115611c565760405162461bcd60e51b81526004018080602001828103825260278152602001806126b26027913960400191505060405180910390fd5b6000611c628383612159565b905060008460400151620186a08386010281611c7a57fe5b04905080611cb95760405162461bcd60e51b81526004018080602001828103825260388152602001806127436038913960400191505060405180910390fd5b60e085015160c08601805164ffffffffff60019182011691829052336000908152600660205260409020920191611cf490828886868a612223565b611d008187858861232e565b5050602085018051909101905250508151019052565b6001600160a01b038216611d5b5760405162461bcd60e51b81526004018080602001828103825260218152602001806128126021913960400191505060405180910390fd5b611d9e816040518060600160405280602281526020016126d9602291396001600160a01b038516600090815260208190526040902054919063ffffffff61137116565b6001600160a01b038316600090815260208190526040902055600254611dca908263ffffffff6123ac16565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b604080514264ffffffffff9081166dffffffffffffffffff0000000000602889901b161768ffffffffffffffffff60701b607088901b16176001600160b81b031960b887901b161782526001600160481b038416602083015282513393918916926001600160a01b038b16927fd824970a2cf19cc2b630c87ce5b00f67301cac3ac60513d027c7a39129f93b4692918290030190a4505050505050565b80518254602083015160408401516060850151608086015160a09096015164ffffffffff1990941664ffffffffff909516949094176dffffffffffffffffff00000000001916600160281b6001600160481b03938416021768ffffffffffffffffff60701b1916600160701b92909116919091021761ffff60b81b1916600160b81b61ffff938416021761ffff60c81b1916600160c81b938316939093029290921761ffff60d81b1916600160d81b9190921602179055565b81836080015110611f7857610f40565b611f806125f3565b8351611f8a6106a1565b0181526080840151611f9d8583836123ee565b602085015115611fbd5760208501805160a0870180519091019052600090525b60010183811015611fd857611fd38583836123ee565b611fbd565b611fe785608001518285612452565b608085015250505050565b815181526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0808301519082015260c09182015164ffffffffff16910152565b60008083860160026001870104605a8110156120545750605a5b856120735760006120658a876124c9565b9190910292506120d5915050565b858110156120a657878101612089868a836120df565b935060006120988783866120df565b850195506120d59350505050565b6120b18589846120df565b9350858114156120c3578392506120d2565b85818502816120ce57fe5b0492505b50505b9550959350505050565b6000825b82811015612124576000818152600560205260409020546001600160481b03600160481b82048116911686028161211657fe5b0491909101906001016120e3565b509392505050565b6000848401600e01808411612145576000915050612151565b6102bc90840383020490505b949350505050565b600080600183111561217f57610e3883111561217757610e3861217c565b600183035b90505b600066354a6ba7a1800085111561219d5766354a6ba7a1800061219f565b845b670214e8348c4f0000830261071c82020193509050680ecca2d59581a400008584025b0495945050505050565b8064ffffffffff167f9861fa0ed101659f7a59b4583fcc798dfa4f3b419bea371c8ee2ad0ffe13a31e60288464ffffffffff16901b4264ffffffffff16176040518082815260200191505060405180910390a25050565b6040805160c08101825264ffffffffff96871681526001600160481b03958616602080830191825295871692820192835261ffff9485166060830190815293851660808301908152600060a084018181528b54600181018d559b825297902092519290990180549151935194519951965164ffffffffff1990921692909816919091176dffffffffffffffffff00000000001916600160281b928716929092029190911768ffffffffffffffffff60701b1916600160701b92909516919091029390931761ffff60b81b1916600160b81b958216959095029490941761ffff60c81b1916600160c81b918516919091021761ffff60d81b1916600160d81b9190931602919091179055565b8364ffffffffff16336001600160a01b03167f14872dc760f33532684e68e1b6d5fd3f71ba7b07dee76bdb2b084f28b74233ef60b88461ffff16901b6070866001600160481b0316901b6028886001600160481b0316901b4264ffffffffff161717176040518082815260200191505060405180910390a350505050565b6000611b9583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611371565b6123f88383612516565b6020918201516000918252600590925260409020805460a0909301516001600160481b03908116600160481b0268ffffffffffffffffff60481b199190931668ffffffffffffffffff199094169390931792909216179055565b337fb8d6eb541ded1720cc657b719f57abcb1fe4711cb7ead82751b135f5d94bc94482612480576000612486565b600160481b5b69ffffffffffffffffffff1660388561ffff16901b60288761ffff16901b4264ffffffffff161717176040518082815260200191505060405180910390a2505050565b60006124d361254b565b6124dd8482611ff2565b6124e56125f3565b84516124ef6106a1565b0181526124fc8282612516565b60a08201805185019081905260208201518502816121c257fe5b8051630246acad9061271002046020820152606082015115610ab0576060820180516020830180519091019052600090525050565b604051806101000160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600064ffffffffff168152602001600081525090565b6040518060c00160405280600064ffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518061012001604052806009906020820280388339509192915050565b604051806040016040528060008152602001600081525090565b6126178282611bae565b15612669576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff1916600117905556fe45524332303a207472616e7366657220746f20746865207a65726f2061646472657373465245453a206e65775374616b65644461797320686967686572207468616e206d6178696d756d45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365465245453a206e65775374616b6564486561727473206d757374206265206174206c65617374206d696e696d756d20736861726552617465464254433a206265666f72654461792063616e6e6f7420626520696e2074686520667574757265465245453a206e65775374616b656444617973206c6f776572207468616e206d696e696d756d45524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365526f6c65733a206163636f756e7420697320746865207a65726f206164647265737345524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820ec5bb25716b7bd4a6e835180afd65fbfbee6a2ff787e8440126e8e2dbbab556164736f6c634300050d0032526f6c65733a206163636f756e7420697320746865207a65726f2061646472657373
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101735760003560e01c806352a438b8116100de57806390de687111610097578063a9059cbb11610071578063a9059cbb1461055f578063c31245251461058b578063dd62ed3e146105e7578063f04b5fa01461061557610173565b806390de6871146104e857806395d89b411461052b578063a457c2d71461053357610173565b806352a438b8146103d65780635c9302c9146103a257806365cf71b2146103f95780636a210a0e1461043257806370a08231146104a55780638f1c65c0146104cb57610173565b806333060d901161013057806333060d901461031c578063343009a214610342578063395093511461036e5780633a70a5ca1461039a5780633e6968b6146103a257806340c10f19146103aa57610173565b806306fdde0314610178578063095ea7b3146101f557806318160ddd1461023557806323b872dd1461024f5780632607443b14610285578063313ce567146102fe575b600080fd5b610180610656565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101ba5781810151838201526020016101a2565b50505050905090810190601f1680156101e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102216004803603604081101561020b57600080fd5b506001600160a01b038135169060200135610684565b604080519115158252519081900360200190f35b61023d6106a1565b60408051918252519081900360200190f35b6102216004803603606081101561026557600080fd5b506001600160a01b038135811691602081013590911690604001356106a7565b6102b16004803603604081101561029b57600080fd5b506001600160a01b038135169060200135610734565b6040805164ffffffffff90971687526001600160481b039586166020880152939094168584015261ffff9182166060860152811660808501529190911660a0830152519081900360c00190f35b6103066107a2565b6040805160ff9092168252519081900360200190f35b61023d6004803603602081101561033257600080fd5b50356001600160a01b03166107a7565b61036c6004803603604081101561035857600080fd5b508035906020013564ffffffffff166107c2565b005b6102216004803603604081101561038457600080fd5b506001600160a01b0381351690602001356109c4565b61023d610a18565b61023d610a35565b61036c600480360360408110156103c057600080fd5b506001600160a01b038135169060200135610a44565b61036c600480360360408110156103ec57600080fd5b5080359060200135610ab4565b61036c6004803603606081101561040f57600080fd5b5080356001600160a01b0316906020810135906040013564ffffffffff16610b3c565b6104556004803603604081101561044857600080fd5b5080359060200135610d91565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610491578181015183820152602001610479565b505050509050019250505060405180910390f35b61023d600480360360208110156104bb57600080fd5b50356001600160a01b0316610e97565b61036c600480360360208110156104e157600080fd5b5035610eb2565b610505600480360360208110156104fe57600080fd5b5035610f45565b604080516001600160481b03938416815291909216602082015281519081900390910190f35b610180610f6b565b6102216004803603604081101561054957600080fd5b506001600160a01b038135169060200135610f8b565b6102216004803603604081101561057557600080fd5b506001600160a01b038135169060200135610ff9565b61059361100d565b604080516001600160481b039889168152968816602088015264ffffffffff95861687820152938716606087015261ffff909216608086015290941660a0840152921660c082015290519081900360e00190f35b61023d600480360360408110156105fd57600080fd5b506001600160a01b0381358116916020013516611060565b61061d61108b565b604051808261012080838360005b8381101561064357818101518382015260200161062b565b5050505090500191505060405180910390f35b60405180604001604052806012815260200171233932b2a134ba31b7b4b739902a37b5b2b760711b81525081565b6000610698610691611125565b8484611129565b50600192915050565b60025490565b60006106b4848484611215565b61072a846106c0611125565b610725856040518060600160405280602881526020016127c8602891396001600160a01b038a166000908152600160205260408120906106fe611125565b6001600160a01b03168152602081019190915260400160002054919063ffffffff61137116565b611129565b5060019392505050565b6006602052816000526040600020818154811061074d57fe5b60009182526020909120015464ffffffffff811692506001600160481b03600160281b820481169250600160701b8204169061ffff600160b81b8204811691600160c81b8104821691600160d81b9091041686565b600881565b6001600160a01b031660009081526006602052604090205490565b6107ca61254b565b6107d261254b565b6107dc8282611408565b3360009081526006602052604090208054610837576040805162461bcd60e51b8152602060048201526016602482015275119491514e88115b5c1d1e481cdd185ad9481b1a5cdd60521b604482015290519081900360640190fd5b80548510610887576040805162461bcd60e51b8152602060048201526018602482015277119491514e881cdd185ad9525b99195e081a5b9d985b1a5960421b604482015290519081900360640190fd5b61088f612597565b6108af82878154811061089e57fe5b906000526020600020018683611488565b6108b88461154a565b60a0810151606082015160e08601516000921515918391829182918291116109315784156108ec5786608001519550610917565b6108f68a8861155d565b86606001518a60e00151039550866080015186111561091757866080015195505b6109228a888861157b565b9296509094509250905061094a565b60408701516020808c0180519290920390915287015193505b6109618b8860200151896040015186868b8b61161e565b801580159061096e575084155b1561097d5761097d8a826116e0565b83156109985761098d338561171b565b6109988a888661180b565b60208701518a51038a526109ac888d61187e565b6109b68a8a6119be565b505050505050505050505050565b60006106986109d1611125565b8461072585600160006109e2611125565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff611b3b16565b6003546000906001600160481b0316610a2f6106a1565b01905090565b6000610a3f611b9c565b905090565b610a5560073363ffffffff611bae16565b610aa6576040805162461bcd60e51b815260206004820152601960248201527f444f45535f4e4f545f484156455f4d494e5445525f524f4c4500000000000000604482015290519081900360640190fd5b610ab0828261171b565b5050565b610abc61254b565b610ac461254b565b610ace8282611408565b6001831015610b0e5760405162461bcd60e51b81526004018080602001828103825260268152602001806127a26026913960400191505060405180910390fd5b610b178261154a565b610b22828585611c15565b610b2c3385611d16565b610b3682826119be565b50505050565b610b4461254b565b610b4c61254b565b610b568282611408565b6001600160a01b038516600090815260066020526040902054610bb9576040805162461bcd60e51b8152602060048201526016602482015275119491514e88115b5c1d1e481cdd185ad9481b1a5cdd60521b604482015290519081900360640190fd5b6001600160a01b0385166000908152600660205260409020548410610c20576040805162461bcd60e51b8152602060048201526018602482015277119491514e881cdd185ad9525b99195e081a5b9d985b1a5960421b604482015290519081900360640190fd5b6001600160a01b0385166000908152600660205260408120805486908110610c4457fe5b906000526020600020019050610c58612597565b610c63828683611488565b80608001518160600151018460e001511015610cc6576040805162461bcd60e51b815260206004820152601c60248201527f465245453a205374616b65206e6f742066756c6c792073657276656400000000604482015290519081900360640190fd5b60a081015115610d1d576040805162461bcd60e51b815260206004820152601c60248201527f465245453a205374616b6520616c726561647920756e6c6f636b656400000000604482015290519081900360640190fd5b610d268461154a565b610d30848261155d565b6000806000610d448785866080015161157b565b93509350935050610d618a89866020015187604001518787611e12565b8015610d7157610d7187826116e0565b610d7b8585611eaf565b610d8587876119be565b50505050505050505050565b60608183108015610da8575060045461ffff168211155b610def576040805162461bcd60e51b815260206004820152601360248201527211909510ce881c985b99d9481a5b9d985b1a59606a1b604482015290519081900360640190fd5b828203604051908082528060200260200182016040528015610e1b578160200160208202803883390190505b509050826000805b5060008281526005602052604090205483516001830192600160481b830460481b71ffffffffffffffffff000000000000000000166001600160481b03909316929092179182918691908110610e7557fe5b602002602001018181525050848360010193508310610e235750505092915050565b6001600160a01b031660009081526020819052604090205490565b610eba61254b565b610ec261254b565b610ecc8282611408565b8215610f26578160e00151831115610f155760405162461bcd60e51b815260040180806020018281038252602781526020018061277b6027913960400191505060405180910390fd5b610f2182846000611f68565b610f36565b610f36828360e001516000611f68565b610f4082826119be565b505050565b6005602052600090815260409020546001600160481b0380821691600160481b90041682565b604051806040016040528060048152602001634642544360e01b81525081565b6000610698610f98611125565b846107258560405180606001604052806025815260200161287c6025913960016000610fc2611125565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61137116565b6000610698611006611125565b8484611215565b6003546004546001600160481b0380831692600160481b810482169264ffffffffff600160901b8304811693600160b81b90930483169261ffff83169262010000810490911691600160581b9091041687565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6110936125d4565b60408051610120810182526003546001600160481b038082168352600160481b82048116602084015264ffffffffff600160901b8304811694840194909452600160b81b9091048116606083015260045461ffff8116608084015262010000810490911660a0830152600160581b900490911660c08201524260e0820152610100810161111e6106a1565b9052905090565b3390565b6001600160a01b03831661116e5760405162461bcd60e51b81526004018080602001828103825260248152602001806128586024913960400191505060405180910390fd5b6001600160a01b0382166111b35760405162461bcd60e51b81526004018080602001828103825260228152602001806126fb6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661125a5760405162461bcd60e51b81526004018080602001828103825260258152602001806128336025913960400191505060405180910390fd5b6001600160a01b03821661129f5760405162461bcd60e51b815260040180806020018281038252602381526020018061268f6023913960400191505060405180910390fd5b6112e28160405180606001604052806026815260200161271d602691396001600160a01b038616600090815260208190526040902054919063ffffffff61137116565b6001600160a01b038085166000908152602081905260408082209390935590841681522054611317908263ffffffff611b3b16565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156114005760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156113c55781810151838201526020016113ad565b50505050905090810190601f1680156113f25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6003546001600160481b038082168452600160481b82048116602085015264ffffffffff600160901b830481166040860152600160b81b9092048116606085015260045461ffff8116608086015262010000810490911660a0850152600160581b90041660c0830152611479611b9c565b60e0830152610ab08282611ff2565b825464ffffffffff8381169116146114e7576040805162461bcd60e51b815260206004820152601f60248201527f464254433a207374616b654964506172616d206e6f7420696e207374616b6500604482015290519081900360640190fd5b915464ffffffffff811683526001600160481b03600160281b820481166020850152600160701b820416604084015261ffff600160b81b820481166060850152600160c81b820481166080850152600160d81b9091041660a09092019190915250565b61155a818260e001516001611f68565b50565b604081015160a080840180519290920390915260e090920151910152565b60008060008085608001518510156115b9576115a68787606001518860800151888a6040015161203a565b60208801518201955090935091506115f6565b604086015160608701516115d091908781016120df565b92508286602001510193506115f3866060015187608001518860a001518761212c565b91505b8115611615578382111561160d5750600092611615565b509182900391805b93509350935093565b8664ffffffffff16336001600160a01b03167f72d9c5a7ab13846e08d9c838f9e866a1bb4a66a2fd3ba3c9e7da3cf9e394dfd760b8876001600160481b0316901b6070896001600160481b0316901b60288b6001600160481b0316901b4264ffffffffff1617171784611692576000611698565b600160581b5b6bffffffffffffffffffffffff1660488761ffff16901b886001600160481b03161717604051808381526020018281526020019250505060405180910390a350505050505050565b6002810480156117085761170873b8cf11b8de281560884b4a23efd69d9aacbf3f4d8261171b565b6060909201805192909103919091019052565b6001600160a01b038216611776576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600254611789908263ffffffff611b3b16565b6002556001600160a01b0382166000908152602081905260409020546117b5908263ffffffff611b3b16565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b8160200151811115610f40576000611827828460800151612159565b905060008360400151620186a0838501028161183f57fe5b04905064ffffffffff811115611857575064ffffffffff5b8460400151811115611877576040850181905283516118779082906121cc565b5050505050565b81546000190181811461198d5782818154811061189757fe5b906000526020600020018383815481106118ad57fe5b6000918252602090912082549101805464ffffffffff191664ffffffffff9092169190911780825582546001600160481b03600160281b9182900481169091026dffffffffffffffffff000000000019909216919091178083558354600160701b9081900490921690910268ffffffffffffffffff60701b1990911617808255825461ffff600160b81b91829004811690910261ffff60b81b19909216919091178083558354600160c81b9081900483160261ffff60c81b19909116178083559254600160d81b908190049091160261ffff60d81b199092169190911790555b8280548061199757fe5b600082815260209020810160001990810180546001600160e81b0319169055019055505050565b805182511415806119d757508060200151826020015114155b806119ea57508060400151826040015114155b806119fd57508060600151826060015114155b15611a8b5781516003805460208501516040860151606087015168ffffffffffffffffff199093166001600160481b039586161768ffffffffffffffffff60481b1916600160481b928616929092029190911764ffffffffff60901b1916600160901b64ffffffffff90921691909102176001600160b81b0316600160b81b93909116929092029190911790555b80608001518260800151141580611aaa57508060a001518260a0015114155b80611acb57508060c0015164ffffffffff168260c0015164ffffffffff1614155b15610ab05760808201516004805460a085015160c086015164ffffffffff16600160581b0264ffffffffff60581b196001600160481b0390921662010000026affffffffffffffffff00001961ffff90961661ffff19909416939093179490941691909117169190911790555050565b600082820183811015611b95576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b620151804265017af4b5e7ff19010490565b60006001600160a01b038216611bf55760405162461bcd60e51b81526004018080602001828103825260228152602001806127f06022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b6115b3811115611c565760405162461bcd60e51b81526004018080602001828103825260278152602001806126b26027913960400191505060405180910390fd5b6000611c628383612159565b905060008460400151620186a08386010281611c7a57fe5b04905080611cb95760405162461bcd60e51b81526004018080602001828103825260388152602001806127436038913960400191505060405180910390fd5b60e085015160c08601805164ffffffffff60019182011691829052336000908152600660205260409020920191611cf490828886868a612223565b611d008187858861232e565b5050602085018051909101905250508151019052565b6001600160a01b038216611d5b5760405162461bcd60e51b81526004018080602001828103825260218152602001806128126021913960400191505060405180910390fd5b611d9e816040518060600160405280602281526020016126d9602291396001600160a01b038516600090815260208190526040902054919063ffffffff61137116565b6001600160a01b038316600090815260208190526040902055600254611dca908263ffffffff6123ac16565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b604080514264ffffffffff9081166dffffffffffffffffff0000000000602889901b161768ffffffffffffffffff60701b607088901b16176001600160b81b031960b887901b161782526001600160481b038416602083015282513393918916926001600160a01b038b16927fd824970a2cf19cc2b630c87ce5b00f67301cac3ac60513d027c7a39129f93b4692918290030190a4505050505050565b80518254602083015160408401516060850151608086015160a09096015164ffffffffff1990941664ffffffffff909516949094176dffffffffffffffffff00000000001916600160281b6001600160481b03938416021768ffffffffffffffffff60701b1916600160701b92909116919091021761ffff60b81b1916600160b81b61ffff938416021761ffff60c81b1916600160c81b938316939093029290921761ffff60d81b1916600160d81b9190921602179055565b81836080015110611f7857610f40565b611f806125f3565b8351611f8a6106a1565b0181526080840151611f9d8583836123ee565b602085015115611fbd5760208501805160a0870180519091019052600090525b60010183811015611fd857611fd38583836123ee565b611fbd565b611fe785608001518285612452565b608085015250505050565b815181526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0808301519082015260c09182015164ffffffffff16910152565b60008083860160026001870104605a8110156120545750605a5b856120735760006120658a876124c9565b9190910292506120d5915050565b858110156120a657878101612089868a836120df565b935060006120988783866120df565b850195506120d59350505050565b6120b18589846120df565b9350858114156120c3578392506120d2565b85818502816120ce57fe5b0492505b50505b9550959350505050565b6000825b82811015612124576000818152600560205260409020546001600160481b03600160481b82048116911686028161211657fe5b0491909101906001016120e3565b509392505050565b6000848401600e01808411612145576000915050612151565b6102bc90840383020490505b949350505050565b600080600183111561217f57610e3883111561217757610e3861217c565b600183035b90505b600066354a6ba7a1800085111561219d5766354a6ba7a1800061219f565b845b670214e8348c4f0000830261071c82020193509050680ecca2d59581a400008584025b0495945050505050565b8064ffffffffff167f9861fa0ed101659f7a59b4583fcc798dfa4f3b419bea371c8ee2ad0ffe13a31e60288464ffffffffff16901b4264ffffffffff16176040518082815260200191505060405180910390a25050565b6040805160c08101825264ffffffffff96871681526001600160481b03958616602080830191825295871692820192835261ffff9485166060830190815293851660808301908152600060a084018181528b54600181018d559b825297902092519290990180549151935194519951965164ffffffffff1990921692909816919091176dffffffffffffffffff00000000001916600160281b928716929092029190911768ffffffffffffffffff60701b1916600160701b92909516919091029390931761ffff60b81b1916600160b81b958216959095029490941761ffff60c81b1916600160c81b918516919091021761ffff60d81b1916600160d81b9190931602919091179055565b8364ffffffffff16336001600160a01b03167f14872dc760f33532684e68e1b6d5fd3f71ba7b07dee76bdb2b084f28b74233ef60b88461ffff16901b6070866001600160481b0316901b6028886001600160481b0316901b4264ffffffffff161717176040518082815260200191505060405180910390a350505050565b6000611b9583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611371565b6123f88383612516565b6020918201516000918252600590925260409020805460a0909301516001600160481b03908116600160481b0268ffffffffffffffffff60481b199190931668ffffffffffffffffff199094169390931792909216179055565b337fb8d6eb541ded1720cc657b719f57abcb1fe4711cb7ead82751b135f5d94bc94482612480576000612486565b600160481b5b69ffffffffffffffffffff1660388561ffff16901b60288761ffff16901b4264ffffffffff161717176040518082815260200191505060405180910390a2505050565b60006124d361254b565b6124dd8482611ff2565b6124e56125f3565b84516124ef6106a1565b0181526124fc8282612516565b60a08201805185019081905260208201518502816121c257fe5b8051630246acad9061271002046020820152606082015115610ab0576060820180516020830180519091019052600090525050565b604051806101000160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600064ffffffffff168152602001600081525090565b6040518060c00160405280600064ffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518061012001604052806009906020820280388339509192915050565b604051806040016040528060008152602001600081525090565b6126178282611bae565b15612669576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff1916600117905556fe45524332303a207472616e7366657220746f20746865207a65726f2061646472657373465245453a206e65775374616b65644461797320686967686572207468616e206d6178696d756d45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365465245453a206e65775374616b6564486561727473206d757374206265206174206c65617374206d696e696d756d20736861726552617465464254433a206265666f72654461792063616e6e6f7420626520696e2074686520667574757265465245453a206e65775374616b656444617973206c6f776572207468616e206d696e696d756d45524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365526f6c65733a206163636f756e7420697320746865207a65726f206164647265737345524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820ec5bb25716b7bd4a6e835180afd65fbfbee6a2ff787e8440126e8e2dbbab556164736f6c634300050d0032
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.