Polygon Sponsored slots available. Book your slot here!
Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Name:
OtterLake
Compiler Version
v0.7.5+commit.eb77ed08
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; // import 'hardhat/console.sol'; import './interfaces/IERC20.sol'; import './interfaces/IPearlNote.sol'; import './interfaces/IStakingDistributor.sol'; import './interfaces/IOtterLake.sol'; import './libraries/SafeMath.sol'; import './libraries/SafeERC20.sol'; import './types/Pausable.sol'; import './types/ReentrancyGuard.sol'; // @dev: Modified from: https://docs.synthetix.io/contracts/source/contracts/stakingrewards contract OtterLake is IOtterLake, ReentrancyGuard, Pausable { using SafeMath for uint256; using SafeERC20 for IERC20; struct Term { IPearlNote note; uint256 minLockAmount; uint256 lockPeriod; uint16 multiplier; // 100 = x1, 120 = x1.2 bool enabled; } struct Epoch { uint256 length; uint256 number; uint256 endTime; uint256 totalReward; // accumulated rewards uint256 reward; uint256 totalLocked; uint256 rewardPerBoostPoint; } /* ========== STATE VARIABLES ========== */ IERC20 public immutable pearl; IStakingDistributor public distributor; bool public finalized; uint256 _epoch; mapping(uint256 => Epoch) public epochs; // epoch -> unlocked boost points mapping(uint256 => uint256) public unlockedBoostPoints; // note address -> term mapping(address => Term) public terms; address[] public termAddresses; // note address -> token id -> reward paid mapping(address => mapping(uint256 => uint256)) public rewardPerBoostPointPaid; // note address -> token id -> reward mapping(address => mapping(uint256 => uint256)) public rewards; /* ========== CONSTRUCTOR ========== */ constructor( address pearl_, uint256 epochLength_, uint256 firstEpochNumber_, uint256 firstEpochEndTime_ ) { require(pearl_ != address(0)); pearl = IERC20(pearl_); epochs[firstEpochNumber_] = Epoch({ length: epochLength_, number: firstEpochNumber_, endTime: firstEpochEndTime_, totalReward: 0, reward: 0, totalLocked: 0, rewardPerBoostPoint: 0 }); _epoch = firstEpochNumber_; } /* ========== VIEWS ========== */ function epoch() external view override returns (uint256) { return _epoch; } function totalLocked() external view returns (uint256) { return epochs[_epoch].totalLocked; } function balanceOf(address noteAddr, uint256 tokenId) public view returns (uint256) { return terms[noteAddr].note.lockAmount(tokenId); } function termsCount() external view returns (uint256) { return termAddresses.length; } function totalBoostPoint(address owner) external view returns (uint256 sum) { for (uint256 i = 0; i < termAddresses.length; i++) { IPearlNote note = terms[termAddresses[i]].note; uint256 balance = note.balanceOf(owner); for (uint256 j = 0; j < balance; j++) { uint256 tokenId = note.tokenOfOwnerByIndex(owner, j); if (note.endEpoch(tokenId) > _epoch) { sum = sum.add( boostPointOf( address(note), note.tokenOfOwnerByIndex(owner, j) ) ); } } } } function boostPointOf(address noteAddr, uint256 tokenId) public view returns (uint256) { Term memory term = terms[noteAddr]; return term.note.lockAmount(tokenId).mul(term.multiplier).div(100); } function validEpoch(address noteAddr, uint256 tokenId) public view returns (uint256) { IPearlNote note = terms[noteAddr].note; return _epoch < note.endEpoch(tokenId) ? _epoch : note.endEpoch(tokenId).sub(1); } function rewardPerBoostPoint(address noteAddr, uint256 tokenId) public view returns (uint256) { // console.log( // 'reward/point: %s, paid: %s', // epochs[e].rewardPerBoostPoint, // rewardPerBoostPointPaid[noteAddr][tokenId] // ); return epochs[validEpoch(noteAddr, tokenId)].rewardPerBoostPoint.sub( rewardPerBoostPointPaid[noteAddr][tokenId] ); } function reward(address noteAddr, uint256 tokenId) external view returns (uint256) { return rewards[noteAddr][tokenId].add(_pendingReward(noteAddr, tokenId)); } /* ========== MUTATIVE FUNCTIONS ========== */ function lock(address noteAddr, uint256 amount) external nonReentrant notPaused { // console.log( // 'lock epoch: %s term: %s: amount: %s', // _epoch, // termIndex, // amount // ); harvest(); Term memory term = terms[noteAddr]; require(amount > 0, 'OtterLake: cannot lock 0 amount'); require(term.enabled, 'PearVault: term disabled'); require( amount >= term.minLockAmount, 'OtterLake: amount < min lock amount' ); pearl.safeTransferFrom(msg.sender, address(this), amount); pearl.safeApprove(address(term.note), amount); uint256 endEpoch = _epoch.add(term.lockPeriod); uint256 tokenId = term.note.mint(msg.sender, amount, endEpoch); rewardPerBoostPointPaid[noteAddr][tokenId] = epochs[_epoch] .rewardPerBoostPoint; uint256 boostPoint = boostPointOf(noteAddr, tokenId); epochs[_epoch].totalLocked = epochs[_epoch].totalLocked.add(boostPoint); unlockedBoostPoints[endEpoch] = unlockedBoostPoints[endEpoch].add( boostPoint ); emit Locked(msg.sender, noteAddr, tokenId, amount); } function extendLock( address noteAddr, uint256 tokenId, uint256 amount ) public nonReentrant notPaused { harvest(); Term memory term = terms[noteAddr]; require(amount > 0, 'OtterLake: cannot lock 0 amount'); require(term.enabled, 'PearVault: term disabled'); require( terms[noteAddr].note.ownerOf(tokenId) == msg.sender, 'OtterLake: msg.sender is not the note owner' ); uint256 prevEndEpoch = term.note.endEpoch(tokenId); require(prevEndEpoch > _epoch, 'OtterLake: the note is expired'); _updateReward(noteAddr, tokenId); pearl.safeTransferFrom(msg.sender, address(this), amount); pearl.safeApprove(address(term.note), amount); uint256 prevBoostPoint = term .note .lockAmount(tokenId) .mul(term.multiplier) .div(100); uint256 endEpoch = _epoch.add(term.lockPeriod); term.note.extendLock(tokenId, amount, endEpoch); uint256 boostPoint = boostPointOf(noteAddr, tokenId); epochs[_epoch].totalLocked = epochs[_epoch].totalLocked.add( amount.mul(term.multiplier).div(100) ); unlockedBoostPoints[prevEndEpoch] = unlockedBoostPoints[prevEndEpoch] .sub(prevBoostPoint); unlockedBoostPoints[endEpoch] = unlockedBoostPoints[endEpoch].add( boostPoint ); emit Locked(msg.sender, noteAddr, tokenId, amount); } function claimAndLock(address noteAddr, uint256 tokenId) external { uint256 extendingReward = claimReward(noteAddr, tokenId); // console.log('claim and lock: %s', extendingReward); extendLock(noteAddr, tokenId, extendingReward); } function redeem(address noteAddr, uint256 tokenId) public nonReentrant { harvest(); Term memory term = terms[noteAddr]; require( terms[noteAddr].note.ownerOf(tokenId) == msg.sender, 'OtterLake: msg.sender is not the note owner' ); uint256 amount = term.note.burn(tokenId); emit Redeemed(msg.sender, noteAddr, tokenId, amount); } function claimReward(address noteAddr, uint256 tokenId) public nonReentrant returns (uint256) { harvest(); require( terms[noteAddr].note.ownerOf(tokenId) == msg.sender, 'OtterLake: msg.sender is not the note owner' ); uint256 claimableReward = _updateReward(noteAddr, tokenId); // uint256 reward = pendingReward(termIndex, tokenId); if (claimableReward > 0) { // console.log('reward: %s', claimableReward); rewards[noteAddr][tokenId] = 0; pearl.transfer(msg.sender, claimableReward); emit RewardPaid(msg.sender, noteAddr, tokenId, claimableReward); return claimableReward; } return 0; } function exit(address note, uint256 tokenId) external { claimReward(note, tokenId); redeem(note, tokenId); } function harvest() public { if (epochs[_epoch].endTime <= block.timestamp) { Epoch storage e = epochs[_epoch]; if (e.totalLocked > 0) { e.rewardPerBoostPoint = e .totalReward .sub(epochs[_epoch.sub(1)].totalReward) .mul(1e18) .div(e.totalLocked) .add(epochs[_epoch.sub(1)].rewardPerBoostPoint); } else { e.totalReward = e.totalReward.sub(e.reward); } // console.log( // 'distributed epoch: %s locked: %s reward/point: %s', // _epoch, // e.totalLocked, // e.rewardPerBoostPoint // ); uint256 current = pearl.balanceOf(address(this)); distributor.distribute(); uint256 epochReward = pearl.balanceOf(address(this)).sub(current); // advance to next epoch _epoch = _epoch.add(1); epochs[_epoch] = Epoch({ length: e.length, number: _epoch, endTime: e.endTime.add(e.length), totalReward: e.totalReward.add(epochReward), reward: epochReward, totalLocked: e.totalLocked.sub(unlockedBoostPoints[_epoch]), rewardPerBoostPoint: e.rewardPerBoostPoint }); // console.log( // 'start epoch: %s locked: %s reward: %s', // _epoch, // epochs[_epoch].totalLocked, // epochReward // ); } } /* ========== INTERNAL FUNCTIONS ========== */ function _updateReward(address noteAddr, uint256 tokenId) internal returns (uint256) { rewards[noteAddr][tokenId] = rewards[noteAddr][tokenId].add( _pendingReward(noteAddr, tokenId) ); rewardPerBoostPointPaid[noteAddr][tokenId] = epochs[ validEpoch(noteAddr, tokenId) ].rewardPerBoostPoint; return rewards[noteAddr][tokenId]; } function _pendingReward(address noteAddr, uint256 tokenId) internal view returns (uint256) { return boostPointOf(noteAddr, tokenId) .mul(rewardPerBoostPoint(noteAddr, tokenId)) .div(1e18); } /* ========== RESTRICTED FUNCTIONS ========== */ function setDistributor(address distributor_) external onlyOwner { distributor = IStakingDistributor(distributor_); } // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner { if (finalized) { // @dev if something wrong, dev can extract reward to recover the lose require( tokenAddress != address(pearl), 'OtterLake: Cannot withdraw the pearl' ); } IERC20(tokenAddress).safeTransfer(owner(), tokenAmount); emit Recovered(tokenAddress, tokenAmount); } function finalize() external onlyOwner { finalized = true; } function addTerm( address note_, uint256 minLockAmount_, uint256 lockPeriod_, uint16 multiplier_ ) public onlyOwner { require( multiplier_ < 1000, 'OtterLake: multiplier cannot larger than x10' ); require( terms[note_].multiplier == 0, 'OtterLake: duplicate note added' ); IPearlNote note = IPearlNote(note_); // @dev: check the note address is valid note.lockAmount(0); terms[note_] = Term({ note: note, minLockAmount: minLockAmount_, lockPeriod: lockPeriod_, multiplier: multiplier_, enabled: true }); termAddresses.push(note_); emit TermAdded(note_, minLockAmount_, lockPeriod_, multiplier_); } enum TERM_SETTING { MIN_LOCK_AMOUNT, LOCK_PERIOD } function setTerm( address note_, TERM_SETTING setting_, uint256 value_ ) external onlyOwner { if (setting_ == TERM_SETTING.MIN_LOCK_AMOUNT) { // 0 terms[note_].minLockAmount = value_; } else if (setting_ == TERM_SETTING.LOCK_PERIOD) { // 1 terms[note_].lockPeriod = value_; } emit TermUpdated(note_, setting_, value_); } function disableTerm(address note_) external onlyOwner { terms[note_].enabled = false; emit TermDisabled(note_); } function removeTermAt(uint256 index) external onlyOwner { require(index < termAddresses.length); address termAddress = termAddresses[index]; address note = address(terms[termAddress].note); // delete from map delete terms[termAddress]; // delete from array termAddresses[index] = termAddresses[termAddresses.length - 1]; delete termAddresses[termAddresses.length - 1]; emit TermRemoved(note); } /* ========== EVENTS ========== */ event TermAdded( address indexed note, uint256 minLockAmount, uint256 lockPeriod, uint16 multiplier ); event TermDisabled(address indexed note); event TermRemoved(address indexed note); event TermUpdated( address indexed note, TERM_SETTING setting, uint256 value ); event RewardAdded(uint256 epoch, uint256 reward); event Locked( address indexed user, address indexed note, uint256 indexed tokenId, uint256 amount ); event Redeemed( address indexed user, address indexed note, uint256 indexed tokenId, uint256 amount ); event RewardPaid( address indexed user, address indexed note, uint256 indexed tokenId, uint256 reward ); event Recovered(address token, uint256 amount); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity >=0.5.0; interface IERC20 { event Approval( address indexed owner, address indexed spender, uint256 value ); event Transfer(address indexed from, address indexed to, uint256 value); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); } interface IERC20Mintable { function mint(uint256 amount_) external; function mint(address account_, uint256 ammount_) external; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity >=0.7.5; import '@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol'; interface IPearlNote is IERC721Enumerable { function lockAmount(uint256 tokenId) external view returns (uint256); function endEpoch(uint256 tokenId) external view returns (uint256); /// @dev Extend the NFT lock period /// @param _tokenId the token id need to extend /// @param _amount The extra lock amount /// @param _endEpoch The lock due date function extendLock( uint256 _tokenId, uint256 _amount, uint256 _endEpoch ) external; /// @dev Mint a new ERC721 to represent receipt of lock /// @param _user The locker, who will receive this token /// @param _amount The lock amount /// @param _endEpoch The lock due date /// @return token id minted function mint( address _user, uint256 _amount, uint256 _endEpoch ) external returns (uint256); /// @dev Burn the NFT and get token locked inside back /// @param tokenId the token id which got burned /// @return the amount of unlocked token function burn(uint256 tokenId) external returns (uint256); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; interface IStakingDistributor { function distribute() external returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; interface IOtterLake { function epoch() external view returns (uint256); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, 'SafeMath: addition overflow'); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, 'SafeMath: subtraction overflow'); } function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, 'SafeMath: multiplication overflow'); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, 'SafeMath: division by zero'); } function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function sqrrt(uint256 a) internal pure returns (uint256 c) { if (a > 3) { c = a; uint256 b = add(div(a, 2), 1); while (b < c) { c = b; b = div(add(div(a, b), b), 2); } } else if (a != 0) { c = 1; } } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; import '../interfaces/IERC20.sol'; import './SafeMath.sol'; import './Counters.sol'; import './Address.sol'; library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } function safeApprove( IERC20 token, address spender, uint256 value ) internal { require( (value == 0) || (token.allowance(address(this), spender) == 0), 'SafeERC20: approve from non-zero to non-zero allowance' ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, value) ); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).add( value ); _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).sub( value, 'SafeERC20: decreased allowance below zero' ); _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function _callOptionalReturn(IERC20 token, bytes memory data) private { bytes memory returndata = address(token).functionCall( data, 'SafeERC20: low-level call failed' ); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require( abi.decode(returndata, (bool)), 'SafeERC20: ERC20 operation did not succeed' ); } } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; import "./Ownable.sol"; // https://docs.synthetix.io/contracts/source/contracts/pausable abstract contract Pausable is Ownable { uint public lastPauseTime; bool public paused; constructor() { // This contract is abstract, and thus cannot be instantiated directly require(_owner != address(0), "Owner must be set"); // Paused will be false, and lastPauseTime will be 0 upon initialisation } /** * @notice Change the paused state of the contract * @dev Only the contract owner may call this. */ function setPaused(bool _paused) external onlyOwner { // Ensure we're actually changing the state before we do anything if (_paused == paused) { return; } // Set our paused state. paused = _paused; // If applicable, set the last pause time. if (paused) { lastPauseTime = block.timestamp; } // Let everyone know that our pause state has changed. emit PauseChanged(paused); } event PauseChanged(bool isPaused); modifier notPaused { require(!paused, "This action cannot be performed while the contract is paused"); _; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (security/ReentrancyGuard.sol) pragma solidity 0.7.5; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "../../introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; import './SafeMath.sol'; library Counters { using SafeMath for uint256; struct Counter { uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; library Address { function isContract(address account) internal view returns (bool) { uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } function sendValue(address payable recipient, uint256 amount) internal { require( address(this).balance >= amount, 'Address: insufficient balance' ); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{value: amount}(''); require( success, 'Address: unable to send value, recipient may have reverted' ); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, 'Address: low-level call failed'); } function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, 'Address: low-level call with value failed' ); } function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require( address(this).balance >= value, 'Address: insufficient balance for call' ); require(isContract(target), 'Address: call to non-contract'); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{value: value}( data ); return _verifyCallResult(success, returndata, errorMessage); } function _functionCallWithValue( address target, bytes memory data, uint256 weiValue, string memory errorMessage ) private returns (bytes memory) { require(isContract(target), 'Address: call to non-contract'); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{value: weiValue}( data ); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall( target, data, 'Address: low-level static call failed' ); } function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), 'Address: static call to non-contract'); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall( target, data, 'Address: low-level delegate call failed' ); } function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), 'Address: delegate call to non-contract'); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) private pure returns (bytes memory) { if (success) { return returndata; } else { if (returndata.length > 0) { assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } function addressToString(address _address) internal pure returns (string memory) { bytes32 _bytes = bytes32(uint256(_address)); bytes memory HEX = '0123456789abcdef'; bytes memory _addr = new bytes(42); _addr[0] = '0'; _addr[1] = 'x'; for (uint256 i = 0; i < 20; i++) { _addr[2 + i * 2] = HEX[uint8(_bytes[i + 12] >> 4)]; _addr[3 + i * 2] = HEX[uint8(_bytes[i + 12] & 0x0f)]; } return string(_addr); } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; interface IOwnable { function owner() external view returns (address); function renounceManagement() external; function pushManagement(address newOwner_) external; function pullManagement() external; } contract Ownable is IOwnable { address internal _owner; address internal _newOwner; event OwnershipPushed( address indexed previousOwner, address indexed newOwner ); event OwnershipPulled( address indexed previousOwner, address indexed newOwner ); constructor() { _owner = msg.sender; emit OwnershipPushed(address(0), _owner); } function owner() public view override returns (address) { return _owner; } modifier onlyOwner() { require(_owner == msg.sender, 'Ownable: caller is not the owner'); _; } function renounceManagement() public virtual override onlyOwner { emit OwnershipPushed(_owner, address(0)); _owner = address(0); } function pushManagement(address newOwner_) public virtual override onlyOwner { require( newOwner_ != address(0), 'Ownable: new owner is the zero address' ); emit OwnershipPushed(_owner, newOwner_); _newOwner = newOwner_; } function pullManagement() public virtual override { require(msg.sender == _newOwner, 'Ownable: must be new owner to pull'); emit OwnershipPulled(_owner, _newOwner); _owner = _newOwner; } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"pearl_","type":"address"},{"internalType":"uint256","name":"epochLength_","type":"uint256"},{"internalType":"uint256","name":"firstEpochNumber_","type":"uint256"},{"internalType":"uint256","name":"firstEpochEndTime_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"note","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipPulled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipPushed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PauseChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"note","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Redeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"note","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"note","type":"address"},{"indexed":false,"internalType":"uint256","name":"minLockAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lockPeriod","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"multiplier","type":"uint16"}],"name":"TermAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"note","type":"address"}],"name":"TermDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"note","type":"address"}],"name":"TermRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"note","type":"address"},{"indexed":false,"internalType":"enum OtterLake.TERM_SETTING","name":"setting","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TermUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"note_","type":"address"},{"internalType":"uint256","name":"minLockAmount_","type":"uint256"},{"internalType":"uint256","name":"lockPeriod_","type":"uint256"},{"internalType":"uint16","name":"multiplier_","type":"uint16"}],"name":"addTerm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"noteAddr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"noteAddr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"boostPointOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"noteAddr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"claimAndLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"noteAddr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"claimReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"note_","type":"address"}],"name":"disableTerm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributor","outputs":[{"internalType":"contract IStakingDistributor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochs","outputs":[{"internalType":"uint256","name":"length","type":"uint256"},{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"totalReward","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"totalLocked","type":"uint256"},{"internalType":"uint256","name":"rewardPerBoostPoint","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"note","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"noteAddr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"extendLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"noteAddr","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pearl","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pullManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner_","type":"address"}],"name":"pushManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"noteAddr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"removeTermAt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"noteAddr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"reward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"noteAddr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"rewardPerBoostPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardPerBoostPointPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"distributor_","type":"address"}],"name":"setDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"note_","type":"address"},{"internalType":"enum OtterLake.TERM_SETTING","name":"setting_","type":"uint8"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"setTerm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"termAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"terms","outputs":[{"internalType":"contract IPearlNote","name":"note","type":"address"},{"internalType":"uint256","name":"minLockAmount","type":"uint256"},{"internalType":"uint256","name":"lockPeriod","type":"uint256"},{"internalType":"uint16","name":"multiplier","type":"uint16"},{"internalType":"bool","name":"enabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"termsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"totalBoostPoint","outputs":[{"internalType":"uint256","name":"sum","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"unlockedBoostPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"noteAddr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"validEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b506040516200594238038062005942833981810160405260808110156200003757600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190505050600160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415620001f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f4f776e6572206d7573742062652073657400000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156200022d57600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250506040518060e00160405280848152602001838152602001828152602001600081526020016000815260200160008152602001600081525060066000848152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c08201518160060155905050816005819055505050505060805160601c6155fa620003486000398061148252806114d25280611bb852806126c652806127165280612ef052806130605280613dee528061484652506155fa6000f3fe608060405234801561001057600080fd5b506004361061023c5760003560e01c80635a96ac0a1161013b578063a42993ff116100b8578063c6b61e4c1161007c578063c6b61e4c14610ae8578063c8c819ac14610b54578063dc19c4d814610be4578063eecd230014610c18578063ef693bed14610c365761023c565b8063a42993ff1461096a578063b3f05b97146109d0578063b933ceac146109f0578063bcc8f93414610a52578063bfe1092814610ab45761023c565b80638980f11f116100ff5780638980f11f1461084a5780638da5cb5b14610898578063900cf0cf146108cc57806391b4ded9146108ea578063a23a8b56146109085761023c565b80635a96ac0a1461076a5780635c975abb146107745780636bd19f261461079457806375619ab5146107d85780637facfde41461081c5761023c565b806325925ea3116101c957806346f68ee91161018d57806346f68ee9146106445780634bb278f314610688578063510bdcf01461069257806355e8f1e1146106ea578063568914121461074c5761023c565b806325925ea3146104f0578063282d3fdf146105325780633789ae231461058057806338d64f58146105d85780634641257d1461063a5761023c565b806316c38b3c1161021057806316c38b3c14610353578063174e31c4146103835780631e9a6950146103e5578063210acac51461043357806321670f221461048e5761023c565b8062fdd58e1461024157806304bc60b6146102a3578063089208d8146102f15780630bd2f005146102fb575b600080fd5b61028d6004803603604081101561025757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c84565b6040518082815260200191505060405180910390f35b6102ef600480360360408110156102b957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d7c565b005b6102f9610d9a565b005b6103516004803603606081101561031157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610f1e565b005b6103816004803603602081101561036957600080fd5b810190808035151590602001909291905050506117e7565b005b6103cf6004803603604081101561039957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061194d565b6040518082815260200191505060405180910390f35b610431600480360360408110156103fb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611d06565b005b61048c6004803603606081101561044957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff16906020019092919080359060200190929190505050612103565b005b6104da600480360360408110156104a457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506122fe565b6040518082815260200191505060405180910390f35b61051c6004803603602081101561050657600080fd5b8101908080359060200190929190505050612374565b6040518082815260200191505060405180910390f35b61057e6004803603604081101561054857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061238c565b005b6105c26004803603602081101561059657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506129a8565b6040518082815260200191505060405180910390f35b610624600480360360408110156105ee57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612d3b565b6040518082815260200191505060405180910390f35b610642612dc7565b005b6106866004803603602081101561065a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613248565b005b610690613451565b005b6106be600480360360208110156106a857600080fd5b8101908080359060200190929190505050613531565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107366004803603604081101561070057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613570565b6040518082815260200191505060405180910390f35b610754613595565b6040518082815260200191505060405180910390f35b6107726135b5565b005b61077c61375e565b60405180821515815260200191505060405180910390f35b6107d6600480360360208110156107aa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613771565b005b61081a600480360360208110156107ee57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506138d5565b005b6108486004803603602081101561083257600080fd5b81019080803590602001909291905050506139dc565b005b6108966004803603604081101561086057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613d14565b005b6108a0613f1d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108d4613f47565b6040518082815260200191505060405180910390f35b6108f2613f51565b6040518082815260200191505060405180910390f35b6109546004803603604081101561091e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613f57565b6040518082815260200191505060405180910390f35b6109ce6004803603608081101561098057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803561ffff169060200190929190505050614118565b005b6109d8614586565b60405180821515815260200191505060405180910390f35b610a3c60048036036040811015610a0657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614599565b6040518082815260200191505060405180910390f35b610a9e60048036036040811015610a6857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506145be565b6040518082815260200191505060405180910390f35b610abc61476b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610b1460048036036020811015610afe57600080fd5b8101908080359060200190929190505050614791565b6040518088815260200187815260200186815260200185815260200184815260200183815260200182815260200197505050505050505060405180910390f35b610b9660048036036020811015610b6a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506147d3565b604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020018361ffff16815260200182151581526020019550505050505060405180910390f35b610bec614844565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c20614868565b6040518082815260200191505060405180910390f35b610c8260048036036040811015610c4c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614875565b005b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663daa58555836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610d3957600080fd5b505afa158015610d4d573d6000803e3d6000fd5b505050506040513d6020811015610d6357600080fd5b8101908080519060200190929190505050905092915050565b6000610d88838361194d565b9050610d95838383610f1e565b505050565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e5d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a36000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60026000541415610f97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600081905550600460009054906101000a900460ff1615611005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180615529603c913960400191505060405180910390fd5b61100d612dc7565b6110156153d6565b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900461ffff1661ffff1661ffff1681526020016003820160029054906101000a900460ff16151515158152505090506000821161117c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4f747465724c616b653a2063616e6e6f74206c6f636b203020616d6f756e740081525060200191505060405180910390fd5b80608001516111f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f506561725661756c743a207465726d2064697361626c6564000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156112bd57600080fd5b505afa1580156112d1573d6000803e3d6000fd5b505050506040513d60208110156112e757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614611364576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b81526020018061548f602b913960400191505060405180910390fd5b6000816000015173ffffffffffffffffffffffffffffffffffffffff16636164e45d856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156113bb57600080fd5b505afa1580156113cf573d6000803e3d6000fd5b505050506040513d60208110156113e557600080fd5b81019080805190602001909291905050509050600554811161146f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f747465724c616b653a20746865206e6f74652069732065787069726564000081525060200191505060405180910390fd5b611479858561488e565b506114c73330857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16614a1d909392919063ffffffff16565b6115168260000151847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16614ade9092919063ffffffff16565b60006115d560646115c7856060015161ffff16866000015173ffffffffffffffffffffffffffffffffffffffff1663daa585558a6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561157e57600080fd5b505afa158015611592573d6000803e3d6000fd5b505050506040513d60208110156115a857600080fd5b8101908080519060200190929190505050614ca390919063ffffffff16565b614d2990919063ffffffff16565b905060006115f28460400151600554614d7390919063ffffffff16565b9050836000015173ffffffffffffffffffffffffffffffffffffffff1663ffe60d2a8787846040518463ffffffff1660e01b8152600401808481526020018381526020018281526020019350505050600060405180830381600087803b15801561165b57600080fd5b505af115801561166f573d6000803e3d6000fd5b50505050600061167f8888613f57565b90506116d96116b260646116a4886060015161ffff168a614ca390919063ffffffff16565b614d2990919063ffffffff16565b60066000600554815260200190815260200160002060050154614d7390919063ffffffff16565b6006600060055481526020019081526020016000206005018190555061171b836007600087815260200190815260200160002054614dfb90919063ffffffff16565b6007600086815260200190815260200160002081905550611758816007600085815260200190815260200160002054614d7390919063ffffffff16565b6007600084815260200190815260200160002081905550868873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f967ad762aa9070ada8db64577288e214771e89667066ae38e8750cb8a86c5429896040518082815260200191505060405180910390a450505050506001600081905550505050565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146118aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600460009054906101000a900460ff16151581151514156118ca5761194a565b80600460006101000a81548160ff021916908315150217905550600460009054906101000a900460ff161561190157426003819055505b7f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5600460009054906101000a900460ff1660405180821515815260200191505060405180910390a15b50565b6000600260005414156119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026000819055506119d8612dc7565b3373ffffffffffffffffffffffffffffffffffffffff16600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611aa257600080fd5b505afa158015611ab6573d6000803e3d6000fd5b505050506040513d6020811015611acc57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614611b49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b81526020018061548f602b913960400191505060405180910390fd5b6000611b55848461488e565b90506000811115611cf2576000600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611c4757600080fd5b505af1158015611c5b573d6000803e3d6000fd5b505050506040513d6020811015611c7157600080fd5b810190808051906020019092919050505050828473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ff3d804b61a64faf0efebbb149ce09c7269a116f5d28dd046d4a848bcf36049c3846040518082815260200191505060405180910390a480915050611cf8565b60009150505b600160008190555092915050565b60026000541415611d7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600081905550611d8f612dc7565b611d976153d6565b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900461ffff1661ffff1661ffff1681526020016003820160029054906101000a900460ff16151515158152505090503373ffffffffffffffffffffffffffffffffffffffff16600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f5257600080fd5b505afa158015611f66573d6000803e3d6000fd5b505050506040513d6020811015611f7c57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614611ff9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b81526020018061548f602b913960400191505060405180910390fd5b6000816000015173ffffffffffffffffffffffffffffffffffffffff166342966c68846040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561205257600080fd5b505af1158015612066573d6000803e3d6000fd5b505050506040513d602081101561207c57600080fd5b81019080805190602001909291905050509050828473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f5cdf07ad0fc222442720b108e3ed4c4640f0fadc2ab2253e66f259a0fea83480846040518082815260200191505060405180910390a4505060016000819055505050565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146121c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060018111156121d357fe5b8260018111156121df57fe5b14156122315780600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550612298565b60018081111561223d57fe5b82600181111561224957fe5b14156122975780600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201819055505b5b8273ffffffffffffffffffffffffffffffffffffffff167f75f2be053da56a09346c7d96ea6191663296f5087565626b38d2a6f86bc0bc758383604051808360018111156122e257fe5b81526020018281526020019250505060405180910390a2505050565b600061236c61230d8484614e45565b600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085815260200190815260200160002054614d7390919063ffffffff16565b905092915050565b60076020528060005260406000206000915090505481565b60026000541415612405576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600081905550600460009054906101000a900460ff1615612473576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180615529603c913960400191505060405180910390fd5b61247b612dc7565b6124836153d6565b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900461ffff1661ffff1661ffff1681526020016003820160029054906101000a900460ff1615151515815250509050600082116125ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4f747465724c616b653a2063616e6e6f74206c6f636b203020616d6f756e740081525060200191505060405180910390fd5b8060800151612661576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f506561725661756c743a207465726d2064697361626c6564000000000000000081525060200191505060405180910390fd5b80602001518210156126be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806154226023913960400191505060405180910390fd5b61270b3330847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16614a1d909392919063ffffffff16565b61275a8160000151837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16614ade9092919063ffffffff16565b60006127758260400151600554614d7390919063ffffffff16565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1663156e29f63386856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b1580156127f657600080fd5b505af115801561280a573d6000803e3d6000fd5b505050506040513d602081101561282057600080fd5b8101908080519060200190929190505050905060066000600554815260200190815260200160002060060154600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000208190555060006128ac8683613f57565b90506128d98160066000600554815260200190815260200160002060050154614d7390919063ffffffff16565b6006600060055481526020019081526020016000206005018190555061291b816007600086815260200190815260200160002054614d7390919063ffffffff16565b6007600085815260200190815260200160002081905550818673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f967ad762aa9070ada8db64577288e214771e89667066ae38e8750cb8a86c5429886040518082815260200191505060405180910390a45050505060016000819055505050565b600080600090505b600980549050811015612d3557600060086000600984815481106129d057fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612ac457600080fd5b505afa158015612ad8573d6000803e3d6000fd5b505050506040513d6020811015612aee57600080fd5b8101908080519060200190929190505050905060005b81811015612d255760008373ffffffffffffffffffffffffffffffffffffffff16632f745c5988846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b158015612b7d57600080fd5b505afa158015612b91573d6000803e3d6000fd5b505050506040513d6020811015612ba757600080fd5b810190808051906020019092919050505090506005548473ffffffffffffffffffffffffffffffffffffffff16636164e45d836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612c0e57600080fd5b505afa158015612c22573d6000803e3d6000fd5b505050506040513d6020811015612c3857600080fd5b81019080805190602001909291905050501115612d1757612d14612d05858673ffffffffffffffffffffffffffffffffffffffff16632f745c598b876040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b158015612cc557600080fd5b505afa158015612cd9573d6000803e3d6000fd5b505050506040513d6020811015612cef57600080fd5b8101908080519060200190929190505050613f57565b87614d7390919063ffffffff16565b95505b508080600101915050612b04565b50505080806001019150506129b0565b50919050565b6000612dbf600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000205460066000612d9f87876145be565b815260200190815260200160002060060154614dfb90919063ffffffff16565b905092915050565b4260066000600554815260200190815260200160002060020154116132465760006006600060055481526020019081526020016000209050600081600501541115612ec857612ebb60066000612e296001600554614dfb90919063ffffffff16565b815260200190815260200160002060060154612ead8360050154612e9f670de0b6b3a7640000612e9160066000612e6c6001600554614dfb90919063ffffffff16565b8152602001908152602001600020600301548860030154614dfb90919063ffffffff16565b614ca390919063ffffffff16565b614d2990919063ffffffff16565b614d7390919063ffffffff16565b8160060181905550612eec565b612ee381600401548260030154614dfb90919063ffffffff16565b81600301819055505b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015612f7557600080fd5b505afa158015612f89573d6000803e3d6000fd5b505050506040513d6020811015612f9f57600080fd5b81019080805190602001909291905050509050600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4fc6b6d6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561301c57600080fd5b505af1158015613030573d6000803e3d6000fd5b505050506040513d602081101561304657600080fd5b810190808051906020019092919050505050600061312e827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156130e557600080fd5b505afa1580156130f9573d6000803e3d6000fd5b505050506040513d602081101561310f57600080fd5b8101908080519060200190929190505050614dfb90919063ffffffff16565b90506131466001600554614d7390919063ffffffff16565b6005819055506040518060e0016040528084600001548152602001600554815260200161318485600001548660020154614d7390919063ffffffff16565b81526020016131a0838660030154614d7390919063ffffffff16565b81526020018281526020016131d7600760006005548152602001908152602001600020548660050154614dfb90919063ffffffff16565b81526020018460060154815250600660006005548152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c082015181600601559050505050505b565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461330b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613391576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806154456026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613514576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6001600460156101000a81548160ff021916908315150217905550565b6009818154811061354157600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600a602052816000526040600020602052806000526040600020600091509150505481565b600060066000600554815260200190815260200160002060050154905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461365b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806154ba6022913960400191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600460009054906101000a900460ff1681565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613834576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160026101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167fad8dbe2839ed674defa7c3f7cdadfd77ad05f8608d6fe4c6d4737cd3097e287c60405160405180910390a250565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613998576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600460016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613a9f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6009805490508110613ab057600080fd5b600060098281548110613abf57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000905560028201600090556003820160006101000a81549061ffff02191690556003820160026101000a81549060ff02191690555050600960016009805490500381548110613c0a57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660098481548110613c4257fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600960016009805490500381548110613c9f57fe5b9060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690558073ffffffffffffffffffffffffffffffffffffffff167f9cf2385a1cf3ce2c1c86b41250880073aca6432036d4925e66f8c453305c711d60405160405180910390a2505050565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613dd7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600460159054906101000a900460ff1615613e92577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613e91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018061546b6024913960400191505060405180910390fd5b5b613ec4613e9d613f1d565b828473ffffffffffffffffffffffffffffffffffffffff16614e8e9092919063ffffffff16565b7f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa288282604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600554905090565b60035481565b6000613f616153d6565b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820160009054906101000a900461ffff1661ffff1661ffff1681526020016003820160029054906101000a900460ff161515151581525050905061410f6064614101836060015161ffff16846000015173ffffffffffffffffffffffffffffffffffffffff1663daa58555886040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156140b857600080fd5b505afa1580156140cc573d6000803e3d6000fd5b505050506040513d60208110156140e257600080fd5b8101908080519060200190929190505050614ca390919063ffffffff16565b614d2990919063ffffffff16565b91505092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146141db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6103e88161ffff1610614239576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806154dc602c913960400191505060405180910390fd5b6000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160009054906101000a900461ffff1661ffff1614614303576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4f747465724c616b653a206475706c6963617465206e6f74652061646465640081525060200191505060405180910390fd5b60008490508073ffffffffffffffffffffffffffffffffffffffff1663daa5855560006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561435a57600080fd5b505afa15801561436e573d6000803e3d6000fd5b505050506040513d602081101561438457600080fd5b8101908080519060200190929190505050506040518060a001604052808273ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020018361ffff16815260200160011515815250600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015560608201518160030160006101000a81548161ffff021916908361ffff16021790555060808201518160030160026101000a81548160ff0219169083151502179055509050506009859080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508473ffffffffffffffffffffffffffffffffffffffff167fde5b4c960c64dd462ec65912d78dc6af20e2e428af076a5995d743ffa1fb74a6858585604051808481526020018381526020018261ffff168152602001935050505060405180910390a25050505050565b600460159054906101000a900460ff1681565b600b602052816000526040600020602052806000526040600020600091509150505481565b600080600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff16636164e45d846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561467757600080fd5b505afa15801561468b573d6000803e3d6000fd5b505050506040513d60208110156146a157600080fd5b81019080805190602001909291905050506005541061475e5761475960018273ffffffffffffffffffffffffffffffffffffffff16636164e45d866040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561471057600080fd5b505afa158015614724573d6000803e3d6000fd5b505050506040513d602081101561473a57600080fd5b8101908080519060200190929190505050614dfb90919063ffffffff16565b614762565b6005545b91505092915050565b600460019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60066020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154905087565b60086020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020154908060030160009054906101000a900461ffff16908060030160029054906101000a900460ff16905085565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600980549050905090565b61487f828261194d565b5061488a8282611d06565b5050565b60006148fc61489d8484614e45565b600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085815260200190815260200160002054614d7390919063ffffffff16565b600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020819055506006600061495e85856145be565b815260200190815260200160002060060154600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b614ad8846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614f30565b50505050565b6000811480614bac575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015614b6f57600080fd5b505afa158015614b83573d6000803e3d6000fd5b505050506040513d6020811015614b9957600080fd5b8101908080519060200190929190505050145b614c01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061558f6036913960400191505060405180910390fd5b614c9e8363095ea7b360e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614f30565b505050565b600080831415614cb65760009050614d23565b6000828402905082848281614cc757fe5b0414614d1e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806155086021913960400191505060405180910390fd5b809150505b92915050565b6000614d6b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061501f565b905092915050565b600080828401905083811015614df1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000614e3d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506150e5565b905092915050565b6000614e86670de0b6b3a7640000614e78614e608686612d3b565b614e6a8787613f57565b614ca390919063ffffffff16565b614d2990919063ffffffff16565b905092915050565b614f2b8363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614f30565b505050565b6060614f92826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166151a59092919063ffffffff16565b905060008151111561501a57808060200190516020811015614fb357600080fd5b8101908080519060200190929190505050615019576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615565602a913960400191505060405180910390fd5b5b505050565b600080831182906150cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615090578082015181840152602081019050615075565b50505050905090810190601f1680156150bd5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816150d757fe5b049050809150509392505050565b6000838311158290615192576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561515757808201518184015260208101905061513c565b50505050905090810190601f1680156151845780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60606151b484846000856151bd565b90509392505050565b60606151c8856153c3565b61523a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061528a5780518252602082019150602081019050602083039250615267565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146152ec576040519150601f19603f3d011682016040523d82523d6000602084013e6152f1565b606091505b509150915081156153065780925050506153bb565b6000815111156153195780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615380578082015181840152602081019050615365565b50505050905090810190601f1680156153ad5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060a00160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600061ffff168152602001600015158152509056fe4f747465724c616b653a20616d6f756e74203c206d696e206c6f636b20616d6f756e744f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f747465724c616b653a2043616e6e6f742077697468647261772074686520706561726c4f747465724c616b653a206d73672e73656e646572206973206e6f7420746865206e6f7465206f776e65724f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4f747465724c616b653a206d756c7469706c6965722063616e6e6f74206c6172676572207468616e20783130536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775468697320616374696f6e2063616e6e6f7420626520706572666f726d6564207768696c652074686520636f6e7472616374206973207061757365645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a26469706673582212201e1f69dbaf963c6066c49f751873d17fbe8842888c9da1c9952e61a41c91378d64736f6c6343000705003300000000000000000000000052a7f40bb6e9bd9183071cdbdd3a977d713f2e34000000000000000000000000000000000000000000000000000000000000708000000000000000000000000000000000000000000000000000000000000000cf0000000000000000000000000000000000000000000000000000000061dc5800
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000052a7f40bb6e9bd9183071cdbdd3a977d713f2e34000000000000000000000000000000000000000000000000000000000000708000000000000000000000000000000000000000000000000000000000000000cf0000000000000000000000000000000000000000000000000000000061dc5800
-----Decoded View---------------
Arg [0] : pearl_ (address): 0x52a7f40bb6e9bd9183071cdbdd3a977d713f2e34
Arg [1] : epochLength_ (uint256): 28800
Arg [2] : firstEpochNumber_ (uint256): 207
Arg [3] : firstEpochEndTime_ (uint256): 1641830400
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000052a7f40bb6e9bd9183071cdbdd3a977d713f2e34
Arg [1] : 0000000000000000000000000000000000000000000000000000000000007080
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000cf
Arg [3] : 0000000000000000000000000000000000000000000000000000000061dc5800
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.