编译器
0.8.17+commit.8df45f5f
文件 1 的 7:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
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");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 7:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 3 的 7:Errors.sol
pragma solidity ^0.8.9;
error LengthNotMatch();
error EmptyTokenClaim();
error AlreadyRegist();
error NotInvestor();
error AlreadyClaimed();
error WholeClaimed();
error OutofRange();
error Faild();
error NotYet();
error ExceedAmount();
error NotMatchedAmount();
error ExceedTime();
error MoreTimeDelay();
error NotAirdropUser();
error TimeNotSet();
文件 4 的 7:IERC20.sol
pragma solidity ^0.8.17;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 5 的 7:NewPlexusIDO_202311.sol
pragma solidity ^0.8.17;
import "./libraries/SafeERC20.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import {LengthNotMatch, AlreadyRegist, NotInvestor, AlreadyClaimed, WholeClaimed, EmptyTokenClaim, OutofRange, Faild, NotYet, ExceedAmount, NotMatchedAmount, ExceedTime, MoreTimeDelay, NotAirdropUser, TimeNotSet} from "./Errors.sol";
interface OldAirdrop {
struct AirdropUser {
uint256 airdropUserTotalClaimable;
uint256 airdropUserTotalClaimed;
uint256 airdropUpdateLastClaimTime;
}
}
interface IPlexusIDO_202311 {
struct User {
uint256 userTotalClaimableAmount;
uint256 updateLastClaimTimestamp;
uint256 userTotalClaimed;
}
function AirdropUserInfo(address user) external view returns (User memory);
function oldAirdropInfo(address user) external view returns (OldAirdrop.AirdropUser memory);
function TGETimestamp() external view returns (uint256);
}
contract NewPlexusIDO_202311 is Pausable {
using SafeERC20 for IERC20;
event Claim(address user, uint256 claimAmount, uint256 claimTime);
event ChangeOwner(address oldOwner, address newOwner);
event ChangeTGEtime(uint256 oldTime, uint256 newTime);
IERC20 private immutable PLEXUS;
address public owner;
address public plexusIDO;
address public plexusIDO_202311;
address public plexusIDO_202311_old;
uint256 public plexusTotalAmount;
uint256 public TGETimestamp;
uint256 public claimStartTime;
uint256 public constant PLX_ACC_PRECISION = 1e18;
uint256 public constant AIRDROP_TOTAL_SUPPLY = 9_750_500;
uint256 public airdropTotalClaimed;
address[] internal signerList;
mapping(address => uint256) confirmTime;
struct User {
uint256 userTotalClaimableAmount;
uint256 updateLastClaimTimestamp;
uint256 userTotalClaimed;
}
modifier onlyOwner() {
require(msg.sender == owner, "No permission");
_;
}
constructor(address _plxAddress, address _plexusIDO, address _plexusIDO_202311, address _plexusIDO_202311_old) {
PLEXUS = IERC20(_plxAddress);
plexusIDO = _plexusIDO;
plexusIDO_202311 = _plexusIDO_202311;
plexusIDO_202311_old = _plexusIDO_202311_old;
owner = msg.sender;
TGETimestamp = IPlexusIDO_202311(plexusIDO_202311).TGETimestamp();
}
function setClaimStartTime(uint256 _claimStartTime) external onlyOwner {
claimStartTime = _claimStartTime;
}
function setOwner(address _newOwner) public onlyOwner {
require(_newOwner != address(0));
owner = _newOwner;
emit ChangeOwner(msg.sender, _newOwner);
}
function pauseOnOff() external onlyOwner {
if (!paused()) {
_pause();
} else {
_unpause();
}
}
function _calculmonth(uint256 _num) internal pure returns (uint256) {
return _num * 30 days;
}
function _mulPrecision(uint256 _num) internal pure returns (uint256) {
return _num * PLX_ACC_PRECISION;
}
function callPlxBalance() public view returns (uint256) {
return PLEXUS.balanceOf(address(this));
}
mapping(address => User) public AirdropUserInfo;
function airdropUserClaimablePlx(address _user) public view returns (uint256) {
User memory airdropUser = AirdropUserInfo[_user];
uint256 userTotalClaimableAmount;
uint256 userTotalClaimed;
if (airdropUser.updateLastClaimTimestamp == 0) {
userTotalClaimableAmount = IPlexusIDO_202311(plexusIDO).AirdropUserInfo(_user).userTotalClaimableAmount;
userTotalClaimed = IPlexusIDO_202311(plexusIDO).AirdropUserInfo(_user).userTotalClaimed;
if (userTotalClaimableAmount == 0) {
userTotalClaimableAmount = IPlexusIDO_202311(plexusIDO_202311).AirdropUserInfo(_user).userTotalClaimableAmount;
userTotalClaimed = IPlexusIDO_202311(plexusIDO_202311).AirdropUserInfo(_user).userTotalClaimed;
if (userTotalClaimableAmount == 0) {
userTotalClaimableAmount = IPlexusIDO_202311(plexusIDO_202311_old).AirdropUserInfo(_user).userTotalClaimableAmount;
userTotalClaimed = IPlexusIDO_202311(plexusIDO_202311_old).AirdropUserInfo(_user).userTotalClaimed;
}
}
} else {
if (airdropUser.userTotalClaimed >= airdropUser.userTotalClaimableAmount) revert WholeClaimed();
userTotalClaimableAmount = airdropUser.userTotalClaimableAmount;
userTotalClaimed = airdropUser.userTotalClaimed;
}
uint256 tgeDateClaimbleAmount;
uint256 airdropEndTime;
if (userTotalClaimableAmount <= (5000 * PLX_ACC_PRECISION)) {
tgeDateClaimbleAmount = (userTotalClaimableAmount * 125) / 1000;
airdropEndTime = _calculmonth(8);
} else if (userTotalClaimableAmount > (5000 * PLX_ACC_PRECISION) && userTotalClaimableAmount <= (50000 * PLX_ACC_PRECISION)) {
tgeDateClaimbleAmount = (userTotalClaimableAmount * 100) / 1000;
airdropEndTime = _calculmonth(10);
} else if (userTotalClaimableAmount > (50000 * PLX_ACC_PRECISION)) {
tgeDateClaimbleAmount = (userTotalClaimableAmount * 75) / 1000;
airdropEndTime = _calculmonth(12);
}
uint256 remainClaimableAmount = userTotalClaimableAmount - tgeDateClaimbleAmount;
uint256 perSecondClaimableToken = remainClaimableAmount / airdropEndTime;
uint256 claimableAmount;
if (block.timestamp >= TGETimestamp && block.timestamp < TGETimestamp + airdropEndTime) {
if (airdropUser.updateLastClaimTimestamp == 0) {
claimableAmount = tgeDateClaimbleAmount + ((block.timestamp - TGETimestamp) * perSecondClaimableToken) - userTotalClaimed;
} else {
claimableAmount = (block.timestamp - airdropUser.updateLastClaimTimestamp) * perSecondClaimableToken;
}
} else if (block.timestamp >= TGETimestamp + airdropEndTime) {
claimableAmount = userTotalClaimableAmount - userTotalClaimed;
} else {
revert OutofRange();
}
return claimableAmount;
}
function airdropUserClaimPlx() public whenNotPaused {
if (block.timestamp < claimStartTime) revert NotYet();
if (block.timestamp < TGETimestamp) revert NotYet();
User storage airdropUser = AirdropUserInfo[msg.sender];
if (airdropUser.updateLastClaimTimestamp == 0) {
airdropUser.userTotalClaimableAmount = IPlexusIDO_202311(plexusIDO).AirdropUserInfo(msg.sender).userTotalClaimableAmount;
airdropUser.userTotalClaimed = IPlexusIDO_202311(plexusIDO).AirdropUserInfo(msg.sender).userTotalClaimed;
if (airdropUser.userTotalClaimableAmount == 0) {
airdropUser.userTotalClaimableAmount = IPlexusIDO_202311(plexusIDO_202311).AirdropUserInfo(msg.sender).userTotalClaimableAmount;
airdropUser.userTotalClaimed = IPlexusIDO_202311(plexusIDO_202311).AirdropUserInfo(msg.sender).userTotalClaimed;
if (airdropUser.userTotalClaimableAmount == 0) {
airdropUser.userTotalClaimableAmount = IPlexusIDO_202311(plexusIDO_202311_old)
.AirdropUserInfo(msg.sender)
.userTotalClaimableAmount;
airdropUser.userTotalClaimed = IPlexusIDO_202311(plexusIDO_202311_old).AirdropUserInfo(msg.sender).userTotalClaimed;
}
}
}
uint256 claimableAmount = airdropUserClaimablePlx(msg.sender);
if (claimableAmount == 0) revert EmptyTokenClaim();
PLEXUS.safeTransfer(msg.sender, claimableAmount);
airdropUser.updateLastClaimTimestamp = block.timestamp;
airdropUser.userTotalClaimed += claimableAmount;
airdropTotalClaimed += claimableAmount;
}
function oldAirdropInfo(address user) public view returns (OldAirdrop.AirdropUser memory) {
return IPlexusIDO_202311(plexusIDO_202311).oldAirdropInfo(user);
}
function airdropUserInfo(address user) external view returns (uint256 total, uint256 claimable, uint256 claimed) {
User memory airdropUser = AirdropUserInfo[user];
if (airdropUser.updateLastClaimTimestamp == 0) {
claimed = IPlexusIDO_202311(plexusIDO).AirdropUserInfo(user).userTotalClaimed;
total = IPlexusIDO_202311(plexusIDO).AirdropUserInfo(user).userTotalClaimableAmount;
if (total == 0) {
claimed = IPlexusIDO_202311(plexusIDO_202311).AirdropUserInfo(user).userTotalClaimed;
total = IPlexusIDO_202311(plexusIDO_202311).AirdropUserInfo(user).userTotalClaimableAmount;
if (total == 0) {
claimed = IPlexusIDO_202311(plexusIDO_202311_old).AirdropUserInfo(user).userTotalClaimed;
total = IPlexusIDO_202311(plexusIDO_202311_old).AirdropUserInfo(user).userTotalClaimableAmount;
}
}
} else {
total = airdropUser.userTotalClaimableAmount;
claimed = airdropUser.userTotalClaimed;
}
claimable = airdropUserClaimablePlx(user);
}
function emergencyWithdraw() external onlyOwner {
uint256 length = signerList.length;
for (uint256 i; i < length; i++) {
if (confirmTime[signerList[i]] + 600 < block.timestamp) revert ExceedTime();
}
PLEXUS.safeTransfer(owner, callPlxBalance());
}
function setSigner(address[] memory _signer) external onlyOwner {
require(_signer.length >= 3);
for (uint256 i = 0; i < _signer.length; i++) {
signerList.push(_signer[i]);
}
}
function viewSigner() external view returns (address[] memory) {
return signerList;
}
function signerConfirm() external {
bool check;
uint256 length = signerList.length;
for (uint256 i; i < length; i++) {
if (msg.sender == signerList[i]) {
check = true;
break;
}
}
require(check);
confirmTime[msg.sender] = block.timestamp;
}
}
文件 6 的 7:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 7 的 7:SafeERC20.sol
pragma solidity ^0.8.0;
import "../interfaces/IERC20.sol";
import "./Address.sol";
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));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender) + 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));
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
{
"compilationTarget": {
"contracts/NewPlexusIDO_202311.sol": "NewPlexusIDO_202311"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_plxAddress","type":"address"},{"internalType":"address","name":"_plexusIDO","type":"address"},{"internalType":"address","name":"_plexusIDO_202311","type":"address"},{"internalType":"address","name":"_plexusIDO_202311_old","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EmptyTokenClaim","type":"error"},{"inputs":[],"name":"ExceedTime","type":"error"},{"inputs":[],"name":"NotYet","type":"error"},{"inputs":[],"name":"OutofRange","type":"error"},{"inputs":[],"name":"WholeClaimed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"ChangeOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTime","type":"uint256"}],"name":"ChangeTGEtime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claimTime","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"AIRDROP_TOTAL_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"AirdropUserInfo","outputs":[{"internalType":"uint256","name":"userTotalClaimableAmount","type":"uint256"},{"internalType":"uint256","name":"updateLastClaimTimestamp","type":"uint256"},{"internalType":"uint256","name":"userTotalClaimed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PLX_ACC_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TGETimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"airdropTotalClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"airdropUserClaimPlx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"airdropUserClaimablePlx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"airdropUserInfo","outputs":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"claimable","type":"uint256"},{"internalType":"uint256","name":"claimed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callPlxBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"oldAirdropInfo","outputs":[{"components":[{"internalType":"uint256","name":"airdropUserTotalClaimable","type":"uint256"},{"internalType":"uint256","name":"airdropUserTotalClaimed","type":"uint256"},{"internalType":"uint256","name":"airdropUpdateLastClaimTime","type":"uint256"}],"internalType":"struct OldAirdrop.AirdropUser","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseOnOff","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"plexusIDO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"plexusIDO_202311","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"plexusIDO_202311_old","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"plexusTotalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_claimStartTime","type":"uint256"}],"name":"setClaimStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_signer","type":"address[]"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signerConfirm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"viewSigner","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"}]