文件 1 的 4:ApeXPool2OnArbi.sol
pragma solidity ^0.8.0;
import "./interfaces/IApeXPool2.sol";
import "../utils/Ownable.sol";
import "../libraries/TransferHelper.sol";
contract ApeXPool2OnArbi is Ownable {
event PausedStateChanged(bool newState);
event Staked(address indexed token, address indexed user, uint256 accountId, uint256 amount);
event Unstaked(address indexed token, address indexed user, address indexed to, uint256 accountId, uint256 amount);
address public immutable apeX;
bool public paused;
mapping(address => mapping(uint256 => uint256)) public stakingAPEX;
constructor(address _apeX, address _owner) {
apeX = _apeX;
owner = _owner;
}
function setPaused(bool newState) external onlyOwner {
require(paused != newState, "same state");
paused = newState;
emit PausedStateChanged(newState);
}
function stakeAPEX(uint256 accountId, uint256 amount) external {
require(!paused, "paused");
TransferHelper.safeTransferFrom(apeX, msg.sender, address(this), amount);
stakingAPEX[msg.sender][accountId] += amount;
emit Staked(apeX, msg.sender, accountId, amount);
}
function unstakeAPEX(address to, uint256 accountId, uint256 amount) external {
require(amount <= stakingAPEX[msg.sender][accountId], "not enough balance");
stakingAPEX[msg.sender][accountId] -= amount;
TransferHelper.safeTransfer(apeX, to, amount);
emit Unstaked(apeX, msg.sender, to, accountId, amount);
}
}
文件 2 的 4:IApeXPool2.sol
pragma solidity ^0.8.0;
interface IApeXPool2 {
event PausedStateChanged(bool newState);
event Staked(address indexed token, address indexed user, uint256 accountId, uint256 amount);
event Unstaked(address indexed token, address indexed user, address indexed to, uint256 accountId, uint256 amount);
function apeX() external view returns (address);
function esApeX() external view returns (address);
function stakingAPEX(address user, uint256 accountId) external view returns (uint256);
function stakingEsAPEX(address user, uint256 accountId) external view returns (uint256);
function paused() external view returns (bool);
function setPaused(bool newState) external;
function stakeAPEX(uint256 accountId, uint256 amount) external;
function stakeEsAPEX(uint256 accountId, uint256 amount) external;
function unstakeAPEX(address to, uint256 accountId, uint256 amount) external;
function unstakeEsAPEX(address to, uint256 accountId, uint256 amount) external;
}
文件 3 的 4:Ownable.sol
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);
}
}
文件 4 的 4:TransferHelper.sol
pragma solidity ^0.8.0;
library TransferHelper {
function safeApprove(
address token,
address to,
uint256 value
) internal {
(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 {
(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 {
(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");
}
}
{
"compilationTarget": {
"contracts/stakingV2/ApeXPool2OnArbi.sol": "ApeXPool2OnArbi"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_apeX","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldPendingOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newPendingOwner","type":"address"}],"name":"NewPendingOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newState","type":"bool"}],"name":"PausedStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"accountId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"accountId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstaked","type":"event"},{"inputs":[],"name":"acceptOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"apeX","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"newState","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPendingOwner","type":"address"}],"name":"setPendingOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"accountId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stakeAPEX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakingAPEX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"accountId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstakeAPEX","outputs":[],"stateMutability":"nonpayable","type":"function"}]