More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 3,265 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Lock | 20206501 | 6 hrs ago | IN | 0 ETH | 0.00026722 | ||||
Withdraw Expired... | 20203411 | 17 hrs ago | IN | 0 ETH | 0.00045128 | ||||
Withdraw Expired... | 20200282 | 27 hrs ago | IN | 0 ETH | 0.00042516 | ||||
Lock | 20198749 | 32 hrs ago | IN | 0 ETH | 0.00017017 | ||||
Withdraw Expired... | 20195248 | 44 hrs ago | IN | 0 ETH | 0.00028346 | ||||
Withdraw Expired... | 20195216 | 44 hrs ago | IN | 0 ETH | 0.00029928 | ||||
Withdraw Expired... | 20195077 | 45 hrs ago | IN | 0 ETH | 0.00010796 | ||||
Withdraw Expired... | 20192647 | 2 days ago | IN | 0 ETH | 0.00030229 | ||||
Extend Lock | 20187418 | 2 days ago | IN | 0 ETH | 0.00030516 | ||||
Lock | 20185568 | 3 days ago | IN | 0 ETH | 0.00117573 | ||||
Withdraw Expired... | 20183175 | 3 days ago | IN | 0 ETH | 0.00067385 | ||||
Extend Many | 20181815 | 3 days ago | IN | 0 ETH | 0.00030721 | ||||
Withdraw Expired... | 20181155 | 3 days ago | IN | 0 ETH | 0.00095937 | ||||
Withdraw Expired... | 20179718 | 4 days ago | IN | 0 ETH | 0.00030407 | ||||
Lock | 20179713 | 4 days ago | IN | 0 ETH | 0.00034323 | ||||
Lock | 20179699 | 4 days ago | IN | 0 ETH | 0.00030034 | ||||
Lock | 20178083 | 4 days ago | IN | 0 ETH | 0.00089536 | ||||
Lock | 20177761 | 4 days ago | IN | 0 ETH | 0.00052861 | ||||
Withdraw Expired... | 20175532 | 4 days ago | IN | 0 ETH | 0.00032367 | ||||
Extend Lock | 20174732 | 4 days ago | IN | 0 ETH | 0.00020256 | ||||
Withdraw Expired... | 20174727 | 4 days ago | IN | 0 ETH | 0.00039529 | ||||
Lock | 20168043 | 5 days ago | IN | 0 ETH | 0.00039228 | ||||
Lock | 20166999 | 5 days ago | IN | 0 ETH | 0.00026101 | ||||
Lock | 20163891 | 6 days ago | IN | 0 ETH | 0.00087632 | ||||
Lock | 20159499 | 6 days ago | IN | 0 ETH | 0.00023658 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
TokenLocker
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import "PrismaOwnable.sol"; import "SystemStart.sol"; import "IPrismaCore.sol"; import "IIncentiveVoting.sol"; import "IPrismaToken.sol"; /** @title Prisma Token Locker @notice PRISMA tokens can be locked in this contract to receive "lock weight", which is used within `AdminVoting` and `IncentiveVoting` to vote on core protocol operations. */ contract TokenLocker is PrismaOwnable, SystemStart { // The maximum number of weeks that tokens may be locked for. Also determines the maximum // number of active locks that a single account may open. Weight is calculated as: // `[balance] * [weeks to unlock]`. Weights are stored as `uint40` and balances as `uint32`, // so the max lock weeks cannot be greater than 256 or the system could break due to overflow. uint256 public constant MAX_LOCK_WEEKS = 52; // Multiplier applied during token deposits and withdrawals. A balance within this // contract corresponds to a deposit of `balance * lockToTokenRatio` tokens. Balances // in this contract are stored as `uint32`, so the invariant: // // `lockToken.totalSupply() <= type(uint32).max * lockToTokenRatio` // // cannot be violated or the system could break due to overflow. uint256 public immutable lockToTokenRatio; IPrismaToken public immutable lockToken; IIncentiveVoting public immutable incentiveVoter; IPrismaCore public immutable prismaCore; address public immutable deploymentManager; bool public penaltyWithdrawalsEnabled; uint256 public allowPenaltyWithdrawAfter; struct AccountData { // Currently locked balance. Each week the lock weight decays by this amount. uint32 locked; // Currently unlocked balance (from expired locks, can be withdrawn) uint32 unlocked; // Currently "frozen" balance. A frozen balance is equivalent to a `MAX_LOCK_WEEKS` lock, // where the lock weight does not decay weekly. An account may have a locked balance or a // frozen balance, never both at the same time. uint32 frozen; // Current week within `accountWeeklyUnlocks`. Lock durations decay as this value increases. uint16 week; // Array of bitfields, where each bit represents 1 week. A bit is set to true when the // account has a non-zero token balance unlocking in that week, and so a non-zero value // at the same index in `accountWeeklyUnlocks`. We use this bitarray to reduce gas costs // when iterating over the weekly unlocks. uint256[256] updateWeeks; } // structs used in function inputs struct LockData { uint256 amount; uint256 weeksToUnlock; } struct ExtendLockData { uint256 amount; uint256 currentWeeks; uint256 newWeeks; } // Rate at which the total lock weight decreases each week. The total decay rate may not // be equal to the total number of locked tokens, as it does not include frozen accounts. uint32 public totalDecayRate; // Current week within `totalWeeklyWeights` and `totalWeeklyUnlocks`. When up-to-date // this value is always equal to `getWeek()` uint16 public totalUpdatedWeek; // week -> total lock weight uint40[65535] totalWeeklyWeights; // week -> tokens to unlock in this week uint32[65535] totalWeeklyUnlocks; // account -> week -> lock weight mapping(address => uint40[65535]) accountWeeklyWeights; // account -> week -> token balance unlocking this week mapping(address => uint32[65535]) accountWeeklyUnlocks; // account -> primary account data structure mapping(address => AccountData) accountLockData; event LockCreated(address indexed account, uint256 amount, uint256 _weeks); event LockExtended(address indexed account, uint256 amount, uint256 _weeks, uint256 newWeeks); event LocksCreated(address indexed account, LockData[] newLocks); event LocksExtended(address indexed account, ExtendLockData[] locks); event LocksFrozen(address indexed account, uint256 amount); event LocksUnfrozen(address indexed account, uint256 amount); event LocksWithdrawn(address indexed account, uint256 withdrawn, uint256 penalty); constructor( address _prismaCore, IPrismaToken _token, IIncentiveVoting _voter, address _manager, uint256 _lockToTokenRatio ) SystemStart(_prismaCore) PrismaOwnable(_prismaCore) { lockToken = _token; incentiveVoter = _voter; prismaCore = IPrismaCore(_prismaCore); deploymentManager = _manager; lockToTokenRatio = _lockToTokenRatio; } modifier notFrozen(address account) { require(accountLockData[account].frozen == 0, "Lock is frozen"); _; } function setAllowPenaltyWithdrawAfter(uint256 _timestamp) external returns (bool) { require(msg.sender == deploymentManager, "!deploymentManager"); require(allowPenaltyWithdrawAfter == 0, "Already set"); require(_timestamp > block.timestamp && _timestamp < block.timestamp + 13 weeks, "Invalid timestamp"); allowPenaltyWithdrawAfter = _timestamp; return true; } /** @notice Allow or disallow early-exit of locks by paying a penalty */ function setPenaltyWithdrawalsEnabled(bool _enabled) external onlyOwner returns (bool) { uint256 start = allowPenaltyWithdrawAfter; require(start != 0 && block.timestamp > start, "Not yet!"); penaltyWithdrawalsEnabled = _enabled; return true; } /** @notice Get the balances currently held in this contract for an account @return locked balance which is currently locked or frozen @return unlocked expired lock balance which may be withdrawn */ function getAccountBalances(address account) external view returns (uint256 locked, uint256 unlocked) { AccountData storage accountData = accountLockData[account]; uint256 frozen = accountData.frozen; unlocked = accountData.unlocked; if (frozen > 0) { return (frozen, unlocked); } locked = accountData.locked; if (locked > 0) { uint32[65535] storage weeklyUnlocks = accountWeeklyUnlocks[account]; uint256 accountWeek = accountData.week; uint256 systemWeek = getWeek(); uint256 bitfield = accountData.updateWeeks[accountWeek / 256] >> (accountWeek % 256); while (accountWeek < systemWeek) { accountWeek++; if (accountWeek % 256 == 0) { bitfield = accountData.updateWeeks[accountWeek / 256]; } else { bitfield = bitfield >> 1; } if (bitfield & uint256(1) == 1) { uint256 u = weeklyUnlocks[accountWeek]; locked -= u; unlocked += u; if (locked == 0) break; } } } return (locked, unlocked); } /** @notice Get the current lock weight for an account */ function getAccountWeight(address account) external view returns (uint256) { return getAccountWeightAt(account, getWeek()); } /** @notice Get the lock weight for an account in a given week */ function getAccountWeightAt(address account, uint256 week) public view returns (uint256) { if (week > getWeek()) return 0; uint32[65535] storage weeklyUnlocks = accountWeeklyUnlocks[account]; uint40[65535] storage weeklyWeights = accountWeeklyWeights[account]; AccountData storage accountData = accountLockData[account]; uint256 accountWeek = accountData.week; if (accountWeek >= week) return weeklyWeights[week]; uint256 locked = accountData.locked; uint256 weight = weeklyWeights[accountWeek]; if (locked == 0 || accountData.frozen > 0) { return weight; } uint256 bitfield = accountData.updateWeeks[accountWeek / 256] >> (accountWeek % 256); while (accountWeek < week) { accountWeek++; weight -= locked; if (accountWeek % 256 == 0) { bitfield = accountData.updateWeeks[accountWeek / 256]; } else { bitfield = bitfield >> 1; } if (bitfield & uint256(1) == 1) { uint256 amount = weeklyUnlocks[accountWeek]; locked -= amount; if (locked == 0) break; } } return weight; } /** @notice Get data on an accounts's active token locks and frozen balance @param account Address to query data for @return lockData dynamic array of [weeks until expiration, balance of lock] @return frozenAmount total frozen balance */ function getAccountActiveLocks( address account, uint256 minWeeks ) external view returns (LockData[] memory lockData, uint256 frozenAmount) { AccountData storage accountData = accountLockData[account]; frozenAmount = accountData.frozen; if (frozenAmount == 0) { if (minWeeks == 0) minWeeks = 1; uint32[65535] storage unlocks = accountWeeklyUnlocks[account]; uint256 systemWeek = getWeek(); uint256 currentWeek = systemWeek + minWeeks; uint256 maxLockWeek = systemWeek + MAX_LOCK_WEEKS; uint256[] memory unlockWeeks = new uint256[](MAX_LOCK_WEEKS); uint256 bitfield = accountData.updateWeeks[currentWeek / 256] >> (currentWeek % 256); uint256 length; while (currentWeek <= maxLockWeek) { if (bitfield & uint256(1) == 1) { unlockWeeks[length] = currentWeek; length++; } currentWeek++; if (currentWeek % 256 == 0) { bitfield = accountData.updateWeeks[currentWeek / 256]; } else { bitfield = bitfield >> 1; } } lockData = new LockData[](length); uint256 x = length; // increment i, decrement x so LockData is ordered from longest to shortest duration for (uint256 i = 0; x != 0; i++) { x--; uint256 idx = unlockWeeks[x]; lockData[i] = LockData({ weeksToUnlock: idx - systemWeek, amount: unlocks[idx] }); } } return (lockData, frozenAmount); } /** @notice Get withdrawal and penalty amounts when withdrawing locked tokens @param account Account that will withdraw locked tokens @param amountToWithdraw Desired withdrawal amount, divided by `lockToTokenRatio` @return amountWithdrawn Actual amount withdrawn. If `amountToWithdraw` exceeds the max possible withdrawal, the return value is the max amount received after paying the penalty. @return penaltyAmountPaid The amount paid in penalty to perform this withdrawal */ function getWithdrawWithPenaltyAmounts( address account, uint256 amountToWithdraw ) external view returns (uint256 amountWithdrawn, uint256 penaltyAmountPaid) { AccountData storage accountData = accountLockData[account]; uint32[65535] storage unlocks = accountWeeklyUnlocks[account]; if (amountToWithdraw != type(uint256).max) amountToWithdraw *= lockToTokenRatio; // first we apply the unlocked balance without penalty uint256 unlocked = accountData.unlocked * lockToTokenRatio; if (unlocked >= amountToWithdraw) { return (amountToWithdraw, 0); } uint256 remaining = amountToWithdraw - unlocked; uint256 penaltyTotal; uint256 accountWeek = accountData.week; uint256 systemWeek = getWeek(); uint256 offset = systemWeek - accountWeek; uint256 bitfield = accountData.updateWeeks[accountWeek / 256]; // `weeksToUnlock < MAX_LOCK_WEEKS` stops iteration prior to the final week for (uint256 weeksToUnlock = 1; weeksToUnlock < MAX_LOCK_WEEKS; weeksToUnlock++) { accountWeek++; if (accountWeek % 256 == 0) { bitfield = accountData.updateWeeks[accountWeek / 256]; } if ((bitfield >> (accountWeek % 256)) & uint256(1) == 1) { uint256 lockAmount = unlocks[accountWeek] * lockToTokenRatio; uint256 penaltyOnAmount = 0; if (accountWeek > systemWeek) { // only apply the penalty if the lock has not expired penaltyOnAmount = (lockAmount * (weeksToUnlock - offset)) / MAX_LOCK_WEEKS; } if (lockAmount - penaltyOnAmount > remaining) { // after penalty, locked amount exceeds remaining required balance // we can complete the withdrawal using only a portion of this lock penaltyOnAmount = (remaining * MAX_LOCK_WEEKS) / (MAX_LOCK_WEEKS - (weeksToUnlock - offset)) - remaining; uint256 dust = ((penaltyOnAmount + remaining) % lockToTokenRatio); if (dust > 0) penaltyOnAmount += lockToTokenRatio - dust; penaltyTotal += penaltyOnAmount; remaining = 0; } else { // after penalty, locked amount does not exceed remaining required balance // the entire lock must be used in the withdrawal penaltyTotal += penaltyOnAmount; remaining -= lockAmount - penaltyOnAmount; } if (remaining == 0) { break; } } } amountToWithdraw -= remaining; return (amountToWithdraw, penaltyTotal); } /** @notice Get the current total lock weight */ function getTotalWeight() external view returns (uint256) { return getTotalWeightAt(getWeek()); } /** @notice Get the total lock weight for a given week */ function getTotalWeightAt(uint256 week) public view returns (uint256) { uint256 systemWeek = getWeek(); if (week > systemWeek) return 0; uint32 updatedWeek = totalUpdatedWeek; if (week <= updatedWeek) return totalWeeklyWeights[week]; uint32 rate = totalDecayRate; uint40 weight = totalWeeklyWeights[updatedWeek]; if (rate == 0 || updatedWeek >= systemWeek) { return weight; } while (updatedWeek < systemWeek) { updatedWeek++; weight -= rate; rate -= totalWeeklyUnlocks[updatedWeek]; } return weight; } /** @notice Get the current lock weight for an account @dev Also updates local storage values for this account. Using this function over it's `view` counterpart is preferred for contract -> contract interactions. */ function getAccountWeightWrite(address account) external returns (uint256) { return _weeklyWeightWrite(account); } /** @notice Get the current total lock weight @dev Also updates local storage values for total weights. Using this function over it's `view` counterpart is preferred for contract -> contract interactions. */ function getTotalWeightWrite() public returns (uint256) { uint256 week = getWeek(); uint32 rate = totalDecayRate; uint32 updatedWeek = totalUpdatedWeek; uint40 weight = totalWeeklyWeights[updatedWeek]; if (weight == 0) { totalUpdatedWeek = uint16(week); return 0; } while (updatedWeek < week) { updatedWeek++; weight -= rate; totalWeeklyWeights[updatedWeek] = weight; rate -= totalWeeklyUnlocks[updatedWeek]; } totalDecayRate = rate; totalUpdatedWeek = uint16(week); return weight; } /** @notice Deposit tokens into the contract to create a new lock. @dev A lock is created for a given number of weeks. Minimum 1, maximum `MAX_LOCK_WEEKS`. An account can have multiple locks active at the same time. The account's "lock weight" is calculated as the sum of [number of tokens] * [weeks until unlock] for all active locks. At the start of each new week, each lock's weeks until unlock is reduced by 1. Locks that reach 0 weeks no longer receive any weight, and tokens may be withdrawn by calling `withdrawExpiredLocks`. @param _account Address to create a new lock for (does not have to be the caller) @param _amount Amount of tokens to lock. This balance transfered from the caller. @param _weeks The number of weeks for the lock */ function lock(address _account, uint256 _amount, uint256 _weeks) external returns (bool) { require(_weeks > 0, "Min 1 week"); require(_amount > 0, "Amount must be nonzero"); _lock(_account, _amount, _weeks); lockToken.transferToLocker(msg.sender, _amount * lockToTokenRatio); return true; } function _lock(address _account, uint256 _amount, uint256 _weeks) internal { require(_weeks <= MAX_LOCK_WEEKS, "Exceeds MAX_LOCK_WEEKS"); AccountData storage accountData = accountLockData[_account]; uint256 accountWeight = _weeklyWeightWrite(_account); uint256 totalWeight = getTotalWeightWrite(); uint256 systemWeek = getWeek(); uint256 frozen = accountData.frozen; if (frozen > 0) { accountData.frozen = uint32(frozen + _amount); _weeks = MAX_LOCK_WEEKS; } else { // disallow a 1 week lock in the final 3 days of the week if (_weeks == 1 && block.timestamp % 1 weeks > 4 days) _weeks = 2; accountData.locked = uint32(accountData.locked + _amount); totalDecayRate = uint32(totalDecayRate + _amount); uint32[65535] storage unlocks = accountWeeklyUnlocks[_account]; uint256 unlockWeek = systemWeek + _weeks; uint256 previous = unlocks[unlockWeek]; // modify weekly unlocks and unlock bitfield unlocks[unlockWeek] = uint32(previous + _amount); totalWeeklyUnlocks[unlockWeek] += uint32(_amount); if (previous == 0) { uint256 idx = unlockWeek / 256; uint256 bitfield = accountData.updateWeeks[idx] | (uint256(1) << (unlockWeek % 256)); accountData.updateWeeks[idx] = bitfield; } } // update and adjust account weight and decay rate accountWeeklyWeights[_account][systemWeek] = uint40(accountWeight + _amount * _weeks); // update and modify total weight totalWeeklyWeights[systemWeek] = uint40(totalWeight + _amount * _weeks); emit LockCreated(_account, _amount, _weeks); } /** @notice Extend the length of an existing lock. @param _amount Amount of tokens to extend the lock for. When the value given equals the total size of the existing lock, the entire lock is moved. If the amount is less, then the lock is effectively split into two locks, with a portion of the balance extended to the new length and the remaining balance at the old length. @param _weeks The number of weeks for the lock that is being extended. @param _newWeeks The number of weeks to extend the lock until. */ function extendLock( uint256 _amount, uint256 _weeks, uint256 _newWeeks ) external notFrozen(msg.sender) returns (bool) { require(_weeks > 0, "Min 1 week"); require(_newWeeks <= MAX_LOCK_WEEKS, "Exceeds MAX_LOCK_WEEKS"); require(_weeks < _newWeeks, "newWeeks must be greater than weeks"); require(_amount > 0, "Amount must be nonzero"); AccountData storage accountData = accountLockData[msg.sender]; uint256 systemWeek = getWeek(); uint256 increase = (_newWeeks - _weeks) * _amount; uint32[65535] storage unlocks = accountWeeklyUnlocks[msg.sender]; // update and adjust account weight // current decay rate is unaffected when extending uint256 weight = _weeklyWeightWrite(msg.sender); accountWeeklyWeights[msg.sender][systemWeek] = uint40(weight + increase); // reduce account weekly unlock for previous week and modify bitfield uint256 changedWeek = systemWeek + _weeks; uint256 previous = unlocks[changedWeek]; unlocks[changedWeek] = uint32(previous - _amount); totalWeeklyUnlocks[changedWeek] -= uint32(_amount); if (previous == _amount) { uint256 idx = changedWeek / 256; uint256 bitfield = accountData.updateWeeks[idx] & ~(uint256(1) << (changedWeek % 256)); accountData.updateWeeks[idx] = bitfield; } // increase account weekly unlock for new week and modify bitfield changedWeek = systemWeek + _newWeeks; previous = unlocks[changedWeek]; unlocks[changedWeek] = uint32(previous + _amount); totalWeeklyUnlocks[changedWeek] += uint32(_amount); if (previous == 0) { uint256 idx = changedWeek / 256; uint256 bitfield = accountData.updateWeeks[idx] | (uint256(1) << (changedWeek % 256)); accountData.updateWeeks[idx] = bitfield; } // update and modify total weight totalWeeklyWeights[systemWeek] = uint40(getTotalWeightWrite() + increase); emit LockExtended(msg.sender, _amount, _weeks, _newWeeks); return true; } /** @notice Deposit tokens into the contract to create multiple new locks. @param _account Address to create new locks for (does not have to be the caller) @param newLocks Array of [(amount, weeks), ...] where amount is the amount of tokens to lock, and weeks is the number of weeks for the lock. All tokens to be locked are transferred from the caller. */ function lockMany(address _account, LockData[] calldata newLocks) external notFrozen(_account) returns (bool) { AccountData storage accountData = accountLockData[_account]; uint32[65535] storage unlocks = accountWeeklyUnlocks[_account]; // update account weight uint256 accountWeight = _weeklyWeightWrite(_account); uint256 systemWeek = getWeek(); // copy maybe-updated bitfield entries to memory uint256[2] memory bitfield = [ accountData.updateWeeks[systemWeek / 256], accountData.updateWeeks[(systemWeek / 256) + 1] ]; uint256 increasedAmount; uint256 increasedWeight; // iterate new locks and store intermediate values in memory where possible uint256 length = newLocks.length; for (uint256 i = 0; i < length; i++) { uint256 amount = newLocks[i].amount; uint256 week = newLocks[i].weeksToUnlock; require(amount > 0, "Amount must be nonzero"); require(week > 0, "Min 1 week"); require(week <= MAX_LOCK_WEEKS, "Exceeds MAX_LOCK_WEEKS"); // disallow a 1 week lock in the final 3 days of the week if (week == 1 && block.timestamp % 1 weeks > 4 days) week = 2; increasedAmount += amount; increasedWeight += amount * week; uint256 unlockWeek = systemWeek + week; uint256 previous = unlocks[unlockWeek]; unlocks[unlockWeek] = uint32(previous + amount); totalWeeklyUnlocks[unlockWeek] += uint32(amount); if (previous == 0) { uint256 idx = (unlockWeek / 256) - (systemWeek / 256); bitfield[idx] = bitfield[idx] | (uint256(1) << (unlockWeek % 256)); } } // write updated bitfield to storage accountData.updateWeeks[systemWeek / 256] = bitfield[0]; accountData.updateWeeks[(systemWeek / 256) + 1] = bitfield[1]; lockToken.transferToLocker(msg.sender, increasedAmount * lockToTokenRatio); // update account and total weight / decay storage values accountWeeklyWeights[_account][systemWeek] = uint40(accountWeight + increasedWeight); totalWeeklyWeights[systemWeek] = uint40(getTotalWeightWrite() + increasedWeight); accountData.locked = uint32(accountData.locked + increasedAmount); totalDecayRate = uint32(totalDecayRate + increasedAmount); emit LocksCreated(_account, newLocks); return true; } /** @notice Extend the length of multiple existing locks. @param newExtendLocks Array of [(amount, weeks, newWeeks), ...] where amount is the amount of tokens to extend the lock for, weeks is the current number of weeks for the lock that is being extended, and newWeeks is the number of weeks to extend the lock until. */ function extendMany(ExtendLockData[] calldata newExtendLocks) external notFrozen(msg.sender) returns (bool) { AccountData storage accountData = accountLockData[msg.sender]; uint32[65535] storage unlocks = accountWeeklyUnlocks[msg.sender]; // update account weight uint256 accountWeight = _weeklyWeightWrite(msg.sender); uint256 systemWeek = getWeek(); // copy maybe-updated bitfield entries to memory uint256[2] memory bitfield = [ accountData.updateWeeks[systemWeek / 256], accountData.updateWeeks[(systemWeek / 256) + 1] ]; uint256 increasedWeight; // iterate extended locks and store intermediate values in memory where possible uint256 length = newExtendLocks.length; for (uint256 i = 0; i < length; i++) { uint256 amount = newExtendLocks[i].amount; uint256 oldWeeks = newExtendLocks[i].currentWeeks; uint256 newWeeks = newExtendLocks[i].newWeeks; require(oldWeeks > 0, "Min 1 week"); require(newWeeks <= MAX_LOCK_WEEKS, "Exceeds MAX_LOCK_WEEKS"); require(oldWeeks < newWeeks, "newWeeks must be greater than weeks"); require(amount > 0, "Amount must be nonzero"); increasedWeight += (newWeeks - oldWeeks) * amount; // reduce account weekly unlock for previous week and modify bitfield oldWeeks += systemWeek; uint256 previous = unlocks[oldWeeks]; unlocks[oldWeeks] = uint32(previous - amount); totalWeeklyUnlocks[oldWeeks] -= uint32(amount); if (previous == amount) { uint256 idx = (oldWeeks / 256) - (systemWeek / 256); bitfield[idx] = bitfield[idx] & ~(uint256(1) << (oldWeeks % 256)); } // increase account weekly unlock for new week and modify bitfield newWeeks += systemWeek; previous = unlocks[newWeeks]; unlocks[newWeeks] = uint32(previous + amount); totalWeeklyUnlocks[newWeeks] += uint32(amount); if (previous == 0) { uint256 idx = (newWeeks / 256) - (systemWeek / 256); bitfield[idx] = bitfield[idx] | (uint256(1) << (newWeeks % 256)); } } // write updated bitfield to storage accountData.updateWeeks[systemWeek / 256] = bitfield[0]; accountData.updateWeeks[(systemWeek / 256) + 1] = bitfield[1]; accountWeeklyWeights[msg.sender][systemWeek] = uint40(accountWeight + increasedWeight); totalWeeklyWeights[systemWeek] = uint40(getTotalWeightWrite() + increasedWeight); emit LocksExtended(msg.sender, newExtendLocks); return true; } /** @notice Freeze all locks for the caller @dev When an account's locks are frozen, the weeks-to-unlock does not decay. All other functionality remains the same; the account can continue to lock, extend locks, and withdraw tokens. Freezing greatly reduces gas costs for actions such as emissions voting. */ function freeze() external notFrozen(msg.sender) { AccountData storage accountData = accountLockData[msg.sender]; uint32[65535] storage unlocks = accountWeeklyUnlocks[msg.sender]; uint256 accountWeight = _weeklyWeightWrite(msg.sender); uint256 totalWeight = getTotalWeightWrite(); // remove account locked balance from the total decay rate uint256 locked = accountData.locked; require(locked > 0, "No locked balance"); totalDecayRate = uint32(totalDecayRate - locked); accountData.frozen = uint32(locked); accountData.locked = 0; uint256 systemWeek = getWeek(); accountWeeklyWeights[msg.sender][systemWeek] = uint40(locked * MAX_LOCK_WEEKS); totalWeeklyWeights[systemWeek] = uint40(totalWeight - accountWeight + locked * MAX_LOCK_WEEKS); // use bitfield to iterate acount unlocks and subtract them from the total unlocks uint256 bitfield = accountData.updateWeeks[systemWeek / 256] >> (systemWeek % 256); while (locked > 0) { systemWeek++; if (systemWeek % 256 == 0) { bitfield = accountData.updateWeeks[systemWeek / 256]; accountData.updateWeeks[(systemWeek / 256) - 1] = 0; } else { bitfield = bitfield >> 1; } if (bitfield & uint256(1) == 1) { uint32 amount = unlocks[systemWeek]; unlocks[systemWeek] = 0; totalWeeklyUnlocks[systemWeek] -= amount; locked -= amount; } } accountData.updateWeeks[systemWeek / 256] = 0; emit LocksFrozen(msg.sender, locked); } /** @notice Unfreeze all locks for the caller @dev When an account's locks are unfrozen, the weeks-to-unlock decay normally. This is the default locking behaviour for each account. Unfreezing locks also updates the frozen status within `IncentiveVoter` - otherwise it could be possible for accounts to have a larger registered vote weight than their actual lock weight. @param keepIncentivesVote If true, existing incentive votes are preserved when updating the frozen status within `IncentiveVoter`. Voting with unfrozen weight uses significantly more gas than voting with frozen weight. If the caller has many active locks and/or many votes, it will be much cheaper to set this value to false. */ function unfreeze(bool keepIncentivesVote) external { AccountData storage accountData = accountLockData[msg.sender]; uint32[65535] storage unlocks = accountWeeklyUnlocks[msg.sender]; uint256 frozen = accountData.frozen; require(frozen > 0, "Locks already unfrozen"); // unfreeze the caller's registered vote weights incentiveVoter.unfreeze(msg.sender, keepIncentivesVote); // update account weights and get the current account week _weeklyWeightWrite(msg.sender); getTotalWeightWrite(); // add account decay to the total decay rate totalDecayRate = uint32(totalDecayRate + frozen); accountData.locked = uint32(frozen); accountData.frozen = 0; uint256 systemWeek = getWeek(); uint256 unlockWeek = systemWeek + MAX_LOCK_WEEKS; // modify weekly unlocks and unlock bitfield unlocks[unlockWeek] = uint32(frozen); totalWeeklyUnlocks[unlockWeek] += uint32(frozen); uint256 idx = unlockWeek / 256; uint256 bitfield = accountData.updateWeeks[idx] | (uint256(1) << (unlockWeek % 256)); accountData.updateWeeks[idx] = bitfield; emit LocksUnfrozen(msg.sender, frozen); } /** @notice Withdraw tokens from locks that have expired @param _weeks Optional number of weeks for the re-locking. If 0 the full amount is transferred back to the user. */ function withdrawExpiredLocks(uint256 _weeks) external returns (bool) { _weeklyWeightWrite(msg.sender); getTotalWeightWrite(); AccountData storage accountData = accountLockData[msg.sender]; uint256 unlocked = accountData.unlocked; require(unlocked > 0, "No unlocked tokens"); accountData.unlocked = 0; if (_weeks > 0) { _lock(msg.sender, unlocked, _weeks); } else { lockToken.transfer(msg.sender, unlocked * lockToTokenRatio); emit LocksWithdrawn(msg.sender, unlocked, 0); } return true; } /** @notice Pay a penalty to withdraw locked tokens @dev Withdrawals are processed starting with the lock that will expire soonest. The penalty starts at 100% and decays linearly based on the number of weeks remaining until the tokens unlock. The exact calculation used is: [total amount] * [weeks to unlock] / MAX_LOCK_WEEKS = [penalty amount] @param amountToWithdraw Amount to withdraw, divided by `lockToTokenRatio`. This is the same number of tokens that will be received; the penalty amount is taken on top of this. Reverts if the caller's locked balances are insufficient to cover both the withdrawal and penalty amounts. Setting this value as `type(uint256).max` withdrawals the entire available locked balance, excluding any lock at `MAX_LOCK_WEEKS` as the penalty on this lock would be 100%. @return uint256 Amount of tokens withdrawn */ function withdrawWithPenalty(uint256 amountToWithdraw) external notFrozen(msg.sender) returns (uint256) { require(penaltyWithdrawalsEnabled, "Penalty withdrawals are disabled"); AccountData storage accountData = accountLockData[msg.sender]; uint32[65535] storage unlocks = accountWeeklyUnlocks[msg.sender]; uint256 weight = _weeklyWeightWrite(msg.sender); if (amountToWithdraw != type(uint256).max) amountToWithdraw *= lockToTokenRatio; // start by withdrawing unlocked balance without penalty uint256 unlocked = accountData.unlocked * lockToTokenRatio; if (unlocked >= amountToWithdraw) { accountData.unlocked = uint32((unlocked - amountToWithdraw) / lockToTokenRatio); lockToken.transfer(msg.sender, amountToWithdraw); return amountToWithdraw; } // clear the caller's registered vote weight incentiveVoter.clearRegisteredWeight(msg.sender); uint256 remaining = amountToWithdraw; if (unlocked > 0) { remaining -= unlocked; accountData.unlocked = 0; } uint256 systemWeek = getWeek(); uint256 bitfield = accountData.updateWeeks[systemWeek / 256]; uint256 penaltyTotal; uint256 decreasedWeight; // `weeksToUnlock < MAX_LOCK_WEEKS` stops iteration prior to the final week for (uint256 weeksToUnlock = 1; weeksToUnlock < MAX_LOCK_WEEKS; weeksToUnlock++) { systemWeek++; if (systemWeek % 256 == 0) { accountData.updateWeeks[systemWeek / 256 - 1] = 0; bitfield = accountData.updateWeeks[systemWeek / 256]; } if ((bitfield >> (systemWeek % 256)) & uint256(1) == 1) { uint256 lockAmount = unlocks[systemWeek] * lockToTokenRatio; uint256 penaltyOnAmount = (lockAmount * weeksToUnlock) / MAX_LOCK_WEEKS; if (lockAmount - penaltyOnAmount > remaining) { // after penalty, locked amount exceeds remaining required balance // we can complete the withdrawal using only a portion of this lock penaltyOnAmount = (remaining * MAX_LOCK_WEEKS) / (MAX_LOCK_WEEKS - weeksToUnlock) - remaining; uint256 dust = ((penaltyOnAmount + remaining) % lockToTokenRatio); if (dust > 0) penaltyOnAmount += lockToTokenRatio - dust; penaltyTotal += penaltyOnAmount; uint256 lockReduceAmount = (penaltyOnAmount + remaining) / lockToTokenRatio; decreasedWeight += lockReduceAmount * weeksToUnlock; unlocks[systemWeek] -= uint32(lockReduceAmount); totalWeeklyUnlocks[systemWeek] -= uint32(lockReduceAmount); remaining = 0; } else { // after penalty, locked amount does not exceed remaining required balance // the entire lock must be used in the withdrawal penaltyTotal += penaltyOnAmount; decreasedWeight += (lockAmount / lockToTokenRatio) * weeksToUnlock; bitfield = bitfield & ~(uint256(1) << (systemWeek % 256)); unlocks[systemWeek] = 0; totalWeeklyUnlocks[systemWeek] -= uint32(lockAmount / lockToTokenRatio); remaining -= lockAmount - penaltyOnAmount; } if (remaining == 0) { break; } } } accountData.updateWeeks[systemWeek / 256] = bitfield; if (amountToWithdraw == type(uint256).max) { amountToWithdraw -= remaining; } else { require(remaining == 0, "Insufficient balance after fees"); } accountData.locked -= uint32((amountToWithdraw + penaltyTotal - unlocked) / lockToTokenRatio); totalDecayRate -= uint32((amountToWithdraw + penaltyTotal - unlocked) / lockToTokenRatio); systemWeek = getWeek(); accountWeeklyWeights[msg.sender][systemWeek] = uint40(weight - decreasedWeight); totalWeeklyWeights[systemWeek] = uint40(getTotalWeightWrite() - decreasedWeight); lockToken.transfer(msg.sender, amountToWithdraw); lockToken.transfer(prismaCore.feeReceiver(), penaltyTotal); emit LocksWithdrawn(msg.sender, amountToWithdraw, penaltyTotal); return amountToWithdraw; } /** @dev Updates all data for a given account and returns the account's current weight and week */ function _weeklyWeightWrite(address account) internal returns (uint256 weight) { AccountData storage accountData = accountLockData[account]; uint32[65535] storage weeklyUnlocks = accountWeeklyUnlocks[account]; uint40[65535] storage weeklyWeights = accountWeeklyWeights[account]; uint256 systemWeek = getWeek(); uint256 accountWeek = accountData.week; weight = weeklyWeights[accountWeek]; if (accountWeek == systemWeek) return weight; if (accountData.frozen > 0) { while (systemWeek > accountWeek) { accountWeek++; weeklyWeights[accountWeek] = uint40(weight); } accountData.week = uint16(systemWeek); return weight; } // if account is not frozen and locked balance is 0, we only need to update the account week uint256 locked = accountData.locked; if (locked == 0) { if (accountWeek < systemWeek) { accountData.week = uint16(systemWeek); } return 0; } uint256 unlocked; uint256 bitfield = accountData.updateWeeks[accountWeek / 256] >> (accountWeek % 256); while (accountWeek < systemWeek) { accountWeek++; weight -= locked; weeklyWeights[accountWeek] = uint40(weight); if (accountWeek % 256 == 0) { bitfield = accountData.updateWeeks[accountWeek / 256]; } else { bitfield = bitfield >> 1; } if (bitfield & uint256(1) == 1) { uint32 amount = weeklyUnlocks[accountWeek]; locked -= amount; unlocked += amount; if (locked == 0) { // if locked balance hits 0, there are no further tokens to unlock accountWeek = systemWeek; break; } } } accountData.unlocked = uint32(accountData.unlocked + unlocked); accountData.locked = uint32(locked); accountData.week = uint16(accountWeek); return weight; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import "IPrismaCore.sol"; /** @title Prisma Ownable @notice Contracts inheriting `PrismaOwnable` have the same owner as `PrismaCore`. The ownership cannot be independently modified or renounced. */ contract PrismaOwnable { IPrismaCore public immutable PRISMA_CORE; constructor(address _prismaCore) { PRISMA_CORE = IPrismaCore(_prismaCore); } modifier onlyOwner() { require(msg.sender == PRISMA_CORE.owner(), "Only owner"); _; } function owner() public view returns (address) { return PRISMA_CORE.owner(); } function guardian() public view returns (address) { return PRISMA_CORE.guardian(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IPrismaCore { event FeeReceiverSet(address feeReceiver); event GuardianSet(address guardian); event NewOwnerAccepted(address oldOwner, address owner); event NewOwnerCommitted(address owner, address pendingOwner, uint256 deadline); event NewOwnerRevoked(address owner, address revokedOwner); event Paused(); event PriceFeedSet(address priceFeed); event Unpaused(); function acceptTransferOwnership() external; function commitTransferOwnership(address newOwner) external; function revokeTransferOwnership() external; function setFeeReceiver(address _feeReceiver) external; function setGuardian(address _guardian) external; function setPaused(bool _paused) external; function setPriceFeed(address _priceFeed) external; function OWNERSHIP_TRANSFER_DELAY() external view returns (uint256); function feeReceiver() external view returns (address); function guardian() external view returns (address); function owner() external view returns (address); function ownershipTransferDeadline() external view returns (uint256); function paused() external view returns (bool); function pendingOwner() external view returns (address); function priceFeed() external view returns (address); function startTime() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import "IPrismaCore.sol"; /** @title Prisma System Start Time @dev Provides a unified `startTime` and `getWeek`, used for emissions. */ contract SystemStart { uint256 immutable startTime; constructor(address prismaCore) { startTime = IPrismaCore(prismaCore).startTime(); } function getWeek() public view returns (uint256 week) { return (block.timestamp - startTime) / 1 weeks; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IIncentiveVoting { struct Vote { uint256 id; uint256 points; } struct LockData { uint256 amount; uint256 weeksToUnlock; } event AccountWeightRegistered( address indexed account, uint256 indexed week, uint256 frozenBalance, LockData[] registeredLockData ); event ClearedVotes(address indexed account, uint256 indexed week); event NewVotes(address indexed account, uint256 indexed week, Vote[] newVotes, uint256 totalPointsUsed); function clearRegisteredWeight(address account) external returns (bool); function clearVote(address account) external; function getReceiverVotePct(uint256 id, uint256 week) external returns (uint256); function getReceiverWeightWrite(uint256 idx) external returns (uint256); function getTotalWeightWrite() external returns (uint256); function registerAccountWeight(address account, uint256 minWeeks) external; function registerAccountWeightAndVote(address account, uint256 minWeeks, Vote[] calldata votes) external; function registerNewReceiver() external returns (uint256); function setDelegateApproval(address _delegate, bool _isApproved) external; function unfreeze(address account, bool keepVote) external returns (bool); function vote(address account, Vote[] calldata votes, bool clearPrevious) external; function MAX_LOCK_WEEKS() external view returns (uint256); function MAX_POINTS() external view returns (uint256); function getAccountCurrentVotes(address account) external view returns (Vote[] memory votes); function getAccountRegisteredLocks( address account ) external view returns (uint256 frozenWeight, LockData[] memory lockData); function getReceiverWeight(uint256 idx) external view returns (uint256); function getReceiverWeightAt(uint256 idx, uint256 week) external view returns (uint256); function getTotalWeight() external view returns (uint256); function getTotalWeightAt(uint256 week) external view returns (uint256); function getWeek() external view returns (uint256 week); function isApprovedDelegate(address owner, address caller) external view returns (bool isApproved); function receiverCount() external view returns (uint256); function receiverDecayRate(uint256) external view returns (uint32); function receiverUpdatedWeek(uint256) external view returns (uint16); function receiverWeeklyUnlocks(uint256, uint256) external view returns (uint32); function tokenLocker() external view returns (address); function totalDecayRate() external view returns (uint32); function totalUpdatedWeek() external view returns (uint16); function totalWeeklyUnlocks(uint256) external view returns (uint32); function vault() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IPrismaToken { event Approval(address indexed owner, address indexed spender, uint256 value); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event ReceiveFromChain(uint16 indexed _srcChainId, address indexed _to, uint256 _amount); event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash); event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes _toAddress, uint256 _amount); event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint256 _minDstGas); event SetPrecrime(address precrime); event SetTrustedRemote(uint16 _remoteChainId, bytes _path); event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress); event SetUseCustomAdapterParams(bool _useCustomAdapterParams); event Transfer(address indexed from, address indexed to, uint256 value); function approve(address spender, uint256 amount) external returns (bool); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external; function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external; function mintToVault(uint256 _totalSupply) external returns (bool); function nonblockingLzReceive( uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload ) external; function permit( address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function renounceOwnership() external; function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external; function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external; function setPayloadSizeLimit(uint16 _dstChainId, uint256 _size) external; function setPrecrime(address _precrime) external; function setReceiveVersion(uint16 _version) external; function setSendVersion(uint16 _version) external; function setTrustedRemote(uint16 _srcChainId, bytes calldata _path) external; function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external; function setUseCustomAdapterParams(bool _useCustomAdapterParams) external; function transfer(address to, uint256 amount) external returns (bool); function transferFrom(address from, address to, uint256 amount) external returns (bool); function transferOwnership(address newOwner) external; function transferToLocker(address sender, uint256 amount) external returns (bool); function retryMessage( uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload ) external payable; function sendFrom( address _from, uint16 _dstChainId, bytes calldata _toAddress, uint256 _amount, address _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams ) external payable; function DEFAULT_PAYLOAD_SIZE_LIMIT() external view returns (uint256); function NO_EXTRA_GAS() external view returns (uint256); function PT_SEND() external view returns (uint16); function allowance(address owner, address spender) external view returns (uint256); function balanceOf(address account) external view returns (uint256); function circulatingSupply() external view returns (uint256); function decimals() external view returns (uint8); function domainSeparator() external view returns (bytes32); function estimateSendFee( uint16 _dstChainId, bytes calldata _toAddress, uint256 _amount, bool _useZro, bytes calldata _adapterParams ) external view returns (uint256 nativeFee, uint256 zroFee); function failedMessages(uint16, bytes calldata, uint64) external view returns (bytes32); function getConfig( uint16 _version, uint16 _chainId, address, uint256 _configType ) external view returns (bytes memory); function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory); function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool); function locker() external view returns (address); function lzEndpoint() external view returns (address); function maxTotalSupply() external view returns (uint256); function minDstGasLookup(uint16, uint16) external view returns (uint256); function name() external view returns (string memory); function nonces(address owner) external view returns (uint256); function owner() external view returns (address); function payloadSizeLimitLookup(uint16) external view returns (uint256); function permitTypeHash() external view returns (bytes32); function precrime() external view returns (address); function supportsInterface(bytes4 interfaceId) external view returns (bool); function symbol() external view returns (string memory); function token() external view returns (address); function totalSupply() external view returns (uint256); function trustedRemoteLookup(uint16) external view returns (bytes memory); function useCustomAdapterParams() external view returns (bool); function vault() external view returns (address); function version() external view returns (string memory); }
{ "evmVersion": "paris", "optimizer": { "enabled": true, "runs": 200 }, "libraries": { "TokenLocker.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_prismaCore","type":"address"},{"internalType":"contract IPrismaToken","name":"_token","type":"address"},{"internalType":"contract IIncentiveVoting","name":"_voter","type":"address"},{"internalType":"address","name":"_manager","type":"address"},{"internalType":"uint256","name":"_lockToTokenRatio","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_weeks","type":"uint256"}],"name":"LockCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_weeks","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newWeeks","type":"uint256"}],"name":"LockExtended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"weeksToUnlock","type":"uint256"}],"indexed":false,"internalType":"struct TokenLocker.LockData[]","name":"newLocks","type":"tuple[]"}],"name":"LocksCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"currentWeeks","type":"uint256"},{"internalType":"uint256","name":"newWeeks","type":"uint256"}],"indexed":false,"internalType":"struct TokenLocker.ExtendLockData[]","name":"locks","type":"tuple[]"}],"name":"LocksExtended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LocksFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LocksUnfrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"penalty","type":"uint256"}],"name":"LocksWithdrawn","type":"event"},{"inputs":[],"name":"MAX_LOCK_WEEKS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRISMA_CORE","outputs":[{"internalType":"contract IPrismaCore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowPenaltyWithdrawAfter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_weeks","type":"uint256"},{"internalType":"uint256","name":"_newWeeks","type":"uint256"}],"name":"extendLock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"currentWeeks","type":"uint256"},{"internalType":"uint256","name":"newWeeks","type":"uint256"}],"internalType":"struct TokenLocker.ExtendLockData[]","name":"newExtendLocks","type":"tuple[]"}],"name":"extendMany","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"minWeeks","type":"uint256"}],"name":"getAccountActiveLocks","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"weeksToUnlock","type":"uint256"}],"internalType":"struct TokenLocker.LockData[]","name":"lockData","type":"tuple[]"},{"internalType":"uint256","name":"frozenAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountBalances","outputs":[{"internalType":"uint256","name":"locked","type":"uint256"},{"internalType":"uint256","name":"unlocked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"week","type":"uint256"}],"name":"getAccountWeightAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountWeightWrite","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getTotalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"week","type":"uint256"}],"name":"getTotalWeightAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalWeightWrite","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getWeek","outputs":[{"internalType":"uint256","name":"week","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amountToWithdraw","type":"uint256"}],"name":"getWithdrawWithPenaltyAmounts","outputs":[{"internalType":"uint256","name":"amountWithdrawn","type":"uint256"},{"internalType":"uint256","name":"penaltyAmountPaid","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incentiveVoter","outputs":[{"internalType":"contract IIncentiveVoting","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_weeks","type":"uint256"}],"name":"lock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"weeksToUnlock","type":"uint256"}],"internalType":"struct TokenLocker.LockData[]","name":"newLocks","type":"tuple[]"}],"name":"lockMany","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockToTokenRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockToken","outputs":[{"internalType":"contract IPrismaToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"penaltyWithdrawalsEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prismaCore","outputs":[{"internalType":"contract IPrismaCore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"setAllowPenaltyWithdrawAfter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setPenaltyWithdrawalsEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalDecayRate","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUpdatedWeek","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"keepIncentivesVote","type":"bool"}],"name":"unfreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weeks","type":"uint256"}],"name":"withdrawExpiredLocks","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToWithdraw","type":"uint256"}],"name":"withdrawWithPenalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101606040523480156200001257600080fd5b50604051620049bd380380620049bd8339810160408190526200003591620000f0565b6001600160a01b0385166080819052604080516378e9792560e01b815290518792916378e979259160048083019260209291908290030181865afa15801562000082573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a8919062000164565b60a052506001600160a01b0393841660e052918316610100529282166101205291166101405260c0526200017e565b6001600160a01b0381168114620000ed57600080fd5b50565b600080600080600060a086880312156200010957600080fd5b85516200011681620000d7565b60208701519095506200012981620000d7565b60408701519094506200013c81620000d7565b60608701519093506200014f81620000d7565b80925050608086015190509295509295909350565b6000602082840312156200017757600080fd5b5051919050565b60805160a05160c05160e051610100516101205161014051614704620002b96000396000818161034f015261103e01526000818161032801526126eb01526000818161045801528181610c250152611ec60152600081816103cf015281816107e501528181611a5501528181611e3701528181612616015281816126bc015261352a0152600081816104310152818161081001528181611a8001528181611d4f01528181611d8201528181611dbf01528181612036015281816120f20152818161213301528181612174015281816122940152818161232401528181612475015281816124eb01528181613091015281816130c4015281816131dd015281816132b6015281816132f701526135550152600061283601526000818161047f01528181610e420152818161286901526133a701526147046000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c80638da5cb5b1161011a578063c5438b1b116100ad578063e2ab691d1161007c578063e2ab691d146104b4578063e8db55d0146104c7578063fb390a4f146104d4578063ff4819e1146104dd578063ffe60d2a1461050257600080fd5b8063c5438b1b1461042c578063c6cb63a214610453578063cc9641a81461047a578063d922150b146104a157600080fd5b8063bafacab9116100e9578063bafacab9146103c2578063bca7a9e2146103ca578063bd06aadf146103f1578063c373cb401461040457600080fd5b80638da5cb5b1461038c5780639e30c3ec14610394578063aac3751c1461039c578063b3655bc3146103af57600080fd5b8063508f28e5116101925780636b2c0ccb116101615780636b2c0ccb146103235780636ca32a9e1461034a5780638064d26814610371578063874d6d811461038457600080fd5b8063508f28e5146102cd57806362a5af3b146102e057806367a5b10b146102e85780636917e7fd1461031057600080fd5b80633ea01b34116101ce5780633ea01b3414610272578063446d530414610285578063452a93201461029a57806350735f6f146102ba57600080fd5b806306aba0e11461020057806307f93a381461021b57806312d02a981461022e57806317b45bb414610251575b600080fd5b610208610515565b6040519081526020015b60405180910390f35b61020861022936600461416d565b610527565b61024161023c366004614199565b61073b565b6040519015158152602001610212565b61026461025f36600461416d565b6108eb565b6040516102129291906141b2565b610208610280366004614205565b610b89565b610298610293366004614237565b610b97565b005b6102a2610e3e565b6040516001600160a01b039091168152602001610212565b6102086102c8366004614199565b610ec2565b6102416102db366004614199565b611031565b610298611141565b6102fb6102f6366004614205565b611517565b60408051928352602083019190915201610212565b61024161031e366004614254565b6116a3565b6102a27f000000000000000000000000000000000000000000000000000000000000000081565b6102a27f000000000000000000000000000000000000000000000000000000000000000081565b61020861037f366004614199565b611c86565b61020861282b565b6102a2612865565b6102086128c5565b6102086103aa366004614205565b612a54565b6102416103bd3660046142dc565b612a5f565b610208603481565b6102a27f000000000000000000000000000000000000000000000000000000000000000081565b6102fb6103ff36600461416d565b61305c565b60025461041990600160201b900461ffff1681565b60405161ffff9091168152602001610212565b6102087f000000000000000000000000000000000000000000000000000000000000000081565b6102a27f000000000000000000000000000000000000000000000000000000000000000081565b6102a27f000000000000000000000000000000000000000000000000000000000000000081565b6102416104af366004614237565b6133a3565b6102416104c2366004614351565b6134d4565b6000546102419060ff1681565b61020860015481565b6002546104ed9063ffffffff1681565b60405163ffffffff9091168152602001610212565b610241610510366004614386565b6135f4565b60006105226102c861282b565b905090565b600061053161282b565b82111561054057506000610735565b6001600160a01b0383166000908152614aaf60209081526040808320614aae8352818420614ab090935292208054600160601b900461ffff168581106105c257828661ffff8110610593576105936143b2565b600691828204019190066005029054906101000a900464ffffffffff1664ffffffffff16945050505050610735565b815463ffffffff166000848361ffff81106105df576105df6143b2565b600691828204019190066005029054906101000a900464ffffffffff1664ffffffffff169050816000148061062157508354600160401b900463ffffffff1615155b15610633579550610735945050505050565b6000610641610100856143de565b6001860161065161010087614408565b6101008110610662576106626143b2565b0154901c90505b8884101561072c578361067b8161441c565b945061068990508383614435565b9150610697610100856143de565b6000036106c857600185016106ae61010086614408565b61010081106106bf576106bf6143b2565b015490506106cc565b60011c5b60018116600103610727576000878561ffff81106106ec576106ec6143b2565b60088104919091015460079091166004026101000a900463ffffffff1690506107158185614435565b935083600003610725575061072c565b505b610669565b50955050505050505b92915050565b600061074633613a9e565b5061074f6128c5565b50336000908152614ab0602052604090208054600160201b900463ffffffff16806107b65760405162461bcd60e51b81526020600482015260126024820152714e6f20756e6c6f636b656420746f6b656e7360701b60448201526064015b60405180910390fd5b815467ffffffff000000001916825583156107db576107d6338286613dcc565b6108e1565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663a9059cbb336108357f000000000000000000000000000000000000000000000000000000000000000085614448565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a4919061445f565b50604080518281526000602082015233917f3dee403330631fb457dbb611d44e5abc933635841e5e65a403b794d26268ee78910160405180910390a25b5060019392505050565b6001600160a01b0382166000908152614ab0602052604081208054606092600160401b90910463ffffffff169190829003610b80578360000361092d57600193505b6001600160a01b0385166000908152614aaf602052604081209061094f61282b565b9050600061095d878361447c565b9050600061096c60348461447c565b6040805160348082526106a0820190925291925060009190602082016106808036833701905050905060006109a3610100856143de565b600188016109b361010087614408565b61010081106109c4576109c46143b2565b0154901c905060005b838511610a625760018216600103610a0b57848382815181106109f2576109f26143b2565b602090810291909101015280610a078161441c565b9150505b84610a158161441c565b9550610a259050610100866143de565b600003610a565760018801610a3c61010087614408565b6101008110610a4d57610a4d6143b2565b015491506109cd565b600182901c91506109cd565b8067ffffffffffffffff811115610a7b57610a7b61448f565b604051908082528060200260200182016040528015610ac057816020015b6040805180820190915260008082526020820152815260200190600190039081610a995790505b5099508060005b8115610b765781610ad7816144a5565b9250506000858381518110610aee57610aee6143b2565b6020026020010151905060405180604001604052808b8361ffff8110610b1657610b166143b2565b60088104919091015460079091166004026101000a900463ffffffff168152602001610b428b84614435565b8152508d8381518110610b5757610b576143b2565b6020026020010181905250508080610b6e9061441c565b915050610ac7565b5050505050505050505b505b9250929050565b60006107358261022961282b565b336000908152614ab060209081526040808320614aaf9092529091208154600160401b900463ffffffff1680610c085760405162461bcd60e51b81526020600482015260166024820152752637b1b5b99030b63932b0b23c903ab7333937bd32b760511b60448201526064016107ad565b6040516393101b4160e01b815233600482015284151560248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906393101b41906044016020604051808303816000875af1158015610c76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9a919061445f565b50610ca433613a9e565b50610cad6128c5565b50600254610cc290829063ffffffff1661447c565b6002805463ffffffff92831663ffffffff1990911617905583546bffffffff00000000ffffffff19169082161783556000610cfb61282b565b90506000610d0a60348361447c565b905082848261ffff8110610d2057610d206143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555082612aae8261ffff8110610d5f57610d5f6143b2565b600891828204019190066004028282829054906101000a900463ffffffff16610d8891906144bc565b92506101000a81548163ffffffff021916908363ffffffff160217905550600061010082610db69190614408565b90506000610dc6610100846143de565b6001901b87600101836101008110610de057610de06143b2565b01541790508087600101836101008110610dfc57610dfc6143b2565b015560405185815233907f891e32b677b13f3c41e0facb731a92c347d3803878526d8c2dc27c7e1b1bb0e0906020015b60405180910390a25050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e9e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052291906144d9565b600080610ecd61282b565b905080831115610ee05750600092915050565b600254600160201b900461ffff16808411610f365760038461ffff8110610f0957610f096143b2565b600691828204019190066005029054906101000a900464ffffffffff1664ffffffffff1692505050919050565b60025463ffffffff90811690600090600390841661ffff8110610f5b57610f5b6143b2565b600691828204019190066005029054906101000a900464ffffffffff1690508163ffffffff1660001480610f955750838363ffffffff1610155b15610faa5764ffffffffff1695945050505050565b838363ffffffff1610156110215782610fc2816144f6565b9350610fd6905063ffffffff831682614519565b9050612aae8363ffffffff1661ffff8110610ff357610ff36143b2565b600891828204019190066004029054906101000a900463ffffffff168261101a9190614537565b9150610faa565b64ffffffffff1695945050505050565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146110a05760405162461bcd60e51b815260206004820152601260248201527110b232b83637bcb6b2b73a26b0b730b3b2b960711b60448201526064016107ad565b600154156110de5760405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b60448201526064016107ad565b42821180156110f857506110f5426277f88061447c565b82105b6111385760405162461bcd60e51b81526020600482015260116024820152700496e76616c69642074696d657374616d7607c1b60448201526064016107ad565b50600190815590565b336000818152614ab06020526040902054600160401b900463ffffffff161561117c5760405162461bcd60e51b81526004016107ad90614554565b336000818152614ab060209081526040808320614aaf909252822090929091906111a590613a9e565b905060006111b16128c5565b845490915063ffffffff16806111fd5760405162461bcd60e51b81526020600482015260116024820152704e6f206c6f636b65642062616c616e636560781b60448201526064016107ad565b60025461121190829063ffffffff16614435565b6002805463ffffffff92831663ffffffff19918216179091558654918316600160401b02166bffffffff00000000ffffffff19909116178555600061125461282b565b9050611261603483614448565b336000908152614aae602052604090208261ffff8110611283576112836143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff1602179055506034826112bb9190614448565b6112c58585614435565b6112cf919061447c565b60038261ffff81106112e3576112e36143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555060006101008261131e91906143de565b6001880161132e61010085614408565b610100811061133f5761133f6143b2565b0154901c90505b82156114c057816113568161441c565b92506113669050610100836143de565b6000036113c8576001870161137d61010084614408565b610100811061138e5761138e6143b2565b0154905060006001808901906113a661010086614408565b6113b09190614435565b61010081106113c1576113c16143b2565b01556113cc565b60011c5b600181166001036114bb576000868361ffff81106113ec576113ec6143b2565b600891828204019190066004029054906101000a900463ffffffff1690506000878461ffff811061141f5761141f6143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555080612aae8461ffff811061145e5761145e6143b2565b600891828204019190066004028282829054906101000a900463ffffffff166114879190614537565b92506101000a81548163ffffffff021916908363ffffffff1602179055508063ffffffff16846114b79190614435565b9350505b611346565b6000600188016114d261010085614408565b61010081106114e3576114e36143b2565b015560405183815233907fe73bbcb7cad3f5322631cb969cde59a71bf4c70aa914cf02f7f64b6a428e632690602001610e2c565b6001600160a01b0381166000908152614ab060205260408120805463ffffffff600160201b820481169291600160401b900416801561155a578093505050915091565b815463ffffffff169350831561169c576001600160a01b0385166000908152614aaf6020526040812083549091600160601b90910461ffff169061159c61282b565b905060006115ac610100846143de565b600187016115bc61010086614408565b61010081106115cd576115cd6143b2565b0154901c90505b8183101561169757826115e68161441c565b93506115f69050610100846143de565b600003611627576001860161160d61010085614408565b610100811061161e5761161e6143b2565b0154905061162b565b60011c5b60018116600103611692576000848461ffff811061164b5761164b6143b2565b60088104919091015460079091166004026101000a900463ffffffff169050611674818a614435565b9850611680818961447c565b9750886000036116905750611697565b505b6115d4565b505050505b5050915091565b6001600160a01b0383166000908152614ab060205260408120548490600160401b900463ffffffff16156116e95760405162461bcd60e51b81526004016107ad90614554565b6001600160a01b0385166000908152614ab060209081526040808320614aaf9092528220909161171888613a9e565b9050600061172461282b565b90506000604051806040016040528086600101610100856117459190614408565b6101008110611756576117566143b2565b015481526020016001870161176d61010086614408565b61177890600161447c565b6101008110611789576117896143b2565b01549052905060008089815b818110156119f25760008d8d838181106117b1576117b16143b2565b90506040020160000135905060008e8e848181106117d1576117d16143b2565b905060400201602001359050600082116117fd5760405162461bcd60e51b81526004016107ad9061457c565b6000811161181d5760405162461bcd60e51b81526004016107ad906145ac565b603481111561183e5760405162461bcd60e51b81526004016107ad906145d0565b80600114801561185c57506205460061185a62093a80426143de565b115b15611865575060025b61186f828761447c565b955061187b8183614448565b611885908661447c565b94506000611893828a61447c565b905060008b8261ffff81106118aa576118aa6143b2565b60088104919091015460079091166004026101000a900463ffffffff1690506118d3848261447c565b8c8361ffff81106118e6576118e66143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555083612aae8361ffff8110611925576119256143b2565b600891828204019190066004028282829054906101000a900463ffffffff1661194e91906144bc565b92506101000a81548163ffffffff021916908363ffffffff160217905550806000036119db5760006119826101008c614408565b61198e61010085614408565b6119989190614435565b90506119a6610100846143de565b6001901b8a82600281106119bc576119bc6143b2565b6020020151178a82600281106119d4576119d46143b2565b6020020152505b5050505080806119ea9061441c565b915050611795565b50835160018901611a0561010088614408565b6101008110611a1657611a166143b2565b0155602084015160018901611a2d61010088614408565b611a3890600161447c565b6101008110611a4957611a496143b2565b01556001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016637426df5b33611aa57f000000000000000000000000000000000000000000000000000000000000000087614448565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611af0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b14919061445f565b50611b1f828761447c565b6001600160a01b038e166000908152614aae602052604090208661ffff8110611b4a57611b4a6143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555081611b7e6128c5565b611b88919061447c565b60038661ffff8110611b9c57611b9c6143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550828860000160009054906101000a900463ffffffff1663ffffffff16611bed919061447c565b885463ffffffff191663ffffffff918216178955600254611c109185911661447c565b600260006101000a81548163ffffffff021916908363ffffffff1602179055508c6001600160a01b03167f07a2b70451dc196475e467c8fe427b0e097afcf8fd17b87ad483b4de622ebdf68d8d604051611c6b929190614600565b60405180910390a25060019c9b505050505050505050505050565b336000818152614ab06020526040812054909190600160401b900463ffffffff1615611cc45760405162461bcd60e51b81526004016107ad90614554565b60005460ff16611d165760405162461bcd60e51b815260206004820181905260248201527f50656e616c7479207769746864726177616c73206172652064697361626c656460448201526064016107ad565b336000818152614ab060209081526040808320614aaf90925282209092909190611d3f90613a9e565b90506000198614611d7757611d747f000000000000000000000000000000000000000000000000000000000000000087614448565b95505b8254600090611db4907f000000000000000000000000000000000000000000000000000000000000000090600160201b900463ffffffff16614448565b9050868110611eb1577f0000000000000000000000000000000000000000000000000000000000000000611de88883614435565b611df29190614408565b845463ffffffff91909116600160201b0267ffffffff000000001990911617845560405163a9059cbb60e01b8152336004820152602481018890526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015611e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea4919061445f565b5086955050505050612825565b604051630b500bcb60e21b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632d402f2c906024016020604051808303816000875af1158015611f17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f3b919061445f565b50868115611f5f57611f4d8282614435565b855467ffffffff000000001916865590505b6000611f6961282b565b9050600060018701611f7d61010084614408565b6101008110611f8e57611f8e6143b2565b0154905060008060015b60348110156123e75784611fab8161441c565b9550611fbb9050610100866143de565b6000036120195760006001808c0190611fd661010089614408565b611fe09190614435565b6101008110611ff157611ff16143b2565b015560018a0161200361010087614408565b6101008110612014576120146143b2565b015493505b6001612027610100876143de565b85901c166001036123d55760007f00000000000000000000000000000000000000000000000000000000000000008a8761ffff8110612068576120686143b2565b600891828204019190066004029054906101000a900463ffffffff1663ffffffff166120949190614448565b9050600060346120a48484614448565b6120ae9190614408565b9050876120bb8284614435565b111561228257876120cd846034614435565b6120d860348b614448565b6120e29190614408565b6120ec9190614435565b905060007f000000000000000000000000000000000000000000000000000000000000000061211b8a8461447c565b61212591906143de565b9050801561216457612157817f0000000000000000000000000000000000000000000000000000000000000000614435565b612161908361447c565b91505b61216e828761447c565b955060007f000000000000000000000000000000000000000000000000000000000000000061219d8b8561447c565b6121a79190614408565b90506121b38582614448565b6121bd908761447c565b9550808d8a61ffff81106121d3576121d36143b2565b600891828204019190066004028282829054906101000a900463ffffffff166121fc9190614537565b92506101000a81548163ffffffff021916908363ffffffff16021790555080612aae8a61ffff8110612230576122306143b2565b600891828204019190066004028282829054906101000a900463ffffffff166122599190614537565b92506101000a81548163ffffffff021916908363ffffffff1602179055506000995050506123c3565b61228c818661447c565b9450826122b97f000000000000000000000000000000000000000000000000000000000000000084614408565b6122c39190614448565b6122cd908561447c565b93506122db610100886143de565b6001901b198616955060008b8861ffff81106122f9576122f96143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055507f00000000000000000000000000000000000000000000000000000000000000008261234e9190614408565b612aae8861ffff8110612363576123636143b2565b600891828204019190066004028282829054906101000a900463ffffffff1661238c9190614537565b92506101000a81548163ffffffff021916908363ffffffff16021790555080826123b69190614435565b6123c09089614435565b97505b876000036123d25750506123e7565b50505b806123df8161441c565b915050611f98565b508260018a016123f961010087614408565b610100811061240a5761240a6143b2565b015560018c016124255761241e858d614435565b9b50612473565b84156124735760405162461bcd60e51b815260206004820152601f60248201527f496e73756666696369656e742062616c616e636520616674657220666565730060448201526064016107ad565b7f00000000000000000000000000000000000000000000000000000000000000008661249f848f61447c565b6124a99190614435565b6124b39190614408565b89548a906000906124cb90849063ffffffff16614537565b92506101000a81548163ffffffff021916908363ffffffff1602179055507f000000000000000000000000000000000000000000000000000000000000000086838e612517919061447c565b6125219190614435565b61252b9190614408565b6002805460009061254390849063ffffffff16614537565b92506101000a81548163ffffffff021916908363ffffffff16021790555061256961282b565b93506125758188614435565b336000908152614aae602052604090208561ffff8110612597576125976143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550806125cb6128c5565b6125d59190614435565b60038561ffff81106125e9576125e96143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff1602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb338e6040518363ffffffff1660e01b81526004016126769291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015612695573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b9919061445f565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b3f006746040518163ffffffff1660e01b8152600401602060405180830381865afa158015612747573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276b91906144d9565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018590526044016020604051808303816000875af11580156127b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127dc919061445f565b50604080518d81526020810184905233917f3dee403330631fb457dbb611d44e5abc933635841e5e65a403b794d26268ee78910160405180910390a28b9a505050505050505050505b50919050565b600062093a8061285b7f000000000000000000000000000000000000000000000000000000000000000042614435565b6105229190614408565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e9e573d6000803e3d6000fd5b6000806128d061282b565b60025490915063ffffffff81169061ffff600160201b90910481169060009060039083908110612902576129026143b2565b600691828204019190066005029054906101000a900464ffffffffff1690508064ffffffffff1660000361295c5750506002805461ffff909316600160201b0265ffff000000001990931692909217909155506000919050565b838263ffffffff161015612a195781612974816144f6565b9250612988905063ffffffff841682614519565b90508060038363ffffffff1661ffff81106129a5576129a56143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550612aae8263ffffffff1661ffff81106129eb576129eb6143b2565b600891828204019190066004029054906101000a900463ffffffff1683612a129190614537565b925061295c565b6002805461ffff909516600160201b0265ffffffffffff1990951663ffffffff90941693909317939093179091555064ffffffffff16919050565b600061073582613a9e565b336000818152614ab06020526040812054909190600160401b900463ffffffff1615612a9d5760405162461bcd60e51b81526004016107ad90614554565b336000818152614ab060209081526040808320614aaf90925282209092909190612ac690613a9e565b90506000612ad261282b565b9050600060405180604001604052808660010161010085612af39190614408565b6101008110612b0457612b046143b2565b0154815260200160018701612b1b61010086614408565b612b2690600161447c565b6101008110612b3757612b376143b2565b015490529050600088815b81811015612f045760008c8c83818110612b5e57612b5e6143b2565b90506060020160000135905060008d8d84818110612b7e57612b7e6143b2565b90506060020160200135905060008e8e85818110612b9e57612b9e6143b2565b90506060020160400135905060008211612bca5760405162461bcd60e51b81526004016107ad906145ac565b6034811115612beb5760405162461bcd60e51b81526004016107ad906145d0565b808210612c0a5760405162461bcd60e51b81526004016107ad90614647565b60008311612c2a5760405162461bcd60e51b81526004016107ad9061457c565b82612c358383614435565b612c3f9190614448565b612c49908761447c565b9550612c55888361447c565b915060008a8361ffff8110612c6c57612c6c6143b2565b60088104919091015460079091166004026101000a900463ffffffff169050612c958482614435565b8b8461ffff8110612ca857612ca86143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555083612aae8461ffff8110612ce757612ce76143b2565b600891828204019190066004028282829054906101000a900463ffffffff16612d109190614537565b92506101000a81548163ffffffff021916908363ffffffff160217905550838103612d9d576000612d436101008b614408565b612d4f61010086614408565b612d599190614435565b9050612d67610100856143de565b6001901b19898260028110612d7e57612d7e6143b2565b602002015116898260028110612d9657612d966143b2565b6020020152505b612da7898361447c565b91508a8261ffff8110612dbc57612dbc6143b2565b60088104919091015460079091166004026101000a900463ffffffff169050612de5848261447c565b8b8361ffff8110612df857612df86143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555083612aae8361ffff8110612e3757612e376143b2565b600891828204019190066004028282829054906101000a900463ffffffff16612e6091906144bc565b92506101000a81548163ffffffff021916908363ffffffff16021790555080600003612eed576000612e946101008b614408565b612ea061010085614408565b612eaa9190614435565b9050612eb8610100846143de565b6001901b898260028110612ece57612ece6143b2565b602002015117898260028110612ee657612ee66143b2565b6020020152505b505050508080612efc9061441c565b915050612b42565b50825160018801612f1761010087614408565b6101008110612f2857612f286143b2565b0155602083015160018801612f3f61010087614408565b612f4a90600161447c565b6101008110612f5b57612f5b6143b2565b0155612f67828661447c565b336000908152614aae602052604090208561ffff8110612f8957612f896143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555081612fbd6128c5565b612fc7919061447c565b60038561ffff8110612fdb57612fdb6143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550336001600160a01b03167fd3213c37a39d2b2bd91dc0e8c0a14448e5bf1169a66211502a814b2268653b7e8c8c60405161304192919061468a565b60405180910390a260019850505050505050505b5092915050565b6001600160a01b0382166000908152614ab060209081526040808320614aaf909252822082919060001985146130b9576130b67f000000000000000000000000000000000000000000000000000000000000000086614448565b94505b81546000906130f6907f000000000000000000000000000000000000000000000000000000000000000090600160201b900463ffffffff16614448565b905085811061310e5785600094509450505050610b82565b600061311a8288614435565b8454909150600090600160601b900461ffff168161313661282b565b905060006131448383614435565b905060006001890161315861010086614408565b6101008110613169576131696143b2565b0154905060015b603481101561338557846131838161441c565b95506131939050610100866143de565b6000036131c05760018a016131aa61010087614408565b61010081106131bb576131bb6143b2565b015491505b60016131ce610100876143de565b83901c166001036133735760007f00000000000000000000000000000000000000000000000000000000000000008a8761ffff811061320f5761320f6143b2565b600891828204019190066004029054906101000a900463ffffffff1663ffffffff1661323b9190614448565b905060008587111561326a5760346132538685614435565b61325d9084614448565b6132679190614408565b90505b886132758284614435565b111561333e57886132868685614435565b613291906034614435565b61329c60348c614448565b6132a69190614408565b6132b09190614435565b905060007f00000000000000000000000000000000000000000000000000000000000000006132df8b8461447c565b6132e991906143de565b905080156133285761331b817f0000000000000000000000000000000000000000000000000000000000000000614435565b613325908361447c565b91505b613332828a61447c565b98506000995050613361565b613348818961447c565b97506133548183614435565b61335e908a614435565b98505b88600003613370575050613385565b50505b8061337d8161441c565b915050613170565b50613390868d614435565b9d949c50939a5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613403573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342791906144d9565b6001600160a01b0316336001600160a01b0316146134745760405162461bcd60e51b815260206004820152600a60248201526927b7363c9037bbb732b960b11b60448201526064016107ad565b600154801580159061348557508042115b6134bc5760405162461bcd60e51b81526020600482015260086024820152674e6f74207965742160c01b60448201526064016107ad565b50506000805460ff1916911515919091179055600190565b60008082116134f55760405162461bcd60e51b81526004016107ad906145ac565b600083116135155760405162461bcd60e51b81526004016107ad9061457c565b613520848484613dcc565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016637426df5b3361357a7f000000000000000000000000000000000000000000000000000000000000000087614448565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156135c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135e9919061445f565b506001949350505050565b336000818152614ab06020526040812054909190600160401b900463ffffffff16156136325760405162461bcd60e51b81526004016107ad90614554565b600084116136525760405162461bcd60e51b81526004016107ad906145ac565b60348311156136735760405162461bcd60e51b81526004016107ad906145d0565b8284106136925760405162461bcd60e51b81526004016107ad90614647565b600085116136b25760405162461bcd60e51b81526004016107ad9061457c565b336000908152614ab060205260408120906136cb61282b565b90506000876136da8888614435565b6136e49190614448565b336000818152614aaf602052604081209293509061370190613a9e565b905061370d838261447c565b336000908152614aae602052604090208561ffff811061372f5761372f6143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555060008985613768919061447c565b90506000838261ffff811061377f5761377f6143b2565b60088104919091015460079091166004026101000a900463ffffffff1690506137a88c82614435565b848361ffff81106137bb576137bb6143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055508b612aae8361ffff81106137fa576137fa6143b2565b600891828204019190066004028282829054906101000a900463ffffffff166138239190614537565b92506101000a81548163ffffffff021916908363ffffffff1602179055508b81036138a257600061385661010084614408565b90506000613866610100856143de565b6001901b1989600101836101008110613881576138816143b2565b0154169050808960010183610100811061389d5761389d6143b2565b015550505b6138ac8a8761447c565b9150838261ffff81106138c1576138c16143b2565b60088104919091015460079091166004026101000a900463ffffffff1690506138ea8c8261447c565b848361ffff81106138fd576138fd6143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055508b612aae8361ffff811061393c5761393c6143b2565b600891828204019190066004028282829054906101000a900463ffffffff1661396591906144bc565b92506101000a81548163ffffffff021916908363ffffffff160217905550806000036139e457600061399961010084614408565b905060006139a9610100856143de565b6001901b896001018361010081106139c3576139c36143b2565b015417905080896001018361010081106139df576139df6143b2565b015550505b846139ed6128c5565b6139f7919061447c565b60038761ffff8110613a0b57613a0b6143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550336001600160a01b03167f2880f4fc08dec6bc3c61687b882e88598cb950c1dbff72d4a2d20223174215b48d8d8d604051613a84939291909283526020830191909152604082015260600190565b60405180910390a25060019b9a5050505050505050505050565b6001600160a01b0381166000908152614ab060209081526040808320614aaf8352818420614aae90935290832090919083613ad761282b565b845490915061ffff600160601b909104811690839082908110613afc57613afc6143b2565b600691828204019190066005029054906101000a900464ffffffffff1664ffffffffff169550818103613b33575050505050919050565b8454600160401b900463ffffffff1615613bc6575b80821115613ba15780613b5a8161441c565b91505085838261ffff8110613b7157613b716143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550613b48565b50835461ffff909116600160601b0261ffff60601b1990911617909255509092915050565b845463ffffffff166000819003613c065782821015613bf857855461ffff60601b1916600160601b61ffff8516021786555b506000979650505050505050565b600080613c15610100856143de565b60018901613c2561010087614408565b6101008110613c3657613c366143b2565b0154901c90505b84841015613d565783613c4f8161441c565b9450613c5d9050838a614435565b985088868561ffff8110613c7357613c736143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555061010084613cac91906143de565b600003613cdd5760018801613cc361010086614408565b6101008110613cd457613cd46143b2565b01549050613ce1565b60011c5b60018116600103613d51576000878561ffff8110613d0157613d016143b2565b60088104919091015460079091166004026101000a900463ffffffff169050613d2a8185614435565b9350613d3c63ffffffff82168461447c565b925083600003613d4f5785945050613d56565b505b613c3d565b8754613d70908390600160201b900463ffffffff1661447c565b885461ffff909516600160601b026dffff0000000000000000ffffffff1963ffffffff928316600160201b02166dffff00000000ffffffffffffffff199096169590951793169290921792909217909555509395945050505050565b6034811115613ded5760405162461bcd60e51b81526004016107ad906145d0565b6001600160a01b0383166000908152614ab06020526040812090613e1085613a9e565b90506000613e1c6128c5565b90506000613e2861282b565b8454909150600160401b900463ffffffff168015613e7857613e4a878261447c565b855463ffffffff91909116600160401b026bffffffff00000000000000001990911617855560349550614052565b856001148015613e96575062054600613e9462093a80426143de565b115b15613ea057600295505b8454613eb390889063ffffffff1661447c565b855463ffffffff191663ffffffff918216178655600254613ed69189911661447c565b6002805463ffffffff191663ffffffff929092169190911790556001600160a01b0388166000908152614aaf6020526040812090613f14888561447c565b90506000828261ffff8110613f2b57613f2b6143b2565b60088104919091015460079091166004026101000a900463ffffffff169050613f548a8261447c565b838361ffff8110613f6757613f676143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555089612aae8361ffff8110613fa657613fa66143b2565b600891828204019190066004028282829054906101000a900463ffffffff16613fcf91906144bc565b92506101000a81548163ffffffff021916908363ffffffff1602179055508060000361404e57600061400361010084614408565b90506000614013610100856143de565b6001901b8a60010183610100811061402d5761402d6143b2565b0154179050808a600101836101008110614049576140496143b2565b015550505b5050505b61405c8688614448565b614066908561447c565b6001600160a01b0389166000908152614aae602052604090208361ffff8110614091576140916143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555085876140c89190614448565b6140d2908461447c565b60038361ffff81106140e6576140e66143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550876001600160a01b03167f167357c41e38a45e1950f61b1f5accf902c878d83f1685f7f72fb666203ce0478888604051610e2c929190918252602082015260400190565b6001600160a01b038116811461416a57600080fd5b50565b6000806040838503121561418057600080fd5b823561418b81614155565b946020939093013593505050565b6000602082840312156141ab57600080fd5b5035919050565b60408082528351828201819052600091906020906060850190828801855b828110156141f5578151805185528501518585015292850192908401906001016141d0565b5050509301939093525092915050565b60006020828403121561421757600080fd5b813561422281614155565b9392505050565b801515811461416a57600080fd5b60006020828403121561424957600080fd5b813561422281614229565b60008060006040848603121561426957600080fd5b833561427481614155565b9250602084013567ffffffffffffffff8082111561429157600080fd5b818601915086601f8301126142a557600080fd5b8135818111156142b457600080fd5b8760208260061b85010111156142c957600080fd5b6020830194508093505050509250925092565b600080602083850312156142ef57600080fd5b823567ffffffffffffffff8082111561430757600080fd5b818501915085601f83011261431b57600080fd5b81358181111561432a57600080fd5b86602060608302850101111561433f57600080fd5b60209290920196919550909350505050565b60008060006060848603121561436657600080fd5b833561437181614155565b95602085013595506040909401359392505050565b60008060006060848603121561439b57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6000826143ed576143ed6143c8565b500690565b634e487b7160e01b600052601160045260246000fd5b600082614417576144176143c8565b500490565b60006001820161442e5761442e6143f2565b5060010190565b81810381811115610735576107356143f2565b8082028115828204841417610735576107356143f2565b60006020828403121561447157600080fd5b815161422281614229565b80820180821115610735576107356143f2565b634e487b7160e01b600052604160045260246000fd5b6000816144b4576144b46143f2565b506000190190565b63ffffffff818116838216019080821115613055576130556143f2565b6000602082840312156144eb57600080fd5b815161422281614155565b600063ffffffff80831681810361450f5761450f6143f2565b6001019392505050565b64ffffffffff828116828216039080821115613055576130556143f2565b63ffffffff828116828216039080821115613055576130556143f2565b6020808252600e908201526d2637b1b59034b990333937bd32b760911b604082015260600190565b602080825260169082015275416d6f756e74206d757374206265206e6f6e7a65726f60501b604082015260600190565b6020808252600a90820152694d696e2031207765656b60b01b604082015260600190565b60208082526016908201527545786365656473204d41585f4c4f434b5f5745454b5360501b604082015260600190565b6020808252818101839052600090604080840186845b8781101561463a578135835284820135858401529183019190830190600101614616565b5090979650505050505050565b60208082526023908201527f6e65775765656b73206d7573742062652067726561746572207468616e207765604082015262656b7360e81b606082015260800190565b6020808252818101839052600090604080840186845b8781101561463a578135835284820135858401528382013584840152606092830192909101906001016146a056fea2646970667358221220ec855f7a256123039d44546cb9975a19d2a7a6b84f5b0ce6d76da3d95576158864736f6c634300081300330000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf8000000000000000000000000da47862a83dac0c112ba89c6abc2159b95afd71c000000000000000000000000fd8df0db401ab7ec7a06a8465134fa32132e850c000000000000000000000000d0efdf01dd8d650bba8992e2c42d0bc6d441a6730000000000000000000000000000000000000000000000000de0b6b3a7640000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c80638da5cb5b1161011a578063c5438b1b116100ad578063e2ab691d1161007c578063e2ab691d146104b4578063e8db55d0146104c7578063fb390a4f146104d4578063ff4819e1146104dd578063ffe60d2a1461050257600080fd5b8063c5438b1b1461042c578063c6cb63a214610453578063cc9641a81461047a578063d922150b146104a157600080fd5b8063bafacab9116100e9578063bafacab9146103c2578063bca7a9e2146103ca578063bd06aadf146103f1578063c373cb401461040457600080fd5b80638da5cb5b1461038c5780639e30c3ec14610394578063aac3751c1461039c578063b3655bc3146103af57600080fd5b8063508f28e5116101925780636b2c0ccb116101615780636b2c0ccb146103235780636ca32a9e1461034a5780638064d26814610371578063874d6d811461038457600080fd5b8063508f28e5146102cd57806362a5af3b146102e057806367a5b10b146102e85780636917e7fd1461031057600080fd5b80633ea01b34116101ce5780633ea01b3414610272578063446d530414610285578063452a93201461029a57806350735f6f146102ba57600080fd5b806306aba0e11461020057806307f93a381461021b57806312d02a981461022e57806317b45bb414610251575b600080fd5b610208610515565b6040519081526020015b60405180910390f35b61020861022936600461416d565b610527565b61024161023c366004614199565b61073b565b6040519015158152602001610212565b61026461025f36600461416d565b6108eb565b6040516102129291906141b2565b610208610280366004614205565b610b89565b610298610293366004614237565b610b97565b005b6102a2610e3e565b6040516001600160a01b039091168152602001610212565b6102086102c8366004614199565b610ec2565b6102416102db366004614199565b611031565b610298611141565b6102fb6102f6366004614205565b611517565b60408051928352602083019190915201610212565b61024161031e366004614254565b6116a3565b6102a27f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf881565b6102a27f000000000000000000000000d0efdf01dd8d650bba8992e2c42d0bc6d441a67381565b61020861037f366004614199565b611c86565b61020861282b565b6102a2612865565b6102086128c5565b6102086103aa366004614205565b612a54565b6102416103bd3660046142dc565b612a5f565b610208603481565b6102a27f000000000000000000000000da47862a83dac0c112ba89c6abc2159b95afd71c81565b6102fb6103ff36600461416d565b61305c565b60025461041990600160201b900461ffff1681565b60405161ffff9091168152602001610212565b6102087f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b6102a27f000000000000000000000000fd8df0db401ab7ec7a06a8465134fa32132e850c81565b6102a27f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf881565b6102416104af366004614237565b6133a3565b6102416104c2366004614351565b6134d4565b6000546102419060ff1681565b61020860015481565b6002546104ed9063ffffffff1681565b60405163ffffffff9091168152602001610212565b610241610510366004614386565b6135f4565b60006105226102c861282b565b905090565b600061053161282b565b82111561054057506000610735565b6001600160a01b0383166000908152614aaf60209081526040808320614aae8352818420614ab090935292208054600160601b900461ffff168581106105c257828661ffff8110610593576105936143b2565b600691828204019190066005029054906101000a900464ffffffffff1664ffffffffff16945050505050610735565b815463ffffffff166000848361ffff81106105df576105df6143b2565b600691828204019190066005029054906101000a900464ffffffffff1664ffffffffff169050816000148061062157508354600160401b900463ffffffff1615155b15610633579550610735945050505050565b6000610641610100856143de565b6001860161065161010087614408565b6101008110610662576106626143b2565b0154901c90505b8884101561072c578361067b8161441c565b945061068990508383614435565b9150610697610100856143de565b6000036106c857600185016106ae61010086614408565b61010081106106bf576106bf6143b2565b015490506106cc565b60011c5b60018116600103610727576000878561ffff81106106ec576106ec6143b2565b60088104919091015460079091166004026101000a900463ffffffff1690506107158185614435565b935083600003610725575061072c565b505b610669565b50955050505050505b92915050565b600061074633613a9e565b5061074f6128c5565b50336000908152614ab0602052604090208054600160201b900463ffffffff16806107b65760405162461bcd60e51b81526020600482015260126024820152714e6f20756e6c6f636b656420746f6b656e7360701b60448201526064015b60405180910390fd5b815467ffffffff000000001916825583156107db576107d6338286613dcc565b6108e1565b6001600160a01b037f000000000000000000000000da47862a83dac0c112ba89c6abc2159b95afd71c1663a9059cbb336108357f0000000000000000000000000000000000000000000000000de0b6b3a764000085614448565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a4919061445f565b50604080518281526000602082015233917f3dee403330631fb457dbb611d44e5abc933635841e5e65a403b794d26268ee78910160405180910390a25b5060019392505050565b6001600160a01b0382166000908152614ab0602052604081208054606092600160401b90910463ffffffff169190829003610b80578360000361092d57600193505b6001600160a01b0385166000908152614aaf602052604081209061094f61282b565b9050600061095d878361447c565b9050600061096c60348461447c565b6040805160348082526106a0820190925291925060009190602082016106808036833701905050905060006109a3610100856143de565b600188016109b361010087614408565b61010081106109c4576109c46143b2565b0154901c905060005b838511610a625760018216600103610a0b57848382815181106109f2576109f26143b2565b602090810291909101015280610a078161441c565b9150505b84610a158161441c565b9550610a259050610100866143de565b600003610a565760018801610a3c61010087614408565b6101008110610a4d57610a4d6143b2565b015491506109cd565b600182901c91506109cd565b8067ffffffffffffffff811115610a7b57610a7b61448f565b604051908082528060200260200182016040528015610ac057816020015b6040805180820190915260008082526020820152815260200190600190039081610a995790505b5099508060005b8115610b765781610ad7816144a5565b9250506000858381518110610aee57610aee6143b2565b6020026020010151905060405180604001604052808b8361ffff8110610b1657610b166143b2565b60088104919091015460079091166004026101000a900463ffffffff168152602001610b428b84614435565b8152508d8381518110610b5757610b576143b2565b6020026020010181905250508080610b6e9061441c565b915050610ac7565b5050505050505050505b505b9250929050565b60006107358261022961282b565b336000908152614ab060209081526040808320614aaf9092529091208154600160401b900463ffffffff1680610c085760405162461bcd60e51b81526020600482015260166024820152752637b1b5b99030b63932b0b23c903ab7333937bd32b760511b60448201526064016107ad565b6040516393101b4160e01b815233600482015284151560248201527f000000000000000000000000fd8df0db401ab7ec7a06a8465134fa32132e850c6001600160a01b0316906393101b41906044016020604051808303816000875af1158015610c76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9a919061445f565b50610ca433613a9e565b50610cad6128c5565b50600254610cc290829063ffffffff1661447c565b6002805463ffffffff92831663ffffffff1990911617905583546bffffffff00000000ffffffff19169082161783556000610cfb61282b565b90506000610d0a60348361447c565b905082848261ffff8110610d2057610d206143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555082612aae8261ffff8110610d5f57610d5f6143b2565b600891828204019190066004028282829054906101000a900463ffffffff16610d8891906144bc565b92506101000a81548163ffffffff021916908363ffffffff160217905550600061010082610db69190614408565b90506000610dc6610100846143de565b6001901b87600101836101008110610de057610de06143b2565b01541790508087600101836101008110610dfc57610dfc6143b2565b015560405185815233907f891e32b677b13f3c41e0facb731a92c347d3803878526d8c2dc27c7e1b1bb0e0906020015b60405180910390a25050505050505050565b60007f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf86001600160a01b031663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e9e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052291906144d9565b600080610ecd61282b565b905080831115610ee05750600092915050565b600254600160201b900461ffff16808411610f365760038461ffff8110610f0957610f096143b2565b600691828204019190066005029054906101000a900464ffffffffff1664ffffffffff1692505050919050565b60025463ffffffff90811690600090600390841661ffff8110610f5b57610f5b6143b2565b600691828204019190066005029054906101000a900464ffffffffff1690508163ffffffff1660001480610f955750838363ffffffff1610155b15610faa5764ffffffffff1695945050505050565b838363ffffffff1610156110215782610fc2816144f6565b9350610fd6905063ffffffff831682614519565b9050612aae8363ffffffff1661ffff8110610ff357610ff36143b2565b600891828204019190066004029054906101000a900463ffffffff168261101a9190614537565b9150610faa565b64ffffffffff1695945050505050565b6000336001600160a01b037f000000000000000000000000d0efdf01dd8d650bba8992e2c42d0bc6d441a67316146110a05760405162461bcd60e51b815260206004820152601260248201527110b232b83637bcb6b2b73a26b0b730b3b2b960711b60448201526064016107ad565b600154156110de5760405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b60448201526064016107ad565b42821180156110f857506110f5426277f88061447c565b82105b6111385760405162461bcd60e51b81526020600482015260116024820152700496e76616c69642074696d657374616d7607c1b60448201526064016107ad565b50600190815590565b336000818152614ab06020526040902054600160401b900463ffffffff161561117c5760405162461bcd60e51b81526004016107ad90614554565b336000818152614ab060209081526040808320614aaf909252822090929091906111a590613a9e565b905060006111b16128c5565b845490915063ffffffff16806111fd5760405162461bcd60e51b81526020600482015260116024820152704e6f206c6f636b65642062616c616e636560781b60448201526064016107ad565b60025461121190829063ffffffff16614435565b6002805463ffffffff92831663ffffffff19918216179091558654918316600160401b02166bffffffff00000000ffffffff19909116178555600061125461282b565b9050611261603483614448565b336000908152614aae602052604090208261ffff8110611283576112836143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff1602179055506034826112bb9190614448565b6112c58585614435565b6112cf919061447c565b60038261ffff81106112e3576112e36143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555060006101008261131e91906143de565b6001880161132e61010085614408565b610100811061133f5761133f6143b2565b0154901c90505b82156114c057816113568161441c565b92506113669050610100836143de565b6000036113c8576001870161137d61010084614408565b610100811061138e5761138e6143b2565b0154905060006001808901906113a661010086614408565b6113b09190614435565b61010081106113c1576113c16143b2565b01556113cc565b60011c5b600181166001036114bb576000868361ffff81106113ec576113ec6143b2565b600891828204019190066004029054906101000a900463ffffffff1690506000878461ffff811061141f5761141f6143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555080612aae8461ffff811061145e5761145e6143b2565b600891828204019190066004028282829054906101000a900463ffffffff166114879190614537565b92506101000a81548163ffffffff021916908363ffffffff1602179055508063ffffffff16846114b79190614435565b9350505b611346565b6000600188016114d261010085614408565b61010081106114e3576114e36143b2565b015560405183815233907fe73bbcb7cad3f5322631cb969cde59a71bf4c70aa914cf02f7f64b6a428e632690602001610e2c565b6001600160a01b0381166000908152614ab060205260408120805463ffffffff600160201b820481169291600160401b900416801561155a578093505050915091565b815463ffffffff169350831561169c576001600160a01b0385166000908152614aaf6020526040812083549091600160601b90910461ffff169061159c61282b565b905060006115ac610100846143de565b600187016115bc61010086614408565b61010081106115cd576115cd6143b2565b0154901c90505b8183101561169757826115e68161441c565b93506115f69050610100846143de565b600003611627576001860161160d61010085614408565b610100811061161e5761161e6143b2565b0154905061162b565b60011c5b60018116600103611692576000848461ffff811061164b5761164b6143b2565b60088104919091015460079091166004026101000a900463ffffffff169050611674818a614435565b9850611680818961447c565b9750886000036116905750611697565b505b6115d4565b505050505b5050915091565b6001600160a01b0383166000908152614ab060205260408120548490600160401b900463ffffffff16156116e95760405162461bcd60e51b81526004016107ad90614554565b6001600160a01b0385166000908152614ab060209081526040808320614aaf9092528220909161171888613a9e565b9050600061172461282b565b90506000604051806040016040528086600101610100856117459190614408565b6101008110611756576117566143b2565b015481526020016001870161176d61010086614408565b61177890600161447c565b6101008110611789576117896143b2565b01549052905060008089815b818110156119f25760008d8d838181106117b1576117b16143b2565b90506040020160000135905060008e8e848181106117d1576117d16143b2565b905060400201602001359050600082116117fd5760405162461bcd60e51b81526004016107ad9061457c565b6000811161181d5760405162461bcd60e51b81526004016107ad906145ac565b603481111561183e5760405162461bcd60e51b81526004016107ad906145d0565b80600114801561185c57506205460061185a62093a80426143de565b115b15611865575060025b61186f828761447c565b955061187b8183614448565b611885908661447c565b94506000611893828a61447c565b905060008b8261ffff81106118aa576118aa6143b2565b60088104919091015460079091166004026101000a900463ffffffff1690506118d3848261447c565b8c8361ffff81106118e6576118e66143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555083612aae8361ffff8110611925576119256143b2565b600891828204019190066004028282829054906101000a900463ffffffff1661194e91906144bc565b92506101000a81548163ffffffff021916908363ffffffff160217905550806000036119db5760006119826101008c614408565b61198e61010085614408565b6119989190614435565b90506119a6610100846143de565b6001901b8a82600281106119bc576119bc6143b2565b6020020151178a82600281106119d4576119d46143b2565b6020020152505b5050505080806119ea9061441c565b915050611795565b50835160018901611a0561010088614408565b6101008110611a1657611a166143b2565b0155602084015160018901611a2d61010088614408565b611a3890600161447c565b6101008110611a4957611a496143b2565b01556001600160a01b037f000000000000000000000000da47862a83dac0c112ba89c6abc2159b95afd71c16637426df5b33611aa57f0000000000000000000000000000000000000000000000000de0b6b3a764000087614448565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611af0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b14919061445f565b50611b1f828761447c565b6001600160a01b038e166000908152614aae602052604090208661ffff8110611b4a57611b4a6143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555081611b7e6128c5565b611b88919061447c565b60038661ffff8110611b9c57611b9c6143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550828860000160009054906101000a900463ffffffff1663ffffffff16611bed919061447c565b885463ffffffff191663ffffffff918216178955600254611c109185911661447c565b600260006101000a81548163ffffffff021916908363ffffffff1602179055508c6001600160a01b03167f07a2b70451dc196475e467c8fe427b0e097afcf8fd17b87ad483b4de622ebdf68d8d604051611c6b929190614600565b60405180910390a25060019c9b505050505050505050505050565b336000818152614ab06020526040812054909190600160401b900463ffffffff1615611cc45760405162461bcd60e51b81526004016107ad90614554565b60005460ff16611d165760405162461bcd60e51b815260206004820181905260248201527f50656e616c7479207769746864726177616c73206172652064697361626c656460448201526064016107ad565b336000818152614ab060209081526040808320614aaf90925282209092909190611d3f90613a9e565b90506000198614611d7757611d747f0000000000000000000000000000000000000000000000000de0b6b3a764000087614448565b95505b8254600090611db4907f0000000000000000000000000000000000000000000000000de0b6b3a764000090600160201b900463ffffffff16614448565b9050868110611eb1577f0000000000000000000000000000000000000000000000000de0b6b3a7640000611de88883614435565b611df29190614408565b845463ffffffff91909116600160201b0267ffffffff000000001990911617845560405163a9059cbb60e01b8152336004820152602481018890526001600160a01b037f000000000000000000000000da47862a83dac0c112ba89c6abc2159b95afd71c169063a9059cbb906044016020604051808303816000875af1158015611e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea4919061445f565b5086955050505050612825565b604051630b500bcb60e21b81523360048201527f000000000000000000000000fd8df0db401ab7ec7a06a8465134fa32132e850c6001600160a01b031690632d402f2c906024016020604051808303816000875af1158015611f17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f3b919061445f565b50868115611f5f57611f4d8282614435565b855467ffffffff000000001916865590505b6000611f6961282b565b9050600060018701611f7d61010084614408565b6101008110611f8e57611f8e6143b2565b0154905060008060015b60348110156123e75784611fab8161441c565b9550611fbb9050610100866143de565b6000036120195760006001808c0190611fd661010089614408565b611fe09190614435565b6101008110611ff157611ff16143b2565b015560018a0161200361010087614408565b6101008110612014576120146143b2565b015493505b6001612027610100876143de565b85901c166001036123d55760007f0000000000000000000000000000000000000000000000000de0b6b3a76400008a8761ffff8110612068576120686143b2565b600891828204019190066004029054906101000a900463ffffffff1663ffffffff166120949190614448565b9050600060346120a48484614448565b6120ae9190614408565b9050876120bb8284614435565b111561228257876120cd846034614435565b6120d860348b614448565b6120e29190614408565b6120ec9190614435565b905060007f0000000000000000000000000000000000000000000000000de0b6b3a764000061211b8a8461447c565b61212591906143de565b9050801561216457612157817f0000000000000000000000000000000000000000000000000de0b6b3a7640000614435565b612161908361447c565b91505b61216e828761447c565b955060007f0000000000000000000000000000000000000000000000000de0b6b3a764000061219d8b8561447c565b6121a79190614408565b90506121b38582614448565b6121bd908761447c565b9550808d8a61ffff81106121d3576121d36143b2565b600891828204019190066004028282829054906101000a900463ffffffff166121fc9190614537565b92506101000a81548163ffffffff021916908363ffffffff16021790555080612aae8a61ffff8110612230576122306143b2565b600891828204019190066004028282829054906101000a900463ffffffff166122599190614537565b92506101000a81548163ffffffff021916908363ffffffff1602179055506000995050506123c3565b61228c818661447c565b9450826122b97f0000000000000000000000000000000000000000000000000de0b6b3a764000084614408565b6122c39190614448565b6122cd908561447c565b93506122db610100886143de565b6001901b198616955060008b8861ffff81106122f9576122f96143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055507f0000000000000000000000000000000000000000000000000de0b6b3a76400008261234e9190614408565b612aae8861ffff8110612363576123636143b2565b600891828204019190066004028282829054906101000a900463ffffffff1661238c9190614537565b92506101000a81548163ffffffff021916908363ffffffff16021790555080826123b69190614435565b6123c09089614435565b97505b876000036123d25750506123e7565b50505b806123df8161441c565b915050611f98565b508260018a016123f961010087614408565b610100811061240a5761240a6143b2565b015560018c016124255761241e858d614435565b9b50612473565b84156124735760405162461bcd60e51b815260206004820152601f60248201527f496e73756666696369656e742062616c616e636520616674657220666565730060448201526064016107ad565b7f0000000000000000000000000000000000000000000000000de0b6b3a76400008661249f848f61447c565b6124a99190614435565b6124b39190614408565b89548a906000906124cb90849063ffffffff16614537565b92506101000a81548163ffffffff021916908363ffffffff1602179055507f0000000000000000000000000000000000000000000000000de0b6b3a764000086838e612517919061447c565b6125219190614435565b61252b9190614408565b6002805460009061254390849063ffffffff16614537565b92506101000a81548163ffffffff021916908363ffffffff16021790555061256961282b565b93506125758188614435565b336000908152614aae602052604090208561ffff8110612597576125976143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550806125cb6128c5565b6125d59190614435565b60038561ffff81106125e9576125e96143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff1602179055507f000000000000000000000000da47862a83dac0c112ba89c6abc2159b95afd71c6001600160a01b031663a9059cbb338e6040518363ffffffff1660e01b81526004016126769291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015612695573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b9919061445f565b507f000000000000000000000000da47862a83dac0c112ba89c6abc2159b95afd71c6001600160a01b031663a9059cbb7f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf86001600160a01b031663b3f006746040518163ffffffff1660e01b8152600401602060405180830381865afa158015612747573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276b91906144d9565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018590526044016020604051808303816000875af11580156127b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127dc919061445f565b50604080518d81526020810184905233917f3dee403330631fb457dbb611d44e5abc933635841e5e65a403b794d26268ee78910160405180910390a28b9a505050505050505050505b50919050565b600062093a8061285b7f0000000000000000000000000000000000000000000000000000000064d4288042614435565b6105229190614408565b60007f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e9e573d6000803e3d6000fd5b6000806128d061282b565b60025490915063ffffffff81169061ffff600160201b90910481169060009060039083908110612902576129026143b2565b600691828204019190066005029054906101000a900464ffffffffff1690508064ffffffffff1660000361295c5750506002805461ffff909316600160201b0265ffff000000001990931692909217909155506000919050565b838263ffffffff161015612a195781612974816144f6565b9250612988905063ffffffff841682614519565b90508060038363ffffffff1661ffff81106129a5576129a56143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550612aae8263ffffffff1661ffff81106129eb576129eb6143b2565b600891828204019190066004029054906101000a900463ffffffff1683612a129190614537565b925061295c565b6002805461ffff909516600160201b0265ffffffffffff1990951663ffffffff90941693909317939093179091555064ffffffffff16919050565b600061073582613a9e565b336000818152614ab06020526040812054909190600160401b900463ffffffff1615612a9d5760405162461bcd60e51b81526004016107ad90614554565b336000818152614ab060209081526040808320614aaf90925282209092909190612ac690613a9e565b90506000612ad261282b565b9050600060405180604001604052808660010161010085612af39190614408565b6101008110612b0457612b046143b2565b0154815260200160018701612b1b61010086614408565b612b2690600161447c565b6101008110612b3757612b376143b2565b015490529050600088815b81811015612f045760008c8c83818110612b5e57612b5e6143b2565b90506060020160000135905060008d8d84818110612b7e57612b7e6143b2565b90506060020160200135905060008e8e85818110612b9e57612b9e6143b2565b90506060020160400135905060008211612bca5760405162461bcd60e51b81526004016107ad906145ac565b6034811115612beb5760405162461bcd60e51b81526004016107ad906145d0565b808210612c0a5760405162461bcd60e51b81526004016107ad90614647565b60008311612c2a5760405162461bcd60e51b81526004016107ad9061457c565b82612c358383614435565b612c3f9190614448565b612c49908761447c565b9550612c55888361447c565b915060008a8361ffff8110612c6c57612c6c6143b2565b60088104919091015460079091166004026101000a900463ffffffff169050612c958482614435565b8b8461ffff8110612ca857612ca86143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555083612aae8461ffff8110612ce757612ce76143b2565b600891828204019190066004028282829054906101000a900463ffffffff16612d109190614537565b92506101000a81548163ffffffff021916908363ffffffff160217905550838103612d9d576000612d436101008b614408565b612d4f61010086614408565b612d599190614435565b9050612d67610100856143de565b6001901b19898260028110612d7e57612d7e6143b2565b602002015116898260028110612d9657612d966143b2565b6020020152505b612da7898361447c565b91508a8261ffff8110612dbc57612dbc6143b2565b60088104919091015460079091166004026101000a900463ffffffff169050612de5848261447c565b8b8361ffff8110612df857612df86143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555083612aae8361ffff8110612e3757612e376143b2565b600891828204019190066004028282829054906101000a900463ffffffff16612e6091906144bc565b92506101000a81548163ffffffff021916908363ffffffff16021790555080600003612eed576000612e946101008b614408565b612ea061010085614408565b612eaa9190614435565b9050612eb8610100846143de565b6001901b898260028110612ece57612ece6143b2565b602002015117898260028110612ee657612ee66143b2565b6020020152505b505050508080612efc9061441c565b915050612b42565b50825160018801612f1761010087614408565b6101008110612f2857612f286143b2565b0155602083015160018801612f3f61010087614408565b612f4a90600161447c565b6101008110612f5b57612f5b6143b2565b0155612f67828661447c565b336000908152614aae602052604090208561ffff8110612f8957612f896143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555081612fbd6128c5565b612fc7919061447c565b60038561ffff8110612fdb57612fdb6143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550336001600160a01b03167fd3213c37a39d2b2bd91dc0e8c0a14448e5bf1169a66211502a814b2268653b7e8c8c60405161304192919061468a565b60405180910390a260019850505050505050505b5092915050565b6001600160a01b0382166000908152614ab060209081526040808320614aaf909252822082919060001985146130b9576130b67f0000000000000000000000000000000000000000000000000de0b6b3a764000086614448565b94505b81546000906130f6907f0000000000000000000000000000000000000000000000000de0b6b3a764000090600160201b900463ffffffff16614448565b905085811061310e5785600094509450505050610b82565b600061311a8288614435565b8454909150600090600160601b900461ffff168161313661282b565b905060006131448383614435565b905060006001890161315861010086614408565b6101008110613169576131696143b2565b0154905060015b603481101561338557846131838161441c565b95506131939050610100866143de565b6000036131c05760018a016131aa61010087614408565b61010081106131bb576131bb6143b2565b015491505b60016131ce610100876143de565b83901c166001036133735760007f0000000000000000000000000000000000000000000000000de0b6b3a76400008a8761ffff811061320f5761320f6143b2565b600891828204019190066004029054906101000a900463ffffffff1663ffffffff1661323b9190614448565b905060008587111561326a5760346132538685614435565b61325d9084614448565b6132679190614408565b90505b886132758284614435565b111561333e57886132868685614435565b613291906034614435565b61329c60348c614448565b6132a69190614408565b6132b09190614435565b905060007f0000000000000000000000000000000000000000000000000de0b6b3a76400006132df8b8461447c565b6132e991906143de565b905080156133285761331b817f0000000000000000000000000000000000000000000000000de0b6b3a7640000614435565b613325908361447c565b91505b613332828a61447c565b98506000995050613361565b613348818961447c565b97506133548183614435565b61335e908a614435565b98505b88600003613370575050613385565b50505b8061337d8161441c565b915050613170565b50613390868d614435565b9d949c50939a5050505050505050505050565b60007f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613403573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342791906144d9565b6001600160a01b0316336001600160a01b0316146134745760405162461bcd60e51b815260206004820152600a60248201526927b7363c9037bbb732b960b11b60448201526064016107ad565b600154801580159061348557508042115b6134bc5760405162461bcd60e51b81526020600482015260086024820152674e6f74207965742160c01b60448201526064016107ad565b50506000805460ff1916911515919091179055600190565b60008082116134f55760405162461bcd60e51b81526004016107ad906145ac565b600083116135155760405162461bcd60e51b81526004016107ad9061457c565b613520848484613dcc565b6001600160a01b037f000000000000000000000000da47862a83dac0c112ba89c6abc2159b95afd71c16637426df5b3361357a7f0000000000000000000000000000000000000000000000000de0b6b3a764000087614448565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156135c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135e9919061445f565b506001949350505050565b336000818152614ab06020526040812054909190600160401b900463ffffffff16156136325760405162461bcd60e51b81526004016107ad90614554565b600084116136525760405162461bcd60e51b81526004016107ad906145ac565b60348311156136735760405162461bcd60e51b81526004016107ad906145d0565b8284106136925760405162461bcd60e51b81526004016107ad90614647565b600085116136b25760405162461bcd60e51b81526004016107ad9061457c565b336000908152614ab060205260408120906136cb61282b565b90506000876136da8888614435565b6136e49190614448565b336000818152614aaf602052604081209293509061370190613a9e565b905061370d838261447c565b336000908152614aae602052604090208561ffff811061372f5761372f6143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555060008985613768919061447c565b90506000838261ffff811061377f5761377f6143b2565b60088104919091015460079091166004026101000a900463ffffffff1690506137a88c82614435565b848361ffff81106137bb576137bb6143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055508b612aae8361ffff81106137fa576137fa6143b2565b600891828204019190066004028282829054906101000a900463ffffffff166138239190614537565b92506101000a81548163ffffffff021916908363ffffffff1602179055508b81036138a257600061385661010084614408565b90506000613866610100856143de565b6001901b1989600101836101008110613881576138816143b2565b0154169050808960010183610100811061389d5761389d6143b2565b015550505b6138ac8a8761447c565b9150838261ffff81106138c1576138c16143b2565b60088104919091015460079091166004026101000a900463ffffffff1690506138ea8c8261447c565b848361ffff81106138fd576138fd6143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055508b612aae8361ffff811061393c5761393c6143b2565b600891828204019190066004028282829054906101000a900463ffffffff1661396591906144bc565b92506101000a81548163ffffffff021916908363ffffffff160217905550806000036139e457600061399961010084614408565b905060006139a9610100856143de565b6001901b896001018361010081106139c3576139c36143b2565b015417905080896001018361010081106139df576139df6143b2565b015550505b846139ed6128c5565b6139f7919061447c565b60038761ffff8110613a0b57613a0b6143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550336001600160a01b03167f2880f4fc08dec6bc3c61687b882e88598cb950c1dbff72d4a2d20223174215b48d8d8d604051613a84939291909283526020830191909152604082015260600190565b60405180910390a25060019b9a5050505050505050505050565b6001600160a01b0381166000908152614ab060209081526040808320614aaf8352818420614aae90935290832090919083613ad761282b565b845490915061ffff600160601b909104811690839082908110613afc57613afc6143b2565b600691828204019190066005029054906101000a900464ffffffffff1664ffffffffff169550818103613b33575050505050919050565b8454600160401b900463ffffffff1615613bc6575b80821115613ba15780613b5a8161441c565b91505085838261ffff8110613b7157613b716143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550613b48565b50835461ffff909116600160601b0261ffff60601b1990911617909255509092915050565b845463ffffffff166000819003613c065782821015613bf857855461ffff60601b1916600160601b61ffff8516021786555b506000979650505050505050565b600080613c15610100856143de565b60018901613c2561010087614408565b6101008110613c3657613c366143b2565b0154901c90505b84841015613d565783613c4f8161441c565b9450613c5d9050838a614435565b985088868561ffff8110613c7357613c736143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555061010084613cac91906143de565b600003613cdd5760018801613cc361010086614408565b6101008110613cd457613cd46143b2565b01549050613ce1565b60011c5b60018116600103613d51576000878561ffff8110613d0157613d016143b2565b60088104919091015460079091166004026101000a900463ffffffff169050613d2a8185614435565b9350613d3c63ffffffff82168461447c565b925083600003613d4f5785945050613d56565b505b613c3d565b8754613d70908390600160201b900463ffffffff1661447c565b885461ffff909516600160601b026dffff0000000000000000ffffffff1963ffffffff928316600160201b02166dffff00000000ffffffffffffffff199096169590951793169290921792909217909555509395945050505050565b6034811115613ded5760405162461bcd60e51b81526004016107ad906145d0565b6001600160a01b0383166000908152614ab06020526040812090613e1085613a9e565b90506000613e1c6128c5565b90506000613e2861282b565b8454909150600160401b900463ffffffff168015613e7857613e4a878261447c565b855463ffffffff91909116600160401b026bffffffff00000000000000001990911617855560349550614052565b856001148015613e96575062054600613e9462093a80426143de565b115b15613ea057600295505b8454613eb390889063ffffffff1661447c565b855463ffffffff191663ffffffff918216178655600254613ed69189911661447c565b6002805463ffffffff191663ffffffff929092169190911790556001600160a01b0388166000908152614aaf6020526040812090613f14888561447c565b90506000828261ffff8110613f2b57613f2b6143b2565b60088104919091015460079091166004026101000a900463ffffffff169050613f548a8261447c565b838361ffff8110613f6757613f676143b2565b600891828204019190066004026101000a81548163ffffffff021916908363ffffffff16021790555089612aae8361ffff8110613fa657613fa66143b2565b600891828204019190066004028282829054906101000a900463ffffffff16613fcf91906144bc565b92506101000a81548163ffffffff021916908363ffffffff1602179055508060000361404e57600061400361010084614408565b90506000614013610100856143de565b6001901b8a60010183610100811061402d5761402d6143b2565b0154179050808a600101836101008110614049576140496143b2565b015550505b5050505b61405c8688614448565b614066908561447c565b6001600160a01b0389166000908152614aae602052604090208361ffff8110614091576140916143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555085876140c89190614448565b6140d2908461447c565b60038361ffff81106140e6576140e66143b2565b600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff160217905550876001600160a01b03167f167357c41e38a45e1950f61b1f5accf902c878d83f1685f7f72fb666203ce0478888604051610e2c929190918252602082015260400190565b6001600160a01b038116811461416a57600080fd5b50565b6000806040838503121561418057600080fd5b823561418b81614155565b946020939093013593505050565b6000602082840312156141ab57600080fd5b5035919050565b60408082528351828201819052600091906020906060850190828801855b828110156141f5578151805185528501518585015292850192908401906001016141d0565b5050509301939093525092915050565b60006020828403121561421757600080fd5b813561422281614155565b9392505050565b801515811461416a57600080fd5b60006020828403121561424957600080fd5b813561422281614229565b60008060006040848603121561426957600080fd5b833561427481614155565b9250602084013567ffffffffffffffff8082111561429157600080fd5b818601915086601f8301126142a557600080fd5b8135818111156142b457600080fd5b8760208260061b85010111156142c957600080fd5b6020830194508093505050509250925092565b600080602083850312156142ef57600080fd5b823567ffffffffffffffff8082111561430757600080fd5b818501915085601f83011261431b57600080fd5b81358181111561432a57600080fd5b86602060608302850101111561433f57600080fd5b60209290920196919550909350505050565b60008060006060848603121561436657600080fd5b833561437181614155565b95602085013595506040909401359392505050565b60008060006060848603121561439b57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6000826143ed576143ed6143c8565b500690565b634e487b7160e01b600052601160045260246000fd5b600082614417576144176143c8565b500490565b60006001820161442e5761442e6143f2565b5060010190565b81810381811115610735576107356143f2565b8082028115828204841417610735576107356143f2565b60006020828403121561447157600080fd5b815161422281614229565b80820180821115610735576107356143f2565b634e487b7160e01b600052604160045260246000fd5b6000816144b4576144b46143f2565b506000190190565b63ffffffff818116838216019080821115613055576130556143f2565b6000602082840312156144eb57600080fd5b815161422281614155565b600063ffffffff80831681810361450f5761450f6143f2565b6001019392505050565b64ffffffffff828116828216039080821115613055576130556143f2565b63ffffffff828116828216039080821115613055576130556143f2565b6020808252600e908201526d2637b1b59034b990333937bd32b760911b604082015260600190565b602080825260169082015275416d6f756e74206d757374206265206e6f6e7a65726f60501b604082015260600190565b6020808252600a90820152694d696e2031207765656b60b01b604082015260600190565b60208082526016908201527545786365656473204d41585f4c4f434b5f5745454b5360501b604082015260600190565b6020808252818101839052600090604080840186845b8781101561463a578135835284820135858401529183019190830190600101614616565b5090979650505050505050565b60208082526023908201527f6e65775765656b73206d7573742062652067726561746572207468616e207765604082015262656b7360e81b606082015260800190565b6020808252818101839052600090604080840186845b8781101561463a578135835284820135858401528382013584840152606092830192909101906001016146a056fea2646970667358221220ec855f7a256123039d44546cb9975a19d2a7a6b84f5b0ce6d76da3d95576158864736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf8000000000000000000000000da47862a83dac0c112ba89c6abc2159b95afd71c000000000000000000000000fd8df0db401ab7ec7a06a8465134fa32132e850c000000000000000000000000d0efdf01dd8d650bba8992e2c42d0bc6d441a6730000000000000000000000000000000000000000000000000de0b6b3a7640000
-----Decoded View---------------
Arg [0] : _prismaCore (address): 0x5d17eA085F2FF5da3e6979D5d26F1dBaB664ccf8
Arg [1] : _token (address): 0xdA47862a83dac0c112BA89c6abC2159b95afd71C
Arg [2] : _voter (address): 0xfd8DF0Db401Ab7EC7a06a8465134FA32132e850C
Arg [3] : _manager (address): 0xD0eFDF01DD8d650bBA8992E2c42D0bC6d441a673
Arg [4] : _lockToTokenRatio (uint256): 1000000000000000000
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf8
Arg [1] : 000000000000000000000000da47862a83dac0c112ba89c6abc2159b95afd71c
Arg [2] : 000000000000000000000000fd8df0db401ab7ec7a06a8465134fa32132e850c
Arg [3] : 000000000000000000000000d0efdf01dd8d650bba8992e2c42d0bc6d441a673
Arg [4] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Loading...
Loading
Loading...
Loading
OVERVIEW
Locker for PRISMA tokensMultichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.05957 | 67,581,302 | $4,025,818.16 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.