ETH Price: $1,866.36 (-4.69%)

Contract Diff Checker

Contract Name:
ApeXPool3

Contract Source Code:

<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import "./interfaces/IApeXPool3.sol";
import "../utils/Ownable.sol";
import "../libraries/TransferHelper.sol";

contract ApeXPool3 is IApeXPool3, Ownable {
    address public override apeX;
    address public override esApeX;

    struct stakingInfo{
        address lockToken;
        address owner;
        uint256 accountId;
        uint256 amount;
        uint256 lockPeriod;
        uint256 lockStart;
        bool unlocked;
    }

    mapping(uint256 => stakingInfo) public stakingAPEX;
    mapping(uint256 => stakingInfo) public stakingEsAPEX;

    uint256 public globalStakeId;
    bool public override paused;

    constructor(address _apeX, address _esApeX, address _owner) {
        apeX = _apeX;
        esApeX = _esApeX;
        owner = _owner;
    }

    function setPaused(bool newState) external override onlyOwner {
        require(paused != newState, "same state");
        paused = newState;
        emit PausedStateChanged(newState);
    }

    function setApex(address _newApex) external override onlyOwner {
        require(_newApex != address(0));
        apeX = _newApex;
        emit ApexChanged(_newApex);
    }

    function setEsApex(address _newEsApex) external override onlyOwner {
        require(_newEsApex != address(0));
        esApeX = _newEsApex;
        emit EsApexChanged(_newEsApex);
    }

    function stakeAPEX(uint256 accountId, uint256 amount,uint256 lockPeriod) external override {
        require(!paused, "paused");
        require(apeX != address(0));
        TransferHelper.safeTransferFrom(apeX, msg.sender, address(this), amount);

        globalStakeId++;
        stakingAPEX[globalStakeId] = stakingInfo({
            lockToken: apeX,
            owner: msg.sender,
            accountId: accountId,
            amount: amount,
            lockPeriod: lockPeriod,
            lockStart: block.timestamp,
            unlocked: false
        });

        emit Staked(apeX, msg.sender, globalStakeId, accountId, amount,lockPeriod);
    }

    function stakeEsAPEX(uint256 accountId, uint256 amount,uint256 lockPeriod) external override {
        require(!paused, "paused");
        require(esApeX != address(0));
        TransferHelper.safeTransferFrom(esApeX, msg.sender, address(this), amount);
       
        globalStakeId++;
        stakingEsAPEX[globalStakeId] = stakingInfo({
            lockToken: esApeX,
            owner: msg.sender,
            accountId: accountId,
            amount: amount,
            lockPeriod: lockPeriod,
            lockStart: block.timestamp,
            unlocked: false
        });

        emit Staked(esApeX, msg.sender, globalStakeId, accountId, amount,lockPeriod);
    }

    function unstakeAPEX(uint256 stakeId) external override {
       _unstakeAPEX(stakeId);
    }

    function _unstakeAPEX(uint256 stakeId) private {
        stakingInfo memory info = stakingAPEX[stakeId];
        require(info.owner == msg.sender, "not allowed");
        require(info.lockStart+info.lockPeriod <= block.timestamp,"in lock period");
        require(info.lockToken == apeX, "apeX token mismatch");
        require(!info.unlocked,"already unlocked");

        TransferHelper.safeTransfer(apeX, info.owner, info.amount);
        stakingAPEX[stakeId].unlocked = true;
        emit Unstaked(stakeId);
    }

    function batchUnstakeAPEX(uint256[] calldata stakeIds) external  {
        for (uint i = 0; i < stakeIds.length; i++) {
            _unstakeAPEX(stakeIds[i]);
        }
    }

    function _unstakeEsAPEX(uint256 stakeId) private{
        stakingInfo memory info = stakingEsAPEX[stakeId];
        require(info.owner == msg.sender, "not allowed");
        require(info.lockStart+info.lockPeriod <= block.timestamp,"in lock period");
        require(info.lockToken == esApeX, "esApeX token mismatch");
        require(!info.unlocked,"already unlocked");

        TransferHelper.safeTransfer(esApeX, info.owner, info.amount);
        stakingEsAPEX[stakeId].unlocked = true;
        emit Unstaked(stakeId);
    }

    function unstakeEsAPEX(uint256 stakeId) external override {
        _unstakeEsAPEX(stakeId);
    }

    function batchUnstakeEsAPEX(uint256[] calldata stakeIds) external  {
        for (uint i = 0; i < stakeIds.length; i++) {
            _unstakeEsAPEX(stakeIds[i]);
        }
    }
}

<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

interface IApeXPool3 {
    event ApexChanged(address newApex);
    event EsApexChanged(address newEsApex);
    event PausedStateChanged(bool newState);
    event Staked(address indexed token, address indexed user, uint256 stakeId, uint256 accountId, uint256 amount, uint256 lockPeriod);
    event Unstaked(uint256 stakeId);

    function apeX() external view returns (address);

    function esApeX() external view returns (address);

    function paused() external view returns (bool);

    function setPaused(bool newState) external;

    function setApex(address newApex) external;

    function setEsApex(address newEsApex) external;

    function stakeAPEX(uint256 accountId, uint256 amount,uint256 lockPeriod) external;

    function stakeEsAPEX(uint256 accountId, uint256 amount,uint256 lockPeriod) external;

    function unstakeAPEX(uint256 stakeId) external;

    function unstakeEsAPEX(uint256 stakeId) external;
}

<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

abstract contract Ownable {
    address public owner;
    address public pendingOwner;

    event NewOwner(address indexed oldOwner, address indexed newOwner);
    event NewPendingOwner(address indexed oldPendingOwner, address indexed newPendingOwner);

    modifier onlyOwner() {
        require(msg.sender == owner, "Ownable: REQUIRE_OWNER");
        _;
    }

    function setPendingOwner(address newPendingOwner) external onlyOwner {
        require(pendingOwner != newPendingOwner, "Ownable: ALREADY_SET");
        emit NewPendingOwner(pendingOwner, newPendingOwner);
        pendingOwner = newPendingOwner;
    }

    function acceptOwner() external {
        require(msg.sender == pendingOwner, "Ownable: REQUIRE_PENDING_OWNER");
        address oldOwner = owner;
        address oldPendingOwner = pendingOwner;
        owner = pendingOwner;
        pendingOwner = address(0);
        emit NewOwner(oldOwner, owner);
        emit NewPendingOwner(oldPendingOwner, pendingOwner);
    }
}

<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper::safeApprove: approve failed"
        );
    }

    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper::safeTransfer: transfer failed"
        );
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper::transferFrom: transferFrom failed"
        );
    }

    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "TransferHelper::safeTransferETH: ETH transfer failed");
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):