Contract 0xc67abda25d0421fe9dc1afd64183b179a426a256 1

 
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xfd80b9d8216ddbd2c097d5bd6145836f7495cddd3689dd64cfa9fe0978c5963dHarvest284872352022-05-19 0:01:091 hr 30 mins ago0x7dca198ee51305579138b2c8508ba7f05ec561c9 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.0304476 75
0x4ba2daf55ca2d1dc9bd289c4a1ec31bff8719408b366f899ac622d0cf653f55dExtend Lock284872012022-05-18 23:59:571 hr 31 mins ago0xa15cc7a81dd811bbdd72eb398878170cec97c3d9 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.00441393645 31.359225674
0x0d98cb47c9987ce6fc2b8d2975e2d1f8237a9af121767dd366938c45c7d97aa2Claim Reward284871902022-05-18 23:59:351 hr 32 mins ago0xa15cc7a81dd811bbdd72eb398878170cec97c3d9 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.00279878245 31.992300791
0xf80d52664c25603516b990d64c24d2991a5b9a746767e3261302b3a07960032eClaim Reward284870082022-05-18 23:53:191 hr 38 mins ago0xa15cc7a81dd811bbdd72eb398878170cec97c3d9 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.002861058637 32.700802783
0x47d2539bec8b2037a21daaad3439404d181f80fa928502d1133433dd8b188bdeExtend Lock284795662022-05-18 19:30:406 hrs 1 min ago0x3beacf93afbf754a3da65a3fb910363c54c6732f IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.004322149821 32.498833193
0xa6240908cbdfb9ba1f5c8012287a9998bf7bca248ed741148ea63ac7d16bc46bClaim Reward284795472022-05-18 19:29:586 hrs 1 min ago0x3beacf93afbf754a3da65a3fb910363c54c6732f IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.002906051018 33.218465509
0x1f185566819a05fdbd6454ef72d33e7afd948727566ed3081c11932f45c2e3b8Claim Reward284795322022-05-18 19:29:286 hrs 2 mins ago0x3beacf93afbf754a3da65a3fb910363c54c6732f IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.003036502952 34.709634475
0x85015ce7afcb40236db864f82345d2efb8929b708ff7f516dbcf81ee427ebe08Claim Reward284795242022-05-18 19:29:126 hrs 2 mins ago0x3beacf93afbf754a3da65a3fb910363c54c6732f IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.003538268376 34.10280548
0xad73893180706b35966f7a216e36c05e71c166f1c81cfd0858470570cc6c06c2Lock284753702022-05-18 16:55:388 hrs 36 mins ago0x8671ea040877d6f471f0cceb6ece826a5d3ed18c IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.013104545775 42.079974875
0x1ca6d93ed2c852fd952c103d2f0b198e50baaf2cf5c23096a05b7e8284606820Exit284753482022-05-18 16:54:548 hrs 37 mins ago0x8671ea040877d6f471f0cceb6ece826a5d3ed18c IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.008151917805 47.106752915
0xaeb313cb433a052660b0240492beab814f65bfc10082c5508268ecda9a7e21daHarvest284739102022-05-18 16:01:109 hrs 30 mins ago0x7dca198ee51305579138b2c8508ba7f05ec561c9 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.0304476 75
0x7bc56d1bde8a6ac9bad3b2900a5df8815116925b2ca0910c5708a12ce3675ddeLock284713772022-05-18 14:27:4411 hrs 4 mins ago0xc884c637199595b5683e9cffb04aac1c336bebff IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.051568027818 165.583587487
0x2c43c725b7200a01cd1249a8978fcb5931d756a9d93503d59f056117bf039406Exit284713122022-05-18 14:25:3011 hrs 6 mins ago0xc884c637199595b5683e9cffb04aac1c336bebff IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.042144395428 243.536020552
0x310e0a321d33a34658d499ce8f32114cb6aac060e5beb881ec345dab7a88369aLock284707912022-05-18 14:01:2811 hrs 30 mins ago0x6a3d51fe0372ae4c0dc0c7d23e81560ecd3bce18 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.048637504458 156.179771558
0x355aaf1276f65cc26558d28c0229135aa304a05e532d4aa8ce0c01a24c55d60fExit284705392022-05-18 13:52:3211 hrs 39 mins ago0x6a3d51fe0372ae4c0dc0c7d23e81560ecd3bce18 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.011805605525 74.075781977
0x3b19bf8926208dfc641a94856b077845c02046fdc940c92546734b56bcbe1461Extend Lock284694882022-05-18 13:14:1412 hrs 17 mins ago0x1743c1f76bb50efe94cfdd0726eb4e61fe63b63f IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.00497476407 31.353686802
0x73fd919f8c8ea78f0ce1be45b37cd4e281fbe1f530ae2db66e9755f8805bb79fClaim Reward284694432022-05-18 13:12:4412 hrs 19 mins ago0x1743c1f76bb50efe94cfdd0726eb4e61fe63b63f IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.003961954149 38.186405692
0xdd7cad1868ebcd877185b38af0643ae5544aa72e8e7562d14420274a60b67ed2Claim Reward284683912022-05-18 12:29:1613 hrs 2 mins ago0xc8728ae130381eb77fc9a8b715564b00e83e19df IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.003120213552 30.070000021
0x44f9c95be1a7f3712aebd523a9cbfd84362bac2dd4dee9c5973aaa5dad84e03fClaim And Lock284673662022-05-18 11:51:4513 hrs 40 mins ago0xbeb820110b525894d3e269014939f74d84d6ae48 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.005381043983 31.782949116
0x7b09b250bbe3e739f99c9188f291e0c7c4925ea1992c39a6b6b7a4d7d1f905baClaim Reward284673622022-05-18 11:51:3713 hrs 40 mins ago0xbeb820110b525894d3e269014939f74d84d6ae48 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.003163700896 30.492620904
0x317b38746764237f221a6f0a514925eb2bf7ee98c8c7333946321589647b00e9Claim And Lock284673522022-05-18 11:51:1713 hrs 40 mins ago0xbeb820110b525894d3e269014939f74d84d6ae48 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.006182646091 31.435691655
0x83fd0d2a9e6e994383ddacfdad11a81985d6ea97cbb479119a6b8d1a8d7fa68cClaim Reward284662582022-05-18 11:11:3814 hrs 20 mins ago0x32505246cfbd4fbec3e829fb42d01ad347e6cca0 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.003113800542 30.01166754
0xa0ae5549ca79d09314ca5e464a6a97363646444342c0476b465da402965228b0Claim Reward284615602022-05-18 8:23:2517 hrs 8 mins ago0xc1a97d1544dd35fb04523c02a4d0a9ae1e5ef296 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.00264782434 30.263616567
0x9d5dfc0deb405c466584e5e9177aa4aff39733f666a90841a4ee94811a6cea60Claim Reward284615582022-05-18 8:23:1717 hrs 8 mins ago0xc1a97d1544dd35fb04523c02a4d0a9ae1e5ef296 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.00338790897 32.653600097
0x9d1c874f30c33bc79f9a2d5b2c56fb1913e2004813ea1bcdd76b6ec138378e47Claim Reward284613092022-05-18 8:12:5317 hrs 19 mins ago0x515ba04d46cc1de60bd98aac9f04f2e6e923a674 IN  0xc67abda25d0421fe9dc1afd64183b179a426a2560 MATIC0.002880936576 32.928
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

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)

File 1 of 15 : OtterLake.sol
// 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);
}

File 2 of 15 : IERC20.sol
// 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;
}

File 3 of 15 : IPearlNote.sol
// 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);
}

File 4 of 15 : IStakingDistributor.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity 0.7.5;

interface IStakingDistributor {
    function distribute() external returns (bool);
}

File 5 of 15 : IOtterLake.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.7.5;

interface IOtterLake {
    function epoch() external view returns (uint256);
}

File 6 of 15 : SafeMath.sol
// 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;
        }
    }
}

File 7 of 15 : SafeERC20.sol
// 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'
            );
        }
    }
}

File 8 of 15 : Pausable.sol
// 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");
        _;
    }
}

File 9 of 15 : ReentrancyGuard.sol
// 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;
    }
}

File 10 of 15 : IERC721Enumerable.sol
// 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);
}

File 11 of 15 : IERC721.sol
// 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;
}

File 12 of 15 : IERC165.sol
// 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);
}

File 13 of 15 : Counters.sol
// 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);
    }
}

File 14 of 15 : Address.sol
// 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);
    }
}

File 15 of 15 : Ownable.sol
// 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;
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"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"}]

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


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.