编译器
0.8.20+commit.a1b79de6
文件 1 的 4:DigitalDumpsterPreSale.sol
pragma solidity ^0.8.20;
import "ReentrancyGuard.sol";
import "SafeMath.sol";
import "IERC20.sol";
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return payable(msg.sender);
}
function _msgData() internal view virtual returns (bytes memory) {
this;
return msg.data;
}
}
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
contract DigitalDumpsterPreSale is ReentrancyGuard, Ownable {
using SafeMath for uint256;
mapping(address => uint256) public _contributions;
mapping(address => uint256) public claimedTokens;
mapping(address => uint256) public lastClaimed;
IERC20 public _token;
uint256 private _tokenDecimals;
address payable public _wallet;
uint256 public startDate;
uint256 public startICODate;
uint256 public _weiRaised;
uint256 public minPurchase = 0.05 ether;
uint256 public maxPurchase = 0.5 ether;
uint256 public softCap = 30 ether;
uint256 public hardCap = 300 ether;
uint256 public availableTokensICO = 14000000 * (10**18);
uint256 public refundStartDate;
uint256 public endICO;
bool public startRefund = false;
mapping(address => bool) public airdropRecipients;
address[] public airdropAddresses;
uint256 public numRecipients;
event AirdropAdded(address indexed recipient);
event AirdropDistributed(address indexed recipient, uint256 amount);
event TokensPurchased(address purchaser, address beneficiary, uint256 value, uint256 amount);
event Refund(address recipient, uint256 amount);
modifier icoActive() {
require(endICO > 0 && block.timestamp >= startDate && block.timestamp < endICO, "ICO must be active");
_;
}
modifier icoNotActive() {
require(endICO == 0 || block.timestamp >= endICO, "ICO must not be active");
_;
}
modifier icoNotStarted() {
require(block.timestamp < startDate || startDate == 0, "ICO must not have started");
_;
}
constructor (
address payable wallet,
address tokenAddress,
uint256 tokenDecimals
) {
require(wallet != address(0), "Pre-Sale: wallet is the zero address");
require(tokenAddress != address(0), "Pre-Sale: token is the zero address");
_wallet = wallet;
_token = IERC20(tokenAddress);
_tokenDecimals = tokenDecimals;
}
receive () external payable {
if (endICO > 0 && block.timestamp < endICO) {
buyTokens(_msgSender());
} else {
endICO = 0;
revert('Pre-Sale is closed');
}
}
function startICO(uint _startDate, uint _endDate) external onlyOwner icoNotActive icoNotStarted {
require(_startDate > block.timestamp, 'start date should be in the future');
require(_endDate > _startDate, 'end date should be after start date');
startDate = _startDate;
endICO = _endDate;
_weiRaised = 0;
startRefund = false;
refundStartDate = 0;
availableTokensICO = _token.balanceOf(address(this));
}
function stopICO() external onlyOwner {
require(endICO != 0, "ICO is already stopped");
endICO = 0;
if (_weiRaised >= softCap) {
_forwardFunds();
} else {
startRefund = true;
refundStartDate = block.timestamp;
}
}
function buyTokens(address beneficiary) public nonReentrant icoActive payable {
uint256 weiAmount = msg.value;
_preValidatePurchase(beneficiary, weiAmount);
uint256 tokens = _getTokenAmount(weiAmount);
_weiRaised = _weiRaised.add(weiAmount);
availableTokensICO = availableTokensICO.sub(tokens);
_contributions[beneficiary] = _contributions[beneficiary].add(weiAmount);
emit TokensPurchased(_msgSender(), beneficiary, weiAmount, tokens);
}
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
require(beneficiary != address(0), "Crowdsale: beneficiary is the zero address");
require(weiAmount != 0, "Crowdsale: weiAmount is 0");
require(weiAmount >= minPurchase, 'have to send at least: minPurchase');
require(_contributions[beneficiary].add(weiAmount) <= maxPurchase, 'can\'t buy more than: maxPurchase');
require((_weiRaised.add(weiAmount)) <= hardCap, 'Hard Cap reached');
require(block.timestamp >= startDate && block.timestamp <= endICO, "ICO is not active");
}
function claimTokens() public nonReentrant icoNotActive returns (bool) {
require(claimedTokens[msg.sender] < totalAllocation(msg.sender), "Already claimed all allocation");
require(lastClaimed[msg.sender] + 1 days <= block.timestamp, "Must wait 24 hours between claims");
uint256 totalTokensForSale = 14000000 * (10**18);
uint256 userContribution = _contributions[msg.sender];
uint256 totalTokensPurchasedByUser = totalTokensForSale.mul(userContribution).div(_weiRaised);
uint256 tokensRemaining = totalTokensPurchasedByUser.sub(claimedTokens[msg.sender]);
require(tokensRemaining > 0, "No tokens left to claim");
uint256 percentToClaim;
if (claimedTokens[msg.sender] == 0) {
percentToClaim = 50;
} else {
percentToClaim = 10;
}
uint256 tokensToClaim = totalTokensPurchasedByUser.mul(percentToClaim).div(100);
claimedTokens[msg.sender] = claimedTokens[msg.sender].add(tokensToClaim);
lastClaimed[msg.sender] = block.timestamp;
bool sent = _token.transfer(msg.sender, tokensToClaim);
require(sent, "Token transfer failed");
return true;
}
function canClaim(address user) public view returns (bool) {
return (lastClaimed[user] + 1 days <= block.timestamp);
}
function claimedAll(address user) public view returns (bool) {
return (claimedTokens[user] >= totalAllocation(user));
}
function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
return weiAmount.mul(_weiRaised).div(10 ** _tokenDecimals);
}
bool private fundsForwarded = false;
function _forwardFunds() internal {
_wallet.transfer(_weiRaised);
uint256 totalTokens = _token.balanceOf(address(this));
uint256 tokensToOwner = totalTokens.mul(48).div(100);
_token.transfer(_wallet, tokensToOwner);
fundsForwarded = true;
}
function claimActive() public view returns (bool) {
return fundsForwarded && _weiRaised >= softCap;
}
function checkContribution(address addr) public view returns(uint256) {
return _contributions[addr];
}
function setAvailableTokens(uint256 amount) public onlyOwner icoNotActive {
availableTokensICO = amount;
}
function weiRaised() public view returns (uint256) {
return _weiRaised;
}
function setWalletReceiver(address payable newWallet) external onlyOwner {
_wallet = newWallet;
}
function setHardCap(uint256 value) external onlyOwner {
hardCap = value;
}
function setSoftCap(uint256 value) external onlyOwner {
softCap = value;
}
function setMaxPurchase(uint256 value) external onlyOwner {
maxPurchase = value;
}
function setMinPurchase(uint256 value) external onlyOwner {
minPurchase = value;
}
function isICOActive() public view returns (bool) {
return endICO > 0 && block.timestamp >= startDate && block.timestamp < endICO;
}
function totalAllocation(address user) public view returns (uint256) {
uint256 totalTokensForSale = 14000000 * (10 ** 18);
uint256 userContribution = _contributions[user];
return totalTokensForSale.mul(userContribution).div(_weiRaised);
}
function unclaimedTokens(address user) public view returns (uint256) {
uint256 totalTokensForSale = 14000000 * (10 ** 18);
uint256 userContribution = _contributions[user];
uint256 totalTokensPurchasedByUser = totalTokensForSale.mul(userContribution).div(_weiRaised);
uint256 tokensRemaining = totalTokensPurchasedByUser.sub(claimedTokens[user]);
return tokensRemaining;
}
function claimedTokensAmount(address user) public view returns (uint256) {
return claimedTokens[user];
}
function takeTokens(IERC20 tokenAddress) public onlyOwner icoNotActive returns (bool) {
IERC20 tokenBEP = tokenAddress;
uint256 tokenAmt = tokenBEP.balanceOf(address(this));
require(tokenAmt > 0, 'BEP-20 balance is 0');
bool sent = tokenBEP.transfer(_wallet, tokenAmt);
require(sent, "Token transfer failed");
return true;
}
function refundMe() public icoNotActive {
require(startRefund == true, 'no refund available');
uint256 amount = _contributions[msg.sender];
if (address(this).balance >= amount) {
_contributions[msg.sender] = 0;
if (amount > 0) {
address payable recipient = payable(msg.sender);
recipient.transfer(amount);
emit Refund(msg.sender, amount);
}
}
}
function addAirdropRecipients(address[] memory recipients) public onlyOwner {
for (uint256 i = 0; i < recipients.length; i++) {
if (!airdropRecipients[recipients[i]]) {
airdropRecipients[recipients[i]] = true;
airdropAddresses.push(recipients[i]);
numRecipients++;
emit AirdropAdded(recipients[i]);
}
}
}
function distributeAirdrop() public onlyOwner {
require(numRecipients > 0, "No recipients for airdrop");
uint256 totalAirdrop = 560000 * 10 ** _tokenDecimals;
require(_token.balanceOf(address(this)) >= totalAirdrop, "Insufficient tokens for airdrop");
uint256 amountPerRecipient = totalAirdrop.div(numRecipients);
for (uint256 i = 0; i < airdropAddresses.length; i++) {
if (airdropRecipients[airdropAddresses[i]]) {
_token.transfer(airdropAddresses[i], amountPerRecipient);
emit AirdropDistributed(airdropAddresses[i], amountPerRecipient);
airdropRecipients[airdropAddresses[i]] = false;
}
}
delete airdropAddresses;
numRecipients = 0;
}
}
文件 2 的 4:IERC20.sol
pragma solidity ^0.8.0;
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);
}
文件 3 的 4:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
文件 4 的 4:SafeMath.sol
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
{
"compilationTarget": {
"DigitalDumpsterPreSale.sol": "DigitalDumpsterPreSale"
},
"evmVersion": "shanghai",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address payable","name":"wallet","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenDecimals","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"AirdropAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AirdropDistributed","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":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"purchaser","type":"address"},{"indexed":false,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensPurchased","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_contributions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_wallet","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_weiRaised","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"addAirdropRecipients","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"airdropAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"airdropRecipients","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"availableTokensICO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary","type":"address"}],"name":"buyTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"canClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"checkContribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"claimedAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"claimedTokensAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributeAirdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endICO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hardCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isICOActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numRecipients","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refundMe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"refundStartDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setAvailableTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setHardCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setMaxPurchase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setMinPurchase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setSoftCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newWallet","type":"address"}],"name":"setWalletReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"softCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startDate","type":"uint256"},{"internalType":"uint256","name":"_endDate","type":"uint256"}],"name":"startICO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startICODate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startRefund","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stopICO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"tokenAddress","type":"address"}],"name":"takeTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"totalAllocation","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":"address","name":"user","type":"address"}],"name":"unclaimedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weiRaised","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]