编译器
0.8.19+commit.7dd6d404
文件 1 的 4: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;
}
}
文件 2 的 4:IERC20.sol
pragma solidity ^0.8.0;
import "../token/ERC20/IERC20.sol";
文件 3 的 4:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 4 的 4:Presale.sol
pragma solidity ^0.8.0;
import "lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol";
import "lib/openzeppelin-contracts/contracts/access/Ownable.sol";
contract YeetPresale is Ownable {
bool public presaleStarted;
bool public presaleEnded;
mapping(address => uint256) public amountPurchased;
uint256 public totalPurchased;
address[] public participants;
uint256 public walletLimit = 0.2 ether;
uint256 public tokensPerEth = 80_000e18;
uint256 public hardCap = 10 ether;
address public tokenAddress;
event BoughtPresale(address indexed participant, uint256 ethAmount);
event Claimed(address indexed participant, uint256 tokenAmount);
function buyPresale() external payable {
require(presaleStarted, "Presale not started yet");
require(!presaleEnded, "Presale ended");
require(msg.value > 0, "Zero amount");
require(amountPurchased[msg.sender] + msg.value <= walletLimit, "Over wallet limit");
require(totalPurchased + msg.value <= hardCap, "Amount over limit");
if (amountPurchased[msg.sender] == 0) participants.push(msg.sender);
amountPurchased[msg.sender] += msg.value;
totalPurchased += msg.value;
emit BoughtPresale(msg.sender, msg.value);
}
function claim() external {
require(presaleEnded, "Not claimable");
require(amountPurchased[msg.sender] > 0, "No amount claimable");
require(tokenAddress != address(0), "Nothing to claim yet");
uint256 amount = amountPurchased[msg.sender] * tokensPerEth / 1e18;
amountPurchased[msg.sender] = 0;
IERC20(tokenAddress).transfer(msg.sender, amount);
emit Claimed(msg.sender, amount);
}
function startPresale(bool hasStarted) external onlyOwner {
presaleStarted = hasStarted;
}
function endPresale(bool hasEnded) external onlyOwner {
presaleEnded = hasEnded;
}
function setHardCap(uint256 _hardCap) external onlyOwner {
hardCap = _hardCap;
}
function setWalletLimit(uint256 _walletLimit) external onlyOwner {
walletLimit = _walletLimit;
}
function setTokensPerEth(uint256 _tokensPerEth) external onlyOwner {
tokensPerEth = _tokensPerEth;
}
function setTokenAddress(address _tokenAddress) external onlyOwner {
tokenAddress = _tokenAddress;
}
function withdrawEth() external onlyOwner {
uint256 totalAmount = address(this).balance;
(bool success,) = owner().call{value: totalAmount}("");
require(success);
}
function withdrawTokens(uint256 amount) external onlyOwner {
IERC20(tokenAddress).transfer(owner(), amount);
}
function refundEth() external onlyOwner {
uint256 participantCount = participants.length;
for (uint256 i = 0; i < participantCount;) {
uint256 ethAmount = amountPurchased[participants[i]];
amountPurchased[participants[i]] = 0;
(bool success,) = participants[i].call{value: ethAmount}("");
require(success);
unchecked {
i++;
}
}
}
function getParticipantsCount() public view returns (uint256 count) {
return participants.length;
}
}
{
"compilationTarget": {
"src/Presale.sol": "YeetPresale"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/",
"lib/forge-std:ds-test/=lib/forge-std/lib/ds-test/src/"
]
}
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"participant","type":"address"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"BoughtPresale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"participant","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"Claimed","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"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"amountPurchased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyPresale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"hasEnded","type":"bool"}],"name":"endPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getParticipantsCount","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hardCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"participants","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleEnded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refundEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_hardCap","type":"uint256"}],"name":"setHardCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"setTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokensPerEth","type":"uint256"}],"name":"setTokensPerEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_walletLimit","type":"uint256"}],"name":"setWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"hasStarted","type":"bool"}],"name":"startPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensPerEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPurchased","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":[],"name":"walletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]