ETH Price: $3,355.92 (-1.76%)
Gas: 8 Gwei

Contract

0x3399eff96D4b6Bae8a56F4852EB55736c9C2b041
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Withdraw And Cla...201554872024-06-23 16:08:593 days ago1719158939IN
0x3399eff9...6c9C2b041
0 ETH0.000634295.26785477
Withdraw And Cla...201319252024-06-20 9:04:116 days ago1718874251IN
0x3399eff9...6c9C2b041
0 ETH0.001083679
Withdraw And Cla...201260672024-06-19 13:24:477 days ago1718803487IN
0x3399eff9...6c9C2b041
0 ETH0.000888127.37595232
Withdraw And Cla...200740632024-06-12 6:49:5914 days ago1718174999IN
0x3399eff9...6c9C2b041
0 ETH0.000715035.93843221
Withdraw And Cla...200316082024-06-06 8:31:1120 days ago1717662671IN
0x3399eff9...6c9C2b041
0 ETH0.0016928914.05965448
Withdraw And Cla...200303922024-06-06 4:26:2320 days ago1717647983IN
0x3399eff9...6c9C2b041
0 ETH0.001154539.58851081
Withdraw200298212024-06-06 2:31:1120 days ago1717641071IN
0x3399eff9...6c9C2b041
0 ETH0.001005910.46572247
Withdraw And Cla...200291392024-06-06 0:13:5920 days ago1717632839IN
0x3399eff9...6c9C2b041
0 ETH0.0028375923.5665274
Withdraw And Cla...200289392024-06-05 23:33:5920 days ago1717630439IN
0x3399eff9...6c9C2b041
0 ETH0.0027880523.15504278
Withdraw200194122024-06-04 15:40:2322 days ago1717515623IN
0x3399eff9...6c9C2b041
0 ETH0.0018260317.27331684
Withdraw199352562024-05-23 21:26:3533 days ago1716499595IN
0x3399eff9...6c9C2b041
0 ETH0.0033149434.48974672
Withdraw199012332024-05-19 3:14:2338 days ago1716088463IN
0x3399eff9...6c9C2b041
0 ETH0.000304223.16527214
Withdraw198842122024-05-16 18:05:3541 days ago1715882735IN
0x3399eff9...6c9C2b041
0 ETH0.000496985.17080346
Withdraw198104422024-05-06 10:27:2351 days ago1714991243IN
0x3399eff9...6c9C2b041
0 ETH0.000626596.51929964
Withdraw198054872024-05-05 17:49:4752 days ago1714931387IN
0x3399eff9...6c9C2b041
0 ETH0.000822068.55298882
Withdraw197995992024-05-04 22:03:2352 days ago1714860203IN
0x3399eff9...6c9C2b041
0 ETH0.000438174.55890947
Withdraw And Cla...197364162024-04-26 1:59:4761 days ago1714096787IN
0x3399eff9...6c9C2b041
0 ETH0.000660855.48844571
Withdraw197314152024-04-25 9:14:1162 days ago1714036451IN
0x3399eff9...6c9C2b041
0 ETH0.0011687512.16007409
Withdraw197086802024-04-22 4:53:4765 days ago1713761627IN
0x3399eff9...6c9C2b041
0 ETH0.000559725.82351179
Withdraw196619942024-04-15 16:06:3572 days ago1713197195IN
0x3399eff9...6c9C2b041
0 ETH0.0016783717.46237871
Withdraw And Cla...196557632024-04-14 19:09:1172 days ago1713121751IN
0x3399eff9...6c9C2b041
0 ETH0.0013118710.89525135
Withdraw And Cla...196406492024-04-12 16:14:1175 days ago1712938451IN
0x3399eff9...6c9C2b041
0 ETH0.0034730528.84402664
Withdraw And Cla...196258022024-04-10 14:23:5977 days ago1712759039IN
0x3399eff9...6c9C2b041
0 ETH0.0039290832.6314423
Withdraw And Cla...196219592024-04-10 1:29:3577 days ago1712712575IN
0x3399eff9...6c9C2b041
0 ETH0.001601113.29731034
Withdraw And Cla...195628192024-04-01 18:39:4786 days ago1711996787IN
0x3399eff9...6c9C2b041
0 ETH0.0029130224.19293738
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PrimeRewards

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 14 : PrimeRewards.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.7;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeCast.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";

/// @title The PrimeRewards caching contract
/// @notice Caching for PrimeKey, PrimeSets, CatalystDrive. It allows for a fixed PRIME token
/// rewards distributed evenly across all cached tokens per second.
contract PrimeRewards is Ownable, ERC1155Holder {
    using SafeERC20 for IERC20;
    using SafeCast for uint256;
    using SafeCast for int256;

    /// @notice Info of each Cache.
    /// `amount` Number of NFT sets the user has provided.
    /// `rewardDebt` The amount of PRIME the user is not eligible for either from
    ///  having already harvesting or from not caching in the past.
    struct CacheInfo {
        uint256 amount;
        int256 rewardDebt;
    }

    /// @notice Info of each pool.
    /// Contains the weighted allocation of the reward pool
    /// as well as the ParallelAlpha tokenIds required to cache in the pool
    struct PoolInfo {
        uint256 accPrimePerShare; // The amount of accumulated PRIME per share
        uint256 allocPoint; // share of the contract's per second rewards to that pool
        uint256 lastRewardTimestamp; // last time stamp at which rewards were assigned  
        uint256[] tokenIds; // ParallelAlpha tokenIds required to cache in the pool
        uint256 totalSupply; // Total number of cached sets in pool
    }

    /// @notice Address of PRIME contract.
    IERC20 public PRIME;

    /// @notice Address of Parallel Alpha erc1155
    IERC1155 public immutable parallelAlpha;

    /// @notice Info of each pool.
    PoolInfo[] public poolInfo;

    /// @notice Cache info of each user that caches NFT sets.
    // poolID(per set) => user address => cache info
    mapping(uint256 => mapping(address => CacheInfo)) public cacheInfo;

    /// @notice Prime amount distributed for given period. primeAmountPerSecond = primeAmount / (endTimestamp - startTimestamp)
    uint256 public startTimestamp; // caching start timestamp.
    uint256 public endTimestamp; // caching end timestamp.
    uint256 public primeAmount; // the amount of PRIME to give out as rewards.
    uint256 public primeAmountPerSecond; // the amount of PRIME to give out as rewards per second.
    uint256 public constant primeAmountPerSecondPrecision = 1e18; // primeAmountPerSecond is carried around with extra precision to reduce rounding errors

    /// @dev PRIME token will be minted after this contract is deployed, but should not be changeable forever
    uint256 public primeUpdateCutoff = 1667304000;

    /// @dev Limit number of pools that can be added
    uint256 public maxNumPools = 500;

    /// @dev Total allocation points. Must be the sum of all allocation points (i.e. multipliers) in all pools.
    uint256 public totalAllocPoint;

    /// @dev Caching functionality flag
    bool public cachingPaused;

    /// @dev Constants passed into event data
    uint256 public constant ID_PRIME = 0;
    uint256 public constant ID_ETH = 1;

    /// @dev internal lock for receiving ERC1155 tokens. Only allow during cache calls
    bool public onReceiveLocked = true;

     // @dev Fire when user has cached an asset (or set of assets) to the contract
    // @param user Address that has cached an asset
    // @param pid Pool ID that the user has caches assets to
    // @param amount Number of assets cached
    event Cache(address indexed user, uint256 indexed pid, uint256 amount);

    // @dev Fire when user withdraws asset (or set of assets) from contract
    // @param user Address that has withdrawn an asset
    // @param pid Pool ID of the withdrawn assets
    // @param amount Number of assets withdrawn
    event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);

    // @dev Fire if an emergency withdrawal of assets occurs
    // @param user Address that has withdrawn an asset
    // @param pid Pool ID of the withdrawn assets
    // @param amount Number of assets withdrawn
    event EmergencyWithdraw(
        address indexed user,
        uint256 indexed pid,
        uint256 amount
    );

    // @dev Fire when user claims their rewards from the contract 
    // @param user Address claiming rewards
    // @param pid Pool ID from which the user has claimed rewards
    // @param amount Amount of rewards claimed
    // @param currencyId Reward currency - 1 = ETH, 2 = PRIME
    event Claim(
        address indexed user,
        uint256 indexed pid,
        uint256 amount,
        uint256 indexed currencyId
    );

    // @dev Fire when a new pool is added to the contract 
    // @param pid Pool ID of the new pool
    // @param tokenIds ERC1155 token ids of pool assets
    event LogPoolAddition(uint256 indexed pid, uint256[] tokenIds);

    // @dev Fire when the end of a rewards regime has been updated 
    // @param endTimestamp New end time for a pool rewards
    // @param currencyId Reward currency - 1 = ETH, 2 = PRIME
    event EndTimestampUpdated(uint256 endTimestamp, uint256 indexed currencyID);

    // @dev Fire when additional rewards are added to a pool's rewards regime 
    // @param amount Amount of new rewards added
    // @param currencyID Reward currency - 1 = ETH, 2 = PRIME
    event RewardIncrease(uint256 amount, uint256 indexed currencyID);

    // @dev Fire when rewards are removed from a pool's rewards regime 
    // @param amount Amount of new rewards added
    // @param currencyID Reward currency - 1 = ETH, 2 = PRIME
    event RewardDecrease(uint256 amount, uint256 indexed currencyID);

    // @dev Fire when caching is paused for the contract 
    // @param cachingPaused True if caching is paused
    event CachingPaused(bool cachingPaused);

    // @dev Fire when there has been a change to the allocation points of a pool
    // @param pid Pool ID for which the allocation points have changed
    // @param totalAllocPoint the new total allocation points of all pools
    // @param currencyID Reward currency - 1 = ETH, 2 = PRIME
    event LogPoolSetAllocPoint(
        uint256 indexed pid,
        uint256 allocPoint,
        uint256 totalAllocPoint,
        uint256 indexed currencyId
    );


    // @dev Fire when rewards are recalculated in the pool
    // @param pid Pool ID for which the update occurred
    // @param lastRewardTimestamp The timestamp at which rewards have been recalculated for
    // @param supply The amount of assets staked to that pool
    // @param currencyID Reward currency - 1 = ETH, 2 = PRIME
    event LogUpdatePool(
        uint256 indexed pid,
        uint256 lastRewardTimestamp,
        uint256 supply,
        uint256 accPerShare,
        uint256 indexed currencyId
    );

    // @dev Fire when the rewards rate has been changed
    // @param amount Amount of rewards
    // @param startTimestamp Begin time of the reward period
    // @param startTimestamp End time of the reward period
    // @param currencyID Reward currency - 1 = ETH, 2 = PRIME
    event LogSetPerSecond(
        uint256 amount,
        uint256 startTimestamp,
        uint256 endTimestamp,
        uint256 indexed currencyId
    );

    /// @param _prime The PRIME token contract address.
    /// @param _parallelAlpha The Parallel Alpha contract address.
    constructor(IERC20 _prime, IERC1155 _parallelAlpha) {
        parallelAlpha = _parallelAlpha;
        PRIME = _prime;
    }

    /// @notice Sets new prime token address
    /// @param _prime The PRIME token contract address.
    function setPrimeTokenAddress(IERC20 _prime) external onlyOwner {
        require(
            block.timestamp < primeUpdateCutoff,
            "PRIME address update window has has passed"
        );
        PRIME = _prime;
    }

    /// @notice Sets new max number of pools. New max cannot be less than
    /// current number of pools.
    /// @param _maxNumPools The new max number of pools.
    function setMaxNumPools(uint256 _maxNumPools) external onlyOwner {
        require(
            _maxNumPools >= poolLength(),
            "Can't set maxNumPools less than poolLength"
        );
        maxNumPools = _maxNumPools;
    }

    /// @notice Returns the number of pools.
    function poolLength() public view returns (uint256 pools) {
        pools = poolInfo.length;
    }

    /// @param _pid Pool to get IDs for
    function getPoolTokenIds(uint256 _pid)
        external
        view
        returns (uint256[] memory)
    {
        return poolInfo[_pid].tokenIds;
    }

    function updateAllPools() internal {
        uint256 len = poolLength();
        for (uint256 i = 0; i < len; ++i) {
            updatePool(i);
        }
    }

    /// @notice Add a new set of tokenIds as a new pool. Can only be called by the owner.
    /// DO NOT add the same token id more than once or rewards will be inaccurate.
    /// @param _allocPoint Allocation Point (i.e. multiplier) of the new pool.
    /// @param _tokenIds TokenIds for ParallelAlpha ERC1155, set of tokenIds for pool.
    function addPool(uint256 _allocPoint, uint256[] memory _tokenIds)
        public
        virtual
        onlyOwner
    {
        require(poolInfo.length < maxNumPools, "Max num pools reached");
        require(_tokenIds.length > 0, "TokenIds cannot be empty");
        require(_allocPoint > 0, "Allocation point cannot be 0 or negative");
        // Update all pool information before adding the AllocPoint for new pool
        for (uint256 i = 0; i < poolInfo.length; ++i) {
            updatePool(i);
            require(
                keccak256(abi.encodePacked(poolInfo[i].tokenIds)) !=
                    keccak256(abi.encodePacked(_tokenIds)),
                "Pool with same tokenIds exists"
            );
        }
        totalAllocPoint += _allocPoint;
        poolInfo.push(
            PoolInfo({
                accPrimePerShare: 0,
                allocPoint: _allocPoint,
                lastRewardTimestamp: Math.max(block.timestamp, startTimestamp),
                tokenIds: _tokenIds,
                totalSupply: 0
            })
        );
        emit LogPoolAddition(poolInfo.length - 1, _tokenIds);
        emit LogPoolSetAllocPoint(
            poolInfo.length - 1,
            _allocPoint,
            totalAllocPoint,
            ID_PRIME
        );
    }

    /// @notice Set new period to distribute rewards between endTimestamp-startTimestamp
    /// evenly per second. primeAmountPerSecond = _primeAmount / (_endTimestamp - _startTimestamp)
    /// Can only be set once any existing setPrimePerSecond regime has concluded (ethEndTimestamp < block.timestamp)
    /// @param _startTimestamp Timestamp for caching period to start at
    /// @param _endTimestamp Timestamp for caching period to end at
    /// @param _primeAmount Amount of Prime to distribute evenly across whole period
    function setPrimePerSecond(
        uint256 _startTimestamp,
        uint256 _endTimestamp,
        uint256 _primeAmount
    ) external onlyOwner {
        require(
            _startTimestamp < _endTimestamp,
            "endTimestamp cant be less than startTimestamp"
        );
        require(
            block.timestamp < startTimestamp || endTimestamp < block.timestamp,
            "Only updates after endTimestamp or before startTimestamp"
        );

        // Update all pools, ensure rewards are calculated up to this timestamp
        for (uint256 i = 0; i < poolInfo.length; ++i) {
            updatePool(i);
            poolInfo[i].lastRewardTimestamp = _startTimestamp;
        }
        primeAmount = _primeAmount;
        startTimestamp = _startTimestamp;
        endTimestamp = _endTimestamp;
        primeAmountPerSecond =
            (_primeAmount * primeAmountPerSecondPrecision) /
            (_endTimestamp - _startTimestamp);
        emit LogSetPerSecond(
            _primeAmount,
            _startTimestamp,
            _endTimestamp,
            ID_PRIME
        );
    }

    /// @notice Update endTimestamp, only possible to call this when caching for
    /// a period has already begun. New endTimestamp must be in the future
    /// @param _endTimestamp New timestamp for caching period to end at
    function setEndTimestamp(uint256 _endTimestamp) external onlyOwner {
        require(
            startTimestamp < block.timestamp,
            "caching period has not started yet"
        );
        require(block.timestamp < _endTimestamp, "invalid end timestamp");
        updateAllPools();

        // Update primeAmountPerSecond based on the new endTimestamp
        startTimestamp = block.timestamp;
        endTimestamp = _endTimestamp;
        primeAmountPerSecond =
            (primeAmount * primeAmountPerSecondPrecision) /
            (endTimestamp - startTimestamp);
        emit EndTimestampUpdated(_endTimestamp, ID_PRIME);
    }

    /// @notice Function for 'Top Ups', adds additional prime to distribute for remaining time
    /// in the period.
    /// @param _addPrimeAmount Amount of Prime to add to the reward pool
    function addPrimeAmount(uint256 _addPrimeAmount) external onlyOwner {
        require(
            startTimestamp < block.timestamp && block.timestamp < endTimestamp,
            "Can only addPrimeAmount during period"
        );
        // Update all pools
        updateAllPools();
        // Top up current period's PRIME
        primeAmount += _addPrimeAmount;
        primeAmountPerSecond =
            (primeAmount * primeAmountPerSecondPrecision) /
            (endTimestamp - block.timestamp);
        emit RewardIncrease(_addPrimeAmount, ID_PRIME);
    }

    /// @notice Function for 'Top Downs', removes prime distributed for remaining time
    /// in the period.
    /// @param _removePrimeAmount Amount of Prime to remove from the remaining reward pool
    function removePrimeAmount(uint256 _removePrimeAmount) external onlyOwner {
        require(
            startTimestamp < block.timestamp && block.timestamp < endTimestamp,
            "Can only removePrimeAmount during a period"
        );

        // Update all pools
        updateAllPools();

        // Adjust current period's PRIME
        // Using min to make sure primeAmount can only be reduced to zero
        _removePrimeAmount = Math.min(_removePrimeAmount, primeAmount);
        primeAmount -= _removePrimeAmount;
        primeAmountPerSecond =
            (primeAmount * primeAmountPerSecondPrecision) /
            (endTimestamp - block.timestamp);
        emit RewardDecrease(_removePrimeAmount, ID_PRIME);
    }

    /// @notice Update the given pool's PRIME allocation point (i.e. multiplier). Only owner.
    /// @param _pid The index of the pool. See `poolInfo`.
    /// @param _allocPoint New allocation point (i.e. multiplier) of the pool.
    function setPoolAllocPoint(uint256 _pid, uint256 _allocPoint)
        external
        onlyOwner
    {
        // Update all pools
        updateAllPools();
        totalAllocPoint =
            totalAllocPoint -
            poolInfo[_pid].allocPoint +
            _allocPoint;
        poolInfo[_pid].allocPoint = _allocPoint;
        emit LogPoolSetAllocPoint(_pid, _allocPoint, totalAllocPoint, ID_PRIME);
    }

    /// @notice Enable/disable caching for pools. Only owner.
    /// @param _cachingPaused boolean value to set
    function setCachingPaused(bool _cachingPaused) external onlyOwner {
        cachingPaused = _cachingPaused;
        emit CachingPaused(cachingPaused);
    }

    /// @notice View function to see cache amounts for pools.
    /// @param _pids List of pool index ids. See `poolInfo`.
    /// @param _addresses List of user addresses.
    /// @return amounts List of cache amounts.
    function getPoolCacheAmounts(
        uint256[] calldata _pids,
        address[] calldata _addresses
    ) external view returns (uint256[] memory) {
        require(
            _pids.length == _addresses.length,
            "pids and addresses length mismatch"
        );

        uint256[] memory amounts = new uint256[](_pids.length);
        for (uint256 i = 0; i < _pids.length; ++i) {
            amounts[i] = cacheInfo[_pids[i]][_addresses[i]].amount;
        }

        return amounts;
    }

    /// @notice View function to see pending PRIME on frontend.
    /// @param _pid The index of the pool. See `poolInfo`.
    /// @param _user Address of user.
    /// @return pending PRIME reward for a given user.
    function pendingPrime(uint256 _pid, address _user)
        external
        view
        returns (uint256 pending)
    {
        PoolInfo memory pool = poolInfo[_pid];
        CacheInfo storage _cache = cacheInfo[_pid][_user];
        uint256 accPrimePerShare = pool.accPrimePerShare;
        uint256 totalSupply = pool.totalSupply;

        if (
            startTimestamp <= block.timestamp &&
            pool.lastRewardTimestamp < block.timestamp &&
            totalSupply > 0
        ) {
            uint256 updateToTimestamp = Math.min(block.timestamp, endTimestamp);
            uint256 seconds_ = updateToTimestamp - pool.lastRewardTimestamp;
            uint256 primeReward = (seconds_ *
                primeAmountPerSecond *
                pool.allocPoint) / totalAllocPoint;
            accPrimePerShare += primeReward / totalSupply;
        }
        pending =
            ((_cache.amount * accPrimePerShare).toInt256() - _cache.rewardDebt)
                .toUint256() /
            primeAmountPerSecondPrecision;
    }

    /// @notice Update reward variables for all pools. Be careful of gas required.
    /// @param _pids Pool IDs of all to be updated. Make sure to update all active pools.
    function massUpdatePools(uint256[] calldata _pids) external {
        uint256 len = _pids.length;
        for (uint256 i = 0; i < len; ++i) {
            updatePool(_pids[i]);
        }
    }

    /// @notice Update reward variables for the given pool.
    /// @param _pid The index of the pool. See `poolInfo`.
    function updatePool(uint256 _pid) public {
        PoolInfo storage pool = poolInfo[_pid];
        if (
            startTimestamp > block.timestamp ||
            pool.lastRewardTimestamp >= block.timestamp ||
            (startTimestamp == 0 && endTimestamp == 0)
        ) {
            return;
        }

        uint256 updateToTimestamp = Math.min(block.timestamp, endTimestamp);
        uint256 totalSupply = pool.totalSupply;
        uint256 seconds_ = updateToTimestamp - pool.lastRewardTimestamp;
        uint256 primeReward = (seconds_ *
            primeAmountPerSecond *
            pool.allocPoint) / totalAllocPoint;
        primeAmount -= primeReward / primeAmountPerSecondPrecision;
        if (totalSupply > 0) {
            pool.accPrimePerShare += primeReward / totalSupply;
        }
        pool.lastRewardTimestamp = updateToTimestamp;
        emit LogUpdatePool(
            _pid,
            pool.lastRewardTimestamp,
            totalSupply,
            pool.accPrimePerShare,
            ID_PRIME
        );
    }

    /// @notice Cache NFTs for PRIME rewards.
    /// @param _pid The index of the pool. See `poolInfo`.
    /// @param _amount Amount of 'tokenIds sets' to cache for _pid.
    function cache(uint256 _pid, uint256 _amount) public virtual {
        require(!cachingPaused, "Caching is paused");
        require(_amount > 0, "Specify valid amount to cache");
        updatePool(_pid);
        CacheInfo storage _cache = cacheInfo[_pid][msg.sender];

        // Create amounts array for tokenIds BatchTransfer
        uint256[] memory amounts = new uint256[](
            poolInfo[_pid].tokenIds.length
        );
        for (uint256 i = 0; i < amounts.length; i++) {
            amounts[i] = _amount;
        }

        // Effects
        poolInfo[_pid].totalSupply += _amount;
        _cache.amount += _amount;
        _cache.rewardDebt += (_amount * poolInfo[_pid].accPrimePerShare)
            .toInt256();

        onReceiveLocked = false;
        parallelAlpha.safeBatchTransferFrom(
            msg.sender,
            address(this),
            poolInfo[_pid].tokenIds,
            amounts,
            bytes("")
        );
        onReceiveLocked = true;

        emit Cache(msg.sender, _pid, _amount);
    }

    /// @notice Withdraw from pool
    /// @param _pid The index of the pool. See `poolInfo`.
    /// @param _amount Amount of tokenId sets to withdraw from the pool
    function withdraw(uint256 _pid, uint256 _amount) public virtual {
        updatePool(_pid);
        CacheInfo storage _cache = cacheInfo[_pid][msg.sender];

        // Create amounts array for tokenIds BatchTransfer
        uint256[] memory amounts = new uint256[](
            poolInfo[_pid].tokenIds.length
        );
        for (uint256 i = 0; i < amounts.length; i++) {
            amounts[i] = _amount;
        }

        // Effects
        poolInfo[_pid].totalSupply -= _amount;
        _cache.rewardDebt -= (_amount * poolInfo[_pid].accPrimePerShare)
            .toInt256();
        _cache.amount -= _amount;

        parallelAlpha.safeBatchTransferFrom(
            address(this),
            msg.sender,
            poolInfo[_pid].tokenIds,
            amounts,
            bytes("")
        );

        emit Withdraw(msg.sender, _pid, _amount);
    }

    /// @notice Claim accumulated PRIME rewards.
    /// @param _pid The index of the pool. See `poolInfo`.
    function claimPrime(uint256 _pid) public {
        updatePool(_pid);
        CacheInfo storage _cache = cacheInfo[_pid][msg.sender];
        int256 accumulatedPrime = (_cache.amount *
            poolInfo[_pid].accPrimePerShare).toInt256();
        uint256 _pendingPrime = (accumulatedPrime - _cache.rewardDebt)
            .toUint256() / primeAmountPerSecondPrecision;

        // Effects
        _cache.rewardDebt = accumulatedPrime;

        // Interactions
        if (_pendingPrime != 0) {
            PRIME.safeTransfer(msg.sender, _pendingPrime);
        }

        emit Claim(msg.sender, _pid, _pendingPrime, ID_PRIME);
    }

    /// @notice claimPrime multiple pools
    /// @param _pids Pool IDs of all to be claimed
    function claimPrimePools(uint256[] calldata _pids) external virtual {
        for (uint256 i = 0; i < _pids.length; ++i) {
            claimPrime(_pids[i]);
        }
    }

    /// @notice Withdraw and claim PRIME rewards.
    /// @param _pid The index of the pool. See `poolInfo`.
    /// @param _amount Amount of tokenId sets to withdraw.
    function withdrawAndClaimPrime(uint256 _pid, uint256 _amount)
        public
        virtual
    {
        updatePool(_pid);
        CacheInfo storage _cache = cacheInfo[_pid][msg.sender];
        int256 accumulatedPrime = (_cache.amount *
            poolInfo[_pid].accPrimePerShare).toInt256();
        uint256 _pendingPrime = (accumulatedPrime - _cache.rewardDebt)
            .toUint256() / primeAmountPerSecondPrecision;

        // Create amounts array for tokenIds BatchTransfer
        uint256[] memory amounts = new uint256[](
            poolInfo[_pid].tokenIds.length
        );
        for (uint256 i = 0; i < amounts.length; i++) {
            amounts[i] = _amount;
        }

        // Effects
        poolInfo[_pid].totalSupply -= _amount;
        _cache.rewardDebt =
            accumulatedPrime -
            (_amount * poolInfo[_pid].accPrimePerShare).toInt256();
        _cache.amount -= _amount;

        if (_pendingPrime != 0) {
            PRIME.safeTransfer(msg.sender, _pendingPrime);
        }

        parallelAlpha.safeBatchTransferFrom(
            address(this),
            msg.sender,
            poolInfo[_pid].tokenIds,
            amounts,
            bytes("")
        );

        emit Withdraw(msg.sender, _pid, _amount);
        emit Claim(msg.sender, _pid, _pendingPrime, ID_PRIME);
    }

    /// @notice Withdraw and forgo rewards. EMERGENCY ONLY.
    /// @param _pid The index of the pool. See `poolInfo`.
    function emergencyWithdraw(uint256 _pid) public virtual {
        CacheInfo storage _cache = cacheInfo[_pid][msg.sender];

        uint256 amount = _cache.amount;
        // Create amounts array for tokenIds BatchTransfer
        uint256[] memory amounts = new uint256[](
            poolInfo[_pid].tokenIds.length
        );
        for (uint256 i = 0; i < amounts.length; i++) {
            amounts[i] = amount;
        }

        // Effects
        poolInfo[_pid].totalSupply -= amount;
        _cache.rewardDebt = 0;
        _cache.amount = 0;

        parallelAlpha.safeBatchTransferFrom(
            address(this),
            msg.sender,
            poolInfo[_pid].tokenIds,
            amounts,
            bytes("")
        );

        emit EmergencyWithdraw(msg.sender, _pid, amount);
    }

    /// @notice Sweep function to transfer erc20 tokens out of contract. Only owner.
    /// @param erc20 Token to transfer out
    /// @param to address to sweep to
    /// @param amount Amount to withdraw
    function sweepERC20(
        IERC20 erc20,
        address to,
        uint256 amount
    ) external onlyOwner {
        erc20.transfer(to, amount);
    }

    /// @notice Disable renounceOwnership. Only callable by owner.
    function renounceOwnership() public virtual override onlyOwner {
        revert("Ownership cannot be renounced");
    }

    /// @notice Revert for calls outside of cache method
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        require(onReceiveLocked == false, "onReceive is locked");
        return this.onERC1155Received.selector;
    }

    /// @notice Revert for calls outside of cache method
    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) public virtual override returns (bytes4) {
        require(onReceiveLocked == false, "onReceive is locked");
        return this.onERC1155BatchReceived.selector;
    }
}

File 2 of 14 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 3 of 14 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    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));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        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) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 4 of 14 : ERC1155Holder.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol)

pragma solidity ^0.8.0;

import "./ERC1155Receiver.sol";

/**
 * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens.
 *
 * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be
 * stuck.
 *
 * @dev _Available since v3.1._
 */
contract ERC1155Holder is ERC1155Receiver {
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155BatchReceived.selector;
    }
}

File 5 of 14 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 6 of 14 : SafeCast.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128) {
        require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
        return int128(value);
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64) {
        require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
        return int64(value);
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32) {
        require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
        return int32(value);
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16) {
        require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
        return int16(value);
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8) {
        require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
        return int8(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

File 7 of 14 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a / b + (a % b == 0 ? 0 : 1);
    }
}

File 8 of 14 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^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 9 of 14 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 10 of 14 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    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");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    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");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 11 of 14 : ERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)

pragma solidity ^0.8.0;

import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";

/**
 * @dev _Available since v3.1._
 */
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
    }
}

File 12 of 14 : IERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

File 13 of 14 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 14 of 14 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IERC20","name":"_prime","type":"address"},{"internalType":"contract IERC1155","name":"_parallelAlpha","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Cache","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"cachingPaused","type":"bool"}],"name":"CachingPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyId","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"endTimestamp","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyID","type":"uint256"}],"name":"EndTimestampUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"LogPoolAddition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalAllocPoint","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyId","type":"uint256"}],"name":"LogPoolSetAllocPoint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTimestamp","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyId","type":"uint256"}],"name":"LogSetPerSecond","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accPerShare","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyId","type":"uint256"}],"name":"LogUpdatePool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyID","type":"uint256"}],"name":"RewardDecrease","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyID","type":"uint256"}],"name":"RewardIncrease","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"ID_ETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ID_PRIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRIME","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"addPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_addPrimeAmount","type":"uint256"}],"name":"addPrimeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"cache","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"cacheInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"int256","name":"rewardDebt","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cachingPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"claimPrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"}],"name":"claimPrimePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"},{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"getPoolCacheAmounts","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getPoolTokenIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"}],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxNumPools","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"onReceiveLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"parallelAlpha","outputs":[{"internalType":"contract IERC1155","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingPrime","outputs":[{"internalType":"uint256","name":"pending","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"uint256","name":"accPrimePerShare","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"pools","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"primeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"primeAmountPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"primeAmountPerSecondPrecision","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"primeUpdateCutoff","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_removePrimeAmount","type":"uint256"}],"name":"removePrimeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_cachingPaused","type":"bool"}],"name":"setCachingPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_endTimestamp","type":"uint256"}],"name":"setEndTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxNumPools","type":"uint256"}],"name":"setMaxNumPools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"}],"name":"setPoolAllocPoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startTimestamp","type":"uint256"},{"internalType":"uint256","name":"_endTimestamp","type":"uint256"},{"internalType":"uint256","name":"_primeAmount","type":"uint256"}],"name":"setPrimePerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_prime","type":"address"}],"name":"setPrimeTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"erc20","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sweepERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawAndClaimPrime","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040526363610a406008556101f4600955600b805461ff0019166101001790553480156200002e57600080fd5b5060405162003357380380620033578339810160408190526200005191620000e2565b6200005c3362000092565b60601b6001600160601b031916608052600180546001600160a01b0319166001600160a01b03929092169190911790556200013a565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060408385031215620000f657600080fd5b8251620001038162000121565b6020840151909250620001168162000121565b809150509250929050565b6001600160a01b03811681146200013757600080fd5b50565b60805160601c6131e26200017560003960008181610506015281816107eb01528181610c7b015281816110e301526120a001526131e26000f3fe608060405234801561001057600080fd5b50600436106102735760003560e01c80638da5cb5b11610151578063cdeccabf116100c3578063e6fd48bc11610087578063e6fd48bc1461059c578063e7bcdafd146105a5578063f15d6f9d146105b8578063f23a6e61146105cb578063f2fde38b146105de578063f928603e146105f157600080fd5b8063cdeccabf1461053b578063dc628aa41461055b578063ddcb4b681461056e578063e1df480f14610581578063e4f3ae431461059457600080fd5b8063bc197c8111610115578063bc197c81146104a6578063bec4d454146104d2578063bee20885146104db578063c9af39e2146104ee578063ca7238f214610501578063cc8ba1881461052857600080fd5b80638da5cb5b1461045f578063a339bb4614610470578063a85adeab14610482578063ae1f071d1461048b578063b588d1c91461049357600080fd5b80634f94a8cd116101ea5780635c5709ca116101ae5780635c5709ca146103ce5780636af84fc014610415578063715018a61461042857806371993130146104305780637df6a6c814610439578063811822e61461044c57600080fd5b80634f94a8cd1461036f578063503690d11461038257806351eb05a6146103955780635312ea8e146103a857806357a5b58c146103bb57600080fd5b806317caf6f11161023c57806317caf6f1146103195780631cb819ad146103225780632fee4c871461032f5780633f3a1f5014610338578063441a3e7014610347578063446a3c1f1461035c57600080fd5b806217cd8b1461027857806301ffc9a7146102a8578063081e3eda146102cb57806312446f49146102dd5780631526fe27146102e6575b600080fd5b60015461028b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6102bb6102b6366004612cc4565b610604565b604051901515815260200161029f565b6002545b60405190815260200161029f565b6102cf60085481565b6102f96102f4366004612d2f565b61063b565b60408051948552602085019390935291830152606082015260800161029f565b6102cf600a5481565b600b546102bb9060ff1681565b6102cf60095481565b6102cf670de0b6b3a764000081565b61035a610355366004612dbe565b610675565b005b6102cf61036a366004612d48565b6108df565b61035a61037d366004612dbe565b610a95565b61035a610390366004612cee565b610db6565b61035a6103a3366004612d2f565b610e71565b61035a6103b6366004612d2f565b610fc9565b61035a6103c9366004612bde565b6111c6565b6104006103dc366004612d48565b60036020908152600092835260408084209091529082529020805460019091015482565b6040805192835260208301919091520161029f565b61035a610423366004612d2f565b611203565b61035a611323565b6102cf60075481565b61035a610447366004612d2f565b611395565b61035a61045a366004612d2f565b6114d5565b6000546001600160a01b031661028b565b600b546102bb90610100900460ff1681565b6102cf60055481565b6102cf600181565b61035a6104a1366004612aac565b611569565b6104b96104b4366004612ac9565b611619565b6040516001600160e01b0319909116815260200161029f565b6102cf60065481565b61035a6104e9366004612d78565b61167c565b61035a6104fc366004612bde565b6119cd565b61028b7f000000000000000000000000000000000000000000000000000000000000000081565b61035a610536366004612de0565b611a0e565b61054e610549366004612c1f565b611bf0565b60405161029f9190612f85565b61035a610569366004612dbe565b611d4c565b61035a61057c366004612c8a565b611e29565b61035a61058f366004612dbe565b611ea0565b6102cf600081565b6102cf60045481565b61035a6105b3366004612d2f565b612194565b61054e6105c6366004612d2f565b61226e565b6104b96105d9366004612b76565b6122ea565b61035a6105ec366004612aac565b61234d565b61035a6105ff366004612d2f565b6123e8565b60006001600160e01b03198216630271189760e51b148061063557506301ffc9a760e01b6001600160e01b03198316145b92915050565b6002818154811061064b57600080fd5b60009182526020909120600590910201805460018201546002830154600490930154919350919084565b61067e82610e71565b6000828152600360209081526040808320338452909152812060028054919291859081106106ae576106ae61315d565b9060005260206000209060050201600301805490506001600160401b038111156106da576106da613173565b604051908082528060200260200182016040528015610703578160200160208202803683370190505b50905060005b815181101561074257838282815181106107255761072561315d565b60209081029190910101528061073a8161312c565b915050610709565b5082600285815481106107575761075761315d565b9060005260206000209060050201600401600082825461077791906130e9565b925050819055506107b6600285815481106107945761079461315d565b906000526020600020906005020160000154846107b1919061308b565b612514565b8260010160008282546107c991906130aa565b90915550508154839083906000906107e29084906130e9565b925050819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632eb2c2d630336002888154811061082d5761082d61315d565b906000526020600020906005020160030185604051806020016040528060008152506040518663ffffffff1660e01b815260040161086f959493929190612ef6565b600060405180830381600087803b15801561088957600080fd5b505af115801561089d573d6000803e3d6000fd5b50506040518581528692503391507ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020015b60405180910390a350505050565b600080600284815481106108f5576108f561315d565b90600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820180548060200260200160405190810160405280929190818152602001828054801561097b57602002820191906000526020600020905b815481526020019060010190808311610967575b505050918352505060049182015460209182015260008781526003825260408082206001600160a01b038916835290925220825160808401519254939450909290919042108015906109d05750428460400151105b80156109dc5750600081115b15610a4d5760006109ef42600554612582565b90506000856040015182610a0391906130e9565b90506000600a54876020015160075484610a1d919061308b565b610a27919061308b565b610a319190613069565b9050610a3d8482613069565b610a479086613051565b94505050505b670de0b6b3a7640000610a808460010154610a718587600001546107b1919061308b565b610a7b91906130aa565b61259a565b610a8a9190613069565b979650505050505050565b610a9e82610e71565b6000828152600360209081526040808320338452909152812060028054919291610af0919086908110610ad357610ad361315d565b600091825260209091206005909102015483546107b1919061308b565b90506000670de0b6b3a7640000610b10846001015484610a7b91906130aa565b610b1a9190613069565b9050600060028681548110610b3157610b3161315d565b9060005260206000209060050201600301805490506001600160401b03811115610b5d57610b5d613173565b604051908082528060200260200182016040528015610b86578160200160208202803683370190505b50905060005b8151811015610bc55785828281518110610ba857610ba861315d565b602090810291909101015280610bbd8161312c565b915050610b8c565b508460028781548110610bda57610bda61315d565b90600052602060002090600502016004016000828254610bfa91906130e9565b92505081905550610c3460028781548110610c1757610c1761315d565b906000526020600020906005020160000154866107b1919061308b565b610c3e90846130aa565b6001850155835485908590600090610c579084906130e9565b90915550508115610c7957600154610c79906001600160a01b031633846125ec565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632eb2c2d6303360028a81548110610cbd57610cbd61315d565b906000526020600020906005020160030185604051806020016040528060008152506040518663ffffffff1660e01b8152600401610cff959493929190612ef6565b600060405180830381600087803b158015610d1957600080fd5b505af1158015610d2d573d6000803e3d6000fd5b50506040518781528892503391507ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a3600086336001600160a01b03167f45c072aa05b9853b5a993de7a28bc332ee01404a628cec1a23ce0f659f842ef185604051610da691815260200190565b60405180910390a4505050505050565b6000546001600160a01b03163314610de95760405162461bcd60e51b8152600401610de090612fab565b60405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0383811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b158015610e3357600080fd5b505af1158015610e47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6b9190612ca7565b50505050565b600060028281548110610e8657610e8661315d565b90600052602060002090600502019050426004541180610eaa575042816002015410155b80610ec05750600454158015610ec05750600554155b15610ec9575050565b6000610ed742600554612582565b6004830154600284015491925090600090610ef290846130e9565b90506000600a54856001015460075484610f0c919061308b565b610f16919061308b565b610f209190613069565b9050610f34670de0b6b3a764000082613069565b60066000828254610f4591906130e9565b90915550508215610f7357610f5a8382613069565b856000016000828254610f6d9190613051565b90915550505b6002850184905584546040805186815260208101869052808201929092525160009188917fc75b283f14d0a806c63b93a3659ed39c43a20bf0fff8030465e93d79e91ca40f9181900360600190a3505050505050565b600081815260036020908152604080832033845290915281208054600280549293919285908110610ffc57610ffc61315d565b9060005260206000209060050201600301805490506001600160401b0381111561102857611028613173565b604051908082528060200260200182016040528015611051578160200160208202803683370190505b50905060005b815181101561109057828282815181106110735761107361315d565b6020908102919091010152806110888161312c565b915050611057565b5081600285815481106110a5576110a561315d565b906000526020600020906005020160040160008282546110c591906130e9565b90915550506000600184018190558355600280546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691632eb2c2d691309133918990811061111e5761111e61315d565b906000526020600020906005020160030185604051806020016040528060008152506040518663ffffffff1660e01b8152600401611160959493929190612ef6565b600060405180830381600087803b15801561117a57600080fd5b505af115801561118e573d6000803e3d6000fd5b50506040518481528692503391507fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae0595906020016108d1565b8060005b81811015610e6b576111f38484838181106111e7576111e761315d565b90506020020135610e71565b6111fc8161312c565b90506111ca565b6000546001600160a01b0316331461122d5760405162461bcd60e51b8152600401610de090612fab565b4260045410801561123f575060055442105b6112995760405162461bcd60e51b815260206004820152602560248201527f43616e206f6e6c79206164645072696d65416d6f756e7420647572696e672070604482015264195c9a5bd960da1b6064820152608401610de0565b6112a161263e565b80600660008282546112b39190613051565b90915550506005546112c69042906130e9565b670de0b6b3a76400006006546112dc919061308b565b6112e69190613069565b6007556040518181526000907f4dffb45d6f962f8af66e8c830a9a6027cea8919fd29147db4be34dadb0fb5f1e906020015b60405180910390a250565b6000546001600160a01b0316331461134d5760405162461bcd60e51b8152600401610de090612fab565b60405162461bcd60e51b815260206004820152601d60248201527f4f776e6572736869702063616e6e6f742062652072656e6f756e6365640000006044820152606401610de0565b6000546001600160a01b031633146113bf5760405162461bcd60e51b8152600401610de090612fab565b426004541061141b5760405162461bcd60e51b815260206004820152602260248201527f63616368696e6720706572696f6420686173206e6f7420737461727465642079604482015261195d60f21b6064820152608401610de0565b8042106114625760405162461bcd60e51b81526020600482015260156024820152740696e76616c696420656e642074696d657374616d7605c1b6044820152606401610de0565b61146a61263e565b426004819055600582905561147f90826130e9565b670de0b6b3a7640000600654611495919061308b565b61149f9190613069565b6007556040518181526000907f7e9fbea655506e5a9e67dca69341fadbddee58b360cc1e2f888d0b5576febb8490602001611318565b6000546001600160a01b031633146114ff5760405162461bcd60e51b8152600401610de090612fab565b6002548110156115645760405162461bcd60e51b815260206004820152602a60248201527f43616e277420736574206d61784e756d506f6f6c73206c657373207468616e206044820152690e0deded898cadccee8d60b31b6064820152608401610de0565b600955565b6000546001600160a01b031633146115935760405162461bcd60e51b8152600401610de090612fab565b60085442106115f75760405162461bcd60e51b815260206004820152602a60248201527f5052494d452061646472657373207570646174652077696e646f7720686173206044820152691a185cc81c185cdcd95960b21b6064820152608401610de0565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600b54600090610100900460ff161561166a5760405162461bcd60e51b81526020600482015260136024820152721bdb949958d95a5d99481a5cc81b1bd8dad959606a1b6044820152606401610de0565b5063bc197c8160e01b95945050505050565b6000546001600160a01b031633146116a65760405162461bcd60e51b8152600401610de090612fab565b600954600254106116f15760405162461bcd60e51b815260206004820152601560248201527413585e081b9d5b481c1bdbdb1cc81c995858da1959605a1b6044820152606401610de0565b60008151116117425760405162461bcd60e51b815260206004820152601860248201527f546f6b656e4964732063616e6e6f7420626520656d70747900000000000000006044820152606401610de0565b600082116117a35760405162461bcd60e51b815260206004820152602860248201527f416c6c6f636174696f6e20706f696e742063616e6e6f742062652030206f72206044820152676e6567617469766560c01b6064820152608401610de0565b60005b600254811015611888576117b981610e71565b816040516020016117ca9190612e73565b60405160208183030381529060405280519060200120600282815481106117f3576117f361315d565b90600052602060002090600502016003016040516020016118149190612ea9565b6040516020818303038152906040528051906020012014156118785760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c20776974682073616d6520746f6b656e4964732065786973747300006044820152606401610de0565b6118818161312c565b90506117a6565b5081600a600082825461189b9190613051565b9250508190555060026040518060a00160405280600081526020018481526020016118c842600454612673565b81526020808201859052600060409283018190528454600181810187559582529082902084516005909202019081558382015194810194909455908201516002840155606082015180519293926119259260038501920190612916565b5060809190910151600490910155600254611942906001906130e9565b7f433d962a500f8c767748676218e15a2c52504785df1e3ea4a25d04926140609c826040516119719190612f85565b60405180910390a260025460009061198b906001906130e9565b600a546040805186815260208101929092527fc12a6201c487829aaa17c8698145154b8fb8c84945e43430f08a08b385ffa8e391015b60405180910390a35050565b60005b81811015611a09576119f98383838181106119ed576119ed61315d565b90506020020135612194565b611a028161312c565b90506119d0565b505050565b6000546001600160a01b03163314611a385760405162461bcd60e51b8152600401610de090612fab565b818310611a9d5760405162461bcd60e51b815260206004820152602d60248201527f656e6454696d657374616d702063616e74206265206c657373207468616e207360448201526c07461727454696d657374616d7609c1b6064820152608401610de0565b600454421080611aae575042600554105b611b205760405162461bcd60e51b815260206004820152603860248201527f4f6e6c79207570646174657320616674657220656e6454696d657374616d702060448201527f6f72206265666f726520737461727454696d657374616d7000000000000000006064820152608401610de0565b60005b600254811015611b6e57611b3681610e71565b8360028281548110611b4a57611b4a61315d565b6000918252602090912060026005909202010155611b678161312c565b9050611b23565b50600681905560048390556005829055611b8883836130e9565b611b9a670de0b6b3a76400008361308b565b611ba49190613069565b60075560408051828152602081018590529081018390526000907f72bb6e826d1a04bd8fa5fdde85546e3b9eb8e95d8500eec20f4c0124edcb422b9060600160405180910390a2505050565b6060838214611c4c5760405162461bcd60e51b815260206004820152602260248201527f7069647320616e6420616464726573736573206c656e677468206d69736d61746044820152610c6d60f31b6064820152608401610de0565b6000846001600160401b03811115611c6657611c66613173565b604051908082528060200260200182016040528015611c8f578160200160208202803683370190505b50905060005b85811015611d425760036000888884818110611cb357611cb361315d565b9050602002013581526020019081526020016000206000868684818110611cdc57611cdc61315d565b9050602002016020810190611cf19190612aac565b6001600160a01b03166001600160a01b0316815260200190815260200160002060000154828281518110611d2757611d2761315d565b6020908102919091010152611d3b8161312c565b9050611c95565b5095945050505050565b6000546001600160a01b03163314611d765760405162461bcd60e51b8152600401610de090612fab565b611d7e61263e565b8060028381548110611d9257611d9261315d565b906000526020600020906005020160010154600a54611db191906130e9565b611dbb9190613051565b600a819055508060028381548110611dd557611dd561315d565b9060005260206000209060050201600101819055506000827fc12a6201c487829aaa17c8698145154b8fb8c84945e43430f08a08b385ffa8e383600a546040516119c1929190918252602082015260400190565b6000546001600160a01b03163314611e535760405162461bcd60e51b8152600401610de090612fab565b600b805460ff191682151590811790915560405160ff909116151581527f066381685e9b988004d0190e3e15af3526943a03d13d8a917b38b77f45d0a4d89060200160405180910390a150565b600b5460ff1615611ee75760405162461bcd60e51b815260206004820152601160248201527010d858da1a5b99c81a5cc81c185d5cd959607a1b6044820152606401610de0565b60008111611f375760405162461bcd60e51b815260206004820152601d60248201527f537065636966792076616c696420616d6f756e7420746f2063616368650000006044820152606401610de0565b611f4082610e71565b600082815260036020908152604080832033845290915281206002805491929185908110611f7057611f7061315d565b9060005260206000209060050201600301805490506001600160401b03811115611f9c57611f9c613173565b604051908082528060200260200182016040528015611fc5578160200160208202803683370190505b50905060005b81518110156120045783828281518110611fe757611fe761315d565b602090810291909101015280611ffc8161312c565b915050611fcb565b5082600285815481106120195761201961315d565b906000526020600020906005020160040160008282546120399190613051565b9091555050815483908390600090612052908490613051565b9250508190555061206f600285815481106107945761079461315d565b8260010160008282546120829190613010565b9091555050600b805461ff0019169055600280546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691632eb2c2d69133913091899081106120db576120db61315d565b906000526020600020906005020160030185604051806020016040528060008152506040518663ffffffff1660e01b815260040161211d959493929190612ef6565b600060405180830381600087803b15801561213757600080fd5b505af115801561214b573d6000803e3d6000fd5b5050600b805461ff0019166101001790555050604051849033907fa1e3bbbdbb1b06b4311536b4174ea3f26a13cacad3a75aaada060941a0c9ab17906108d19087815260200190565b61219d81610e71565b60008181526003602090815260408083203384529091528120600280549192916121d2919085908110610ad357610ad361315d565b90506000670de0b6b3a76400006121f2846001015484610a7b91906130aa565b6121fc9190613069565b600184018390559050801561222257600154612222906001600160a01b031633836125ec565b600084336001600160a01b03167f45c072aa05b9853b5a993de7a28bc332ee01404a628cec1a23ce0f659f842ef18460405161226091815260200190565b60405180910390a450505050565b6060600282815481106122835761228361315d565b90600052602060002090600502016003018054806020026020016040519081016040528092919081815260200182805480156122de57602002820191906000526020600020905b8154815260200190600101908083116122ca575b50505050509050919050565b600b54600090610100900460ff161561233b5760405162461bcd60e51b81526020600482015260136024820152721bdb949958d95a5d99481a5cc81b1bd8dad959606a1b6044820152606401610de0565b5063f23a6e6160e01b95945050505050565b6000546001600160a01b031633146123775760405162461bcd60e51b8152600401610de090612fab565b6001600160a01b0381166123dc5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610de0565b6123e581612683565b50565b6000546001600160a01b031633146124125760405162461bcd60e51b8152600401610de090612fab565b42600454108015612424575060055442105b6124835760405162461bcd60e51b815260206004820152602a60248201527f43616e206f6e6c792072656d6f76655072696d65416d6f756e7420647572696e60448201526919c818481c195c9a5bd960b21b6064820152608401610de0565b61248b61263e565b61249781600654612582565b905080600660008282546124ab91906130e9565b90915550506005546124be9042906130e9565b670de0b6b3a76400006006546124d4919061308b565b6124de9190613069565b6007556040518181526000907fb8f9e0ef8f651eda7570ff1a8ebe8a2acf07d57f7c18a9184d8e4395c2c82aa590602001611318565b60006001600160ff1b0382111561257e5760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b6064820152608401610de0565b5090565b60008183106125915781612593565b825b9392505050565b60008082121561257e5760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610de0565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611a099084906126d3565b600061264960025490565b905060005b8181101561266f5761265f81610e71565b6126688161312c565b905061264e565b5050565b6000818310156125915781612593565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000612728826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166127a59092919063ffffffff16565b805190915015611a0957808060200190518101906127469190612ca7565b611a095760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610de0565b60606127b484846000856127bc565b949350505050565b60608247101561281d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610de0565b6001600160a01b0385163b6128745760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610de0565b600080866001600160a01b031685876040516128909190612eda565b60006040518083038185875af1925050503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b5091509150610a8a828286606083156128ec575081612593565b8251156128fc5782518084602001fd5b8160405162461bcd60e51b8152600401610de09190612f98565b828054828255906000526020600020908101928215612951579160200282015b82811115612951578251825591602001919060010190612936565b5061257e9291505b8082111561257e5760008155600101612959565b60008083601f84011261297f57600080fd5b5081356001600160401b0381111561299657600080fd5b6020830191508360208260051b85010111156129b157600080fd5b9250929050565b600082601f8301126129c957600080fd5b813560206001600160401b038211156129e4576129e4613173565b8160051b6129f3828201612fe0565b838152828101908684018388018501891015612a0e57600080fd5b600093505b85841015612a31578035835260019390930192918401918401612a13565b50979650505050505050565b600082601f830112612a4e57600080fd5b81356001600160401b03811115612a6757612a67613173565b612a7a601f8201601f1916602001612fe0565b818152846020838601011115612a8f57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215612abe57600080fd5b813561259381613189565b600080600080600060a08688031215612ae157600080fd5b8535612aec81613189565b94506020860135612afc81613189565b935060408601356001600160401b0380821115612b1857600080fd5b612b2489838a016129b8565b94506060880135915080821115612b3a57600080fd5b612b4689838a016129b8565b93506080880135915080821115612b5c57600080fd5b50612b6988828901612a3d565b9150509295509295909350565b600080600080600060a08688031215612b8e57600080fd5b8535612b9981613189565b94506020860135612ba981613189565b9350604086013592506060860135915060808601356001600160401b03811115612bd257600080fd5b612b6988828901612a3d565b60008060208385031215612bf157600080fd5b82356001600160401b03811115612c0757600080fd5b612c138582860161296d565b90969095509350505050565b60008060008060408587031215612c3557600080fd5b84356001600160401b0380821115612c4c57600080fd5b612c588883890161296d565b90965094506020870135915080821115612c7157600080fd5b50612c7e8782880161296d565b95989497509550505050565b600060208284031215612c9c57600080fd5b81356125938161319e565b600060208284031215612cb957600080fd5b81516125938161319e565b600060208284031215612cd657600080fd5b81356001600160e01b03198116811461259357600080fd5b600080600060608486031215612d0357600080fd5b8335612d0e81613189565b92506020840135612d1e81613189565b929592945050506040919091013590565b600060208284031215612d4157600080fd5b5035919050565b60008060408385031215612d5b57600080fd5b823591506020830135612d6d81613189565b809150509250929050565b60008060408385031215612d8b57600080fd5b8235915060208301356001600160401b03811115612da857600080fd5b612db4858286016129b8565b9150509250929050565b60008060408385031215612dd157600080fd5b50508035926020909101359150565b600080600060608486031215612df557600080fd5b505081359360208301359350604090920135919050565b600081518084526020808501945080840160005b83811015612e3c57815187529582019590820190600101612e20565b509495945050505050565b60008151808452612e5f816020860160208601613100565b601f01601f19169290920160200192915050565b815160009082906020808601845b83811015612e9d57815185529382019390820190600101612e81565b50929695505050505050565b60008183548391508460005260208060002060005b83811015612e9d57815485529382019360019182019101612ebe565b60008251612eec818460208701613100565b9190910192915050565b6001600160a01b038681168252851660208083019190915260a060408301819052855490830181905260008681528281209092909160c085019190845b81811015612f4f57845484526001948501949383019301612f33565b5050508381036060850152612f648187612e0c565b9150508281036080840152612f798185612e47565b98975050505050505050565b6020815260006125936020830184612e0c565b6020815260006125936020830184612e47565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b604051601f8201601f191681016001600160401b038111828210171561300857613008613173565b604052919050565b600080821280156001600160ff1b038490038513161561303257613032613147565b600160ff1b839003841281161561304b5761304b613147565b50500190565b6000821982111561306457613064613147565b500190565b60008261308657634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156130a5576130a5613147565b500290565b60008083128015600160ff1b8501841216156130c8576130c8613147565b6001600160ff1b03840183138116156130e3576130e3613147565b50500390565b6000828210156130fb576130fb613147565b500390565b60005b8381101561311b578181015183820152602001613103565b83811115610e6b5750506000910152565b600060001982141561314057613140613147565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146123e557600080fd5b80151581146123e557600080fdfea2646970667358221220c6e3af45fc65bda9ad3ce871c672b9ee123b7da33a7e4168c5eb92bfeba54b3764736f6c63430008070033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076be3b62873462d2142405439777e971754e8e77

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102735760003560e01c80638da5cb5b11610151578063cdeccabf116100c3578063e6fd48bc11610087578063e6fd48bc1461059c578063e7bcdafd146105a5578063f15d6f9d146105b8578063f23a6e61146105cb578063f2fde38b146105de578063f928603e146105f157600080fd5b8063cdeccabf1461053b578063dc628aa41461055b578063ddcb4b681461056e578063e1df480f14610581578063e4f3ae431461059457600080fd5b8063bc197c8111610115578063bc197c81146104a6578063bec4d454146104d2578063bee20885146104db578063c9af39e2146104ee578063ca7238f214610501578063cc8ba1881461052857600080fd5b80638da5cb5b1461045f578063a339bb4614610470578063a85adeab14610482578063ae1f071d1461048b578063b588d1c91461049357600080fd5b80634f94a8cd116101ea5780635c5709ca116101ae5780635c5709ca146103ce5780636af84fc014610415578063715018a61461042857806371993130146104305780637df6a6c814610439578063811822e61461044c57600080fd5b80634f94a8cd1461036f578063503690d11461038257806351eb05a6146103955780635312ea8e146103a857806357a5b58c146103bb57600080fd5b806317caf6f11161023c57806317caf6f1146103195780631cb819ad146103225780632fee4c871461032f5780633f3a1f5014610338578063441a3e7014610347578063446a3c1f1461035c57600080fd5b806217cd8b1461027857806301ffc9a7146102a8578063081e3eda146102cb57806312446f49146102dd5780631526fe27146102e6575b600080fd5b60015461028b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6102bb6102b6366004612cc4565b610604565b604051901515815260200161029f565b6002545b60405190815260200161029f565b6102cf60085481565b6102f96102f4366004612d2f565b61063b565b60408051948552602085019390935291830152606082015260800161029f565b6102cf600a5481565b600b546102bb9060ff1681565b6102cf60095481565b6102cf670de0b6b3a764000081565b61035a610355366004612dbe565b610675565b005b6102cf61036a366004612d48565b6108df565b61035a61037d366004612dbe565b610a95565b61035a610390366004612cee565b610db6565b61035a6103a3366004612d2f565b610e71565b61035a6103b6366004612d2f565b610fc9565b61035a6103c9366004612bde565b6111c6565b6104006103dc366004612d48565b60036020908152600092835260408084209091529082529020805460019091015482565b6040805192835260208301919091520161029f565b61035a610423366004612d2f565b611203565b61035a611323565b6102cf60075481565b61035a610447366004612d2f565b611395565b61035a61045a366004612d2f565b6114d5565b6000546001600160a01b031661028b565b600b546102bb90610100900460ff1681565b6102cf60055481565b6102cf600181565b61035a6104a1366004612aac565b611569565b6104b96104b4366004612ac9565b611619565b6040516001600160e01b0319909116815260200161029f565b6102cf60065481565b61035a6104e9366004612d78565b61167c565b61035a6104fc366004612bde565b6119cd565b61028b7f00000000000000000000000076be3b62873462d2142405439777e971754e8e7781565b61035a610536366004612de0565b611a0e565b61054e610549366004612c1f565b611bf0565b60405161029f9190612f85565b61035a610569366004612dbe565b611d4c565b61035a61057c366004612c8a565b611e29565b61035a61058f366004612dbe565b611ea0565b6102cf600081565b6102cf60045481565b61035a6105b3366004612d2f565b612194565b61054e6105c6366004612d2f565b61226e565b6104b96105d9366004612b76565b6122ea565b61035a6105ec366004612aac565b61234d565b61035a6105ff366004612d2f565b6123e8565b60006001600160e01b03198216630271189760e51b148061063557506301ffc9a760e01b6001600160e01b03198316145b92915050565b6002818154811061064b57600080fd5b60009182526020909120600590910201805460018201546002830154600490930154919350919084565b61067e82610e71565b6000828152600360209081526040808320338452909152812060028054919291859081106106ae576106ae61315d565b9060005260206000209060050201600301805490506001600160401b038111156106da576106da613173565b604051908082528060200260200182016040528015610703578160200160208202803683370190505b50905060005b815181101561074257838282815181106107255761072561315d565b60209081029190910101528061073a8161312c565b915050610709565b5082600285815481106107575761075761315d565b9060005260206000209060050201600401600082825461077791906130e9565b925050819055506107b6600285815481106107945761079461315d565b906000526020600020906005020160000154846107b1919061308b565b612514565b8260010160008282546107c991906130aa565b90915550508154839083906000906107e29084906130e9565b925050819055507f00000000000000000000000076be3b62873462d2142405439777e971754e8e776001600160a01b0316632eb2c2d630336002888154811061082d5761082d61315d565b906000526020600020906005020160030185604051806020016040528060008152506040518663ffffffff1660e01b815260040161086f959493929190612ef6565b600060405180830381600087803b15801561088957600080fd5b505af115801561089d573d6000803e3d6000fd5b50506040518581528692503391507ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020015b60405180910390a350505050565b600080600284815481106108f5576108f561315d565b90600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820180548060200260200160405190810160405280929190818152602001828054801561097b57602002820191906000526020600020905b815481526020019060010190808311610967575b505050918352505060049182015460209182015260008781526003825260408082206001600160a01b038916835290925220825160808401519254939450909290919042108015906109d05750428460400151105b80156109dc5750600081115b15610a4d5760006109ef42600554612582565b90506000856040015182610a0391906130e9565b90506000600a54876020015160075484610a1d919061308b565b610a27919061308b565b610a319190613069565b9050610a3d8482613069565b610a479086613051565b94505050505b670de0b6b3a7640000610a808460010154610a718587600001546107b1919061308b565b610a7b91906130aa565b61259a565b610a8a9190613069565b979650505050505050565b610a9e82610e71565b6000828152600360209081526040808320338452909152812060028054919291610af0919086908110610ad357610ad361315d565b600091825260209091206005909102015483546107b1919061308b565b90506000670de0b6b3a7640000610b10846001015484610a7b91906130aa565b610b1a9190613069565b9050600060028681548110610b3157610b3161315d565b9060005260206000209060050201600301805490506001600160401b03811115610b5d57610b5d613173565b604051908082528060200260200182016040528015610b86578160200160208202803683370190505b50905060005b8151811015610bc55785828281518110610ba857610ba861315d565b602090810291909101015280610bbd8161312c565b915050610b8c565b508460028781548110610bda57610bda61315d565b90600052602060002090600502016004016000828254610bfa91906130e9565b92505081905550610c3460028781548110610c1757610c1761315d565b906000526020600020906005020160000154866107b1919061308b565b610c3e90846130aa565b6001850155835485908590600090610c579084906130e9565b90915550508115610c7957600154610c79906001600160a01b031633846125ec565b7f00000000000000000000000076be3b62873462d2142405439777e971754e8e776001600160a01b0316632eb2c2d6303360028a81548110610cbd57610cbd61315d565b906000526020600020906005020160030185604051806020016040528060008152506040518663ffffffff1660e01b8152600401610cff959493929190612ef6565b600060405180830381600087803b158015610d1957600080fd5b505af1158015610d2d573d6000803e3d6000fd5b50506040518781528892503391507ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a3600086336001600160a01b03167f45c072aa05b9853b5a993de7a28bc332ee01404a628cec1a23ce0f659f842ef185604051610da691815260200190565b60405180910390a4505050505050565b6000546001600160a01b03163314610de95760405162461bcd60e51b8152600401610de090612fab565b60405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0383811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b158015610e3357600080fd5b505af1158015610e47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6b9190612ca7565b50505050565b600060028281548110610e8657610e8661315d565b90600052602060002090600502019050426004541180610eaa575042816002015410155b80610ec05750600454158015610ec05750600554155b15610ec9575050565b6000610ed742600554612582565b6004830154600284015491925090600090610ef290846130e9565b90506000600a54856001015460075484610f0c919061308b565b610f16919061308b565b610f209190613069565b9050610f34670de0b6b3a764000082613069565b60066000828254610f4591906130e9565b90915550508215610f7357610f5a8382613069565b856000016000828254610f6d9190613051565b90915550505b6002850184905584546040805186815260208101869052808201929092525160009188917fc75b283f14d0a806c63b93a3659ed39c43a20bf0fff8030465e93d79e91ca40f9181900360600190a3505050505050565b600081815260036020908152604080832033845290915281208054600280549293919285908110610ffc57610ffc61315d565b9060005260206000209060050201600301805490506001600160401b0381111561102857611028613173565b604051908082528060200260200182016040528015611051578160200160208202803683370190505b50905060005b815181101561109057828282815181106110735761107361315d565b6020908102919091010152806110888161312c565b915050611057565b5081600285815481106110a5576110a561315d565b906000526020600020906005020160040160008282546110c591906130e9565b90915550506000600184018190558355600280546001600160a01b037f00000000000000000000000076be3b62873462d2142405439777e971754e8e771691632eb2c2d691309133918990811061111e5761111e61315d565b906000526020600020906005020160030185604051806020016040528060008152506040518663ffffffff1660e01b8152600401611160959493929190612ef6565b600060405180830381600087803b15801561117a57600080fd5b505af115801561118e573d6000803e3d6000fd5b50506040518481528692503391507fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae0595906020016108d1565b8060005b81811015610e6b576111f38484838181106111e7576111e761315d565b90506020020135610e71565b6111fc8161312c565b90506111ca565b6000546001600160a01b0316331461122d5760405162461bcd60e51b8152600401610de090612fab565b4260045410801561123f575060055442105b6112995760405162461bcd60e51b815260206004820152602560248201527f43616e206f6e6c79206164645072696d65416d6f756e7420647572696e672070604482015264195c9a5bd960da1b6064820152608401610de0565b6112a161263e565b80600660008282546112b39190613051565b90915550506005546112c69042906130e9565b670de0b6b3a76400006006546112dc919061308b565b6112e69190613069565b6007556040518181526000907f4dffb45d6f962f8af66e8c830a9a6027cea8919fd29147db4be34dadb0fb5f1e906020015b60405180910390a250565b6000546001600160a01b0316331461134d5760405162461bcd60e51b8152600401610de090612fab565b60405162461bcd60e51b815260206004820152601d60248201527f4f776e6572736869702063616e6e6f742062652072656e6f756e6365640000006044820152606401610de0565b6000546001600160a01b031633146113bf5760405162461bcd60e51b8152600401610de090612fab565b426004541061141b5760405162461bcd60e51b815260206004820152602260248201527f63616368696e6720706572696f6420686173206e6f7420737461727465642079604482015261195d60f21b6064820152608401610de0565b8042106114625760405162461bcd60e51b81526020600482015260156024820152740696e76616c696420656e642074696d657374616d7605c1b6044820152606401610de0565b61146a61263e565b426004819055600582905561147f90826130e9565b670de0b6b3a7640000600654611495919061308b565b61149f9190613069565b6007556040518181526000907f7e9fbea655506e5a9e67dca69341fadbddee58b360cc1e2f888d0b5576febb8490602001611318565b6000546001600160a01b031633146114ff5760405162461bcd60e51b8152600401610de090612fab565b6002548110156115645760405162461bcd60e51b815260206004820152602a60248201527f43616e277420736574206d61784e756d506f6f6c73206c657373207468616e206044820152690e0deded898cadccee8d60b31b6064820152608401610de0565b600955565b6000546001600160a01b031633146115935760405162461bcd60e51b8152600401610de090612fab565b60085442106115f75760405162461bcd60e51b815260206004820152602a60248201527f5052494d452061646472657373207570646174652077696e646f7720686173206044820152691a185cc81c185cdcd95960b21b6064820152608401610de0565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600b54600090610100900460ff161561166a5760405162461bcd60e51b81526020600482015260136024820152721bdb949958d95a5d99481a5cc81b1bd8dad959606a1b6044820152606401610de0565b5063bc197c8160e01b95945050505050565b6000546001600160a01b031633146116a65760405162461bcd60e51b8152600401610de090612fab565b600954600254106116f15760405162461bcd60e51b815260206004820152601560248201527413585e081b9d5b481c1bdbdb1cc81c995858da1959605a1b6044820152606401610de0565b60008151116117425760405162461bcd60e51b815260206004820152601860248201527f546f6b656e4964732063616e6e6f7420626520656d70747900000000000000006044820152606401610de0565b600082116117a35760405162461bcd60e51b815260206004820152602860248201527f416c6c6f636174696f6e20706f696e742063616e6e6f742062652030206f72206044820152676e6567617469766560c01b6064820152608401610de0565b60005b600254811015611888576117b981610e71565b816040516020016117ca9190612e73565b60405160208183030381529060405280519060200120600282815481106117f3576117f361315d565b90600052602060002090600502016003016040516020016118149190612ea9565b6040516020818303038152906040528051906020012014156118785760405162461bcd60e51b815260206004820152601e60248201527f506f6f6c20776974682073616d6520746f6b656e4964732065786973747300006044820152606401610de0565b6118818161312c565b90506117a6565b5081600a600082825461189b9190613051565b9250508190555060026040518060a00160405280600081526020018481526020016118c842600454612673565b81526020808201859052600060409283018190528454600181810187559582529082902084516005909202019081558382015194810194909455908201516002840155606082015180519293926119259260038501920190612916565b5060809190910151600490910155600254611942906001906130e9565b7f433d962a500f8c767748676218e15a2c52504785df1e3ea4a25d04926140609c826040516119719190612f85565b60405180910390a260025460009061198b906001906130e9565b600a546040805186815260208101929092527fc12a6201c487829aaa17c8698145154b8fb8c84945e43430f08a08b385ffa8e391015b60405180910390a35050565b60005b81811015611a09576119f98383838181106119ed576119ed61315d565b90506020020135612194565b611a028161312c565b90506119d0565b505050565b6000546001600160a01b03163314611a385760405162461bcd60e51b8152600401610de090612fab565b818310611a9d5760405162461bcd60e51b815260206004820152602d60248201527f656e6454696d657374616d702063616e74206265206c657373207468616e207360448201526c07461727454696d657374616d7609c1b6064820152608401610de0565b600454421080611aae575042600554105b611b205760405162461bcd60e51b815260206004820152603860248201527f4f6e6c79207570646174657320616674657220656e6454696d657374616d702060448201527f6f72206265666f726520737461727454696d657374616d7000000000000000006064820152608401610de0565b60005b600254811015611b6e57611b3681610e71565b8360028281548110611b4a57611b4a61315d565b6000918252602090912060026005909202010155611b678161312c565b9050611b23565b50600681905560048390556005829055611b8883836130e9565b611b9a670de0b6b3a76400008361308b565b611ba49190613069565b60075560408051828152602081018590529081018390526000907f72bb6e826d1a04bd8fa5fdde85546e3b9eb8e95d8500eec20f4c0124edcb422b9060600160405180910390a2505050565b6060838214611c4c5760405162461bcd60e51b815260206004820152602260248201527f7069647320616e6420616464726573736573206c656e677468206d69736d61746044820152610c6d60f31b6064820152608401610de0565b6000846001600160401b03811115611c6657611c66613173565b604051908082528060200260200182016040528015611c8f578160200160208202803683370190505b50905060005b85811015611d425760036000888884818110611cb357611cb361315d565b9050602002013581526020019081526020016000206000868684818110611cdc57611cdc61315d565b9050602002016020810190611cf19190612aac565b6001600160a01b03166001600160a01b0316815260200190815260200160002060000154828281518110611d2757611d2761315d565b6020908102919091010152611d3b8161312c565b9050611c95565b5095945050505050565b6000546001600160a01b03163314611d765760405162461bcd60e51b8152600401610de090612fab565b611d7e61263e565b8060028381548110611d9257611d9261315d565b906000526020600020906005020160010154600a54611db191906130e9565b611dbb9190613051565b600a819055508060028381548110611dd557611dd561315d565b9060005260206000209060050201600101819055506000827fc12a6201c487829aaa17c8698145154b8fb8c84945e43430f08a08b385ffa8e383600a546040516119c1929190918252602082015260400190565b6000546001600160a01b03163314611e535760405162461bcd60e51b8152600401610de090612fab565b600b805460ff191682151590811790915560405160ff909116151581527f066381685e9b988004d0190e3e15af3526943a03d13d8a917b38b77f45d0a4d89060200160405180910390a150565b600b5460ff1615611ee75760405162461bcd60e51b815260206004820152601160248201527010d858da1a5b99c81a5cc81c185d5cd959607a1b6044820152606401610de0565b60008111611f375760405162461bcd60e51b815260206004820152601d60248201527f537065636966792076616c696420616d6f756e7420746f2063616368650000006044820152606401610de0565b611f4082610e71565b600082815260036020908152604080832033845290915281206002805491929185908110611f7057611f7061315d565b9060005260206000209060050201600301805490506001600160401b03811115611f9c57611f9c613173565b604051908082528060200260200182016040528015611fc5578160200160208202803683370190505b50905060005b81518110156120045783828281518110611fe757611fe761315d565b602090810291909101015280611ffc8161312c565b915050611fcb565b5082600285815481106120195761201961315d565b906000526020600020906005020160040160008282546120399190613051565b9091555050815483908390600090612052908490613051565b9250508190555061206f600285815481106107945761079461315d565b8260010160008282546120829190613010565b9091555050600b805461ff0019169055600280546001600160a01b037f00000000000000000000000076be3b62873462d2142405439777e971754e8e771691632eb2c2d69133913091899081106120db576120db61315d565b906000526020600020906005020160030185604051806020016040528060008152506040518663ffffffff1660e01b815260040161211d959493929190612ef6565b600060405180830381600087803b15801561213757600080fd5b505af115801561214b573d6000803e3d6000fd5b5050600b805461ff0019166101001790555050604051849033907fa1e3bbbdbb1b06b4311536b4174ea3f26a13cacad3a75aaada060941a0c9ab17906108d19087815260200190565b61219d81610e71565b60008181526003602090815260408083203384529091528120600280549192916121d2919085908110610ad357610ad361315d565b90506000670de0b6b3a76400006121f2846001015484610a7b91906130aa565b6121fc9190613069565b600184018390559050801561222257600154612222906001600160a01b031633836125ec565b600084336001600160a01b03167f45c072aa05b9853b5a993de7a28bc332ee01404a628cec1a23ce0f659f842ef18460405161226091815260200190565b60405180910390a450505050565b6060600282815481106122835761228361315d565b90600052602060002090600502016003018054806020026020016040519081016040528092919081815260200182805480156122de57602002820191906000526020600020905b8154815260200190600101908083116122ca575b50505050509050919050565b600b54600090610100900460ff161561233b5760405162461bcd60e51b81526020600482015260136024820152721bdb949958d95a5d99481a5cc81b1bd8dad959606a1b6044820152606401610de0565b5063f23a6e6160e01b95945050505050565b6000546001600160a01b031633146123775760405162461bcd60e51b8152600401610de090612fab565b6001600160a01b0381166123dc5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610de0565b6123e581612683565b50565b6000546001600160a01b031633146124125760405162461bcd60e51b8152600401610de090612fab565b42600454108015612424575060055442105b6124835760405162461bcd60e51b815260206004820152602a60248201527f43616e206f6e6c792072656d6f76655072696d65416d6f756e7420647572696e60448201526919c818481c195c9a5bd960b21b6064820152608401610de0565b61248b61263e565b61249781600654612582565b905080600660008282546124ab91906130e9565b90915550506005546124be9042906130e9565b670de0b6b3a76400006006546124d4919061308b565b6124de9190613069565b6007556040518181526000907fb8f9e0ef8f651eda7570ff1a8ebe8a2acf07d57f7c18a9184d8e4395c2c82aa590602001611318565b60006001600160ff1b0382111561257e5760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b6064820152608401610de0565b5090565b60008183106125915781612593565b825b9392505050565b60008082121561257e5760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610de0565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611a099084906126d3565b600061264960025490565b905060005b8181101561266f5761265f81610e71565b6126688161312c565b905061264e565b5050565b6000818310156125915781612593565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000612728826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166127a59092919063ffffffff16565b805190915015611a0957808060200190518101906127469190612ca7565b611a095760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610de0565b60606127b484846000856127bc565b949350505050565b60608247101561281d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610de0565b6001600160a01b0385163b6128745760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610de0565b600080866001600160a01b031685876040516128909190612eda565b60006040518083038185875af1925050503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b5091509150610a8a828286606083156128ec575081612593565b8251156128fc5782518084602001fd5b8160405162461bcd60e51b8152600401610de09190612f98565b828054828255906000526020600020908101928215612951579160200282015b82811115612951578251825591602001919060010190612936565b5061257e9291505b8082111561257e5760008155600101612959565b60008083601f84011261297f57600080fd5b5081356001600160401b0381111561299657600080fd5b6020830191508360208260051b85010111156129b157600080fd5b9250929050565b600082601f8301126129c957600080fd5b813560206001600160401b038211156129e4576129e4613173565b8160051b6129f3828201612fe0565b838152828101908684018388018501891015612a0e57600080fd5b600093505b85841015612a31578035835260019390930192918401918401612a13565b50979650505050505050565b600082601f830112612a4e57600080fd5b81356001600160401b03811115612a6757612a67613173565b612a7a601f8201601f1916602001612fe0565b818152846020838601011115612a8f57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215612abe57600080fd5b813561259381613189565b600080600080600060a08688031215612ae157600080fd5b8535612aec81613189565b94506020860135612afc81613189565b935060408601356001600160401b0380821115612b1857600080fd5b612b2489838a016129b8565b94506060880135915080821115612b3a57600080fd5b612b4689838a016129b8565b93506080880135915080821115612b5c57600080fd5b50612b6988828901612a3d565b9150509295509295909350565b600080600080600060a08688031215612b8e57600080fd5b8535612b9981613189565b94506020860135612ba981613189565b9350604086013592506060860135915060808601356001600160401b03811115612bd257600080fd5b612b6988828901612a3d565b60008060208385031215612bf157600080fd5b82356001600160401b03811115612c0757600080fd5b612c138582860161296d565b90969095509350505050565b60008060008060408587031215612c3557600080fd5b84356001600160401b0380821115612c4c57600080fd5b612c588883890161296d565b90965094506020870135915080821115612c7157600080fd5b50612c7e8782880161296d565b95989497509550505050565b600060208284031215612c9c57600080fd5b81356125938161319e565b600060208284031215612cb957600080fd5b81516125938161319e565b600060208284031215612cd657600080fd5b81356001600160e01b03198116811461259357600080fd5b600080600060608486031215612d0357600080fd5b8335612d0e81613189565b92506020840135612d1e81613189565b929592945050506040919091013590565b600060208284031215612d4157600080fd5b5035919050565b60008060408385031215612d5b57600080fd5b823591506020830135612d6d81613189565b809150509250929050565b60008060408385031215612d8b57600080fd5b8235915060208301356001600160401b03811115612da857600080fd5b612db4858286016129b8565b9150509250929050565b60008060408385031215612dd157600080fd5b50508035926020909101359150565b600080600060608486031215612df557600080fd5b505081359360208301359350604090920135919050565b600081518084526020808501945080840160005b83811015612e3c57815187529582019590820190600101612e20565b509495945050505050565b60008151808452612e5f816020860160208601613100565b601f01601f19169290920160200192915050565b815160009082906020808601845b83811015612e9d57815185529382019390820190600101612e81565b50929695505050505050565b60008183548391508460005260208060002060005b83811015612e9d57815485529382019360019182019101612ebe565b60008251612eec818460208701613100565b9190910192915050565b6001600160a01b038681168252851660208083019190915260a060408301819052855490830181905260008681528281209092909160c085019190845b81811015612f4f57845484526001948501949383019301612f33565b5050508381036060850152612f648187612e0c565b9150508281036080840152612f798185612e47565b98975050505050505050565b6020815260006125936020830184612e0c565b6020815260006125936020830184612e47565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b604051601f8201601f191681016001600160401b038111828210171561300857613008613173565b604052919050565b600080821280156001600160ff1b038490038513161561303257613032613147565b600160ff1b839003841281161561304b5761304b613147565b50500190565b6000821982111561306457613064613147565b500190565b60008261308657634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156130a5576130a5613147565b500290565b60008083128015600160ff1b8501841216156130c8576130c8613147565b6001600160ff1b03840183138116156130e3576130e3613147565b50500390565b6000828210156130fb576130fb613147565b500390565b60005b8381101561311b578181015183820152602001613103565b83811115610e6b5750506000910152565b600060001982141561314057613140613147565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146123e557600080fd5b80151581146123e557600080fdfea2646970667358221220c6e3af45fc65bda9ad3ce871c672b9ee123b7da33a7e4168c5eb92bfeba54b3764736f6c63430008070033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076be3b62873462d2142405439777e971754e8e77

-----Decoded View---------------
Arg [0] : _prime (address): 0x0000000000000000000000000000000000000000
Arg [1] : _parallelAlpha (address): 0x76BE3b62873462d2142405439777e971754E8E77

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 00000000000000000000000076be3b62873462d2142405439777e971754e8e77


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.