编译器
0.8.17+commit.8df45f5f
文件 1 的 6: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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 2 的 6: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 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 3 的 6:KomputaiLaunchpad.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./Ownable.sol";
import "./ReentrancyGuard.sol";
import "./Pausable.sol";
interface Staking {
function calculateTotalStakeAt(address user, uint256 timestamp) external view returns (uint256);
}
contract KomputaiLaunchpad is Ownable, ReentrancyGuard, Pausable {
mapping(address => uint256) public depositByUser;
address[] public participants;
uint256 public nbParticipants;
uint256 public totalRaised;
uint256 public opening = 1712329200;
Staking public stakingContract = Staking(0x74eEe699c1BBE2411481E7C52116E8FFe7655830);
IERC20 public insContract = IERC20(0xe9572938bcbf08adceE86Fd12A7C0D08dC4Ab841);
uint256 public hardcap;
uint256 public ethPrice;
event Deposited(address indexed user, uint256 amount);
constructor(uint256 _ethPrice, uint256 _usdHardcap) Ownable(msg.sender) {
ethPrice = _ethPrice;
hardcap = _usdHardcap * 1 ether / ethPrice;
}
receive() external payable {}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
function deposit() external payable nonReentrant whenNotPaused {
uint8 phase = getPhase();
require(phase > 0, "Not yet open");
require(totalRaised < hardcap, "Hardcap reached");
require(msg.value > 0, "Can't deposit 0");
require(msg.value <= hardcap - totalRaised, "Deposit larger than available");
uint256 availableAllocation = getAvailableAllocation(msg.sender, phase);
require(msg.value <= availableAllocation, "Deposit exceeds allocation");
if (depositByUser[msg.sender] == 0) {
participants.push(msg.sender);
nbParticipants += 1;
}
depositByUser[msg.sender] += msg.value;
totalRaised += msg.value;
emit Deposited(msg.sender, msg.value);
}
function open() external onlyOwner {
opening = block.timestamp;
}
function withdraw() external onlyOwner {
if (address(this).balance > 0)
payable(msg.sender).transfer(address(this).balance);
}
function getAvailableAllocation(address user, uint8 phase) public view returns (uint256 allocation) {
if (phase == 1) {
uint256 staked = stakingContract.calculateTotalStakeAt(user, block.timestamp);
allocation = getStakerAllocation(staked) - depositByUser[user];
} else if (phase == 2) {
uint256 staked = stakingContract.calculateTotalStakeAt(user, block.timestamp);
uint256 balance = insContract.balanceOf(user);
bool isStaker = staked > 0;
bool isHolder = balance > 0;
if (!isStaker && !isHolder) {
allocation = 0;
} else {
uint256 stakerAllocation = isStaker ? getStakerAllocation(staked) : 0;
uint256 holderAllocation = isHolder ? getHolderAllocation(balance) : 0;
allocation = stakerAllocation + holderAllocation - depositByUser[user];
}
} else if (phase == 3) {
allocation = 10 ether;
}
}
function getStakerAllocation(uint256 amount) public view returns (uint256 allocation) {
if (amount >= 50000 ether) allocation = 10000 ether / ethPrice;
else if (amount >= 10000 ether) allocation = 5000 ether / ethPrice;
else if (amount >= 5000 ether) allocation = 2500 ether / ethPrice;
else if (amount >= 2500 ether) allocation = 1250 ether / ethPrice;
else if (amount >= 500 ether) allocation = 250 ether / ethPrice;
else if (amount >= 100 ether) allocation = 60 ether / ethPrice;
else allocation = 0;
}
function getHolderAllocation(uint256 amount) public view returns (uint256 allocation) {
if (amount >= 50000 ether) allocation = 5000 ether / ethPrice;
else if (amount >= 10000 ether) allocation = 2500 ether / ethPrice;
else if (amount >= 5000 ether) allocation = 1250 ether / ethPrice;
else if (amount >= 2500 ether) allocation = 625 ether / ethPrice;
else if (amount >= 500 ether) allocation = 125 ether / ethPrice;
else if (amount >= 100 ether) allocation = 30 ether / ethPrice;
else allocation = 0;
}
function getPhase() public view returns (uint8 phase) {
if (block.timestamp < opening) {
return 0;
}
uint256 timeSinceOpening = block.timestamp - opening;
if (timeSinceOpening < 1 hours) {
return 1;
} else if (timeSinceOpening < 2 hours) {
return 2;
} else {
return 3;
}
}
}
文件 4 的 6:Ownable.sol
pragma solidity ^0.8.0;
import {Context} from "./Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 5 的 6:Pausable.sol
pragma solidity ^0.8.0;
import {Context} from "./Context.sol";
abstract contract Pausable is Context {
bool private _paused;
event Paused(address account);
event Unpaused(address account);
error EnforcedPause();
error ExpectedPause();
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 6 的 6:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
_status = ENTERED;
}
function _nonReentrantAfter() private {
_status = NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
{
"compilationTarget": {
"KomputaiLaunchpad.sol": "KomputaiLaunchpad"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 800
},
"remappings": []
}
[{"inputs":[{"internalType":"uint256","name":"_ethPrice","type":"uint256"},{"internalType":"uint256","name":"_usdHardcap","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposited","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":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"depositByUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint8","name":"phase","type":"uint8"}],"name":"getAvailableAllocation","outputs":[{"internalType":"uint256","name":"allocation","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getHolderAllocation","outputs":[{"internalType":"uint256","name":"allocation","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPhase","outputs":[{"internalType":"uint8","name":"phase","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getStakerAllocation","outputs":[{"internalType":"uint256","name":"allocation","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hardcap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"insContract","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbParticipants","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"open","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"opening","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":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingContract","outputs":[{"internalType":"contract Staking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRaised","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":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]