Contract Name:
Incubator_Booster
Contract Source Code:
/*
█▀ █▀█ █▄░█ █ █▀▀ █▀▀ ▄▀█ █▀▀ ▀█▀ █▀█ █▀█ █▄█
▄█ █▄█ █░▀█ █ █▄▄ █▀░ █▀█ █▄▄ ░█░ █▄█ █▀▄ ░█░
Trade on SonicFactory and have fun!
Web: https://sonicfactory.fun/
*/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "./interfaces/IERC20.sol";
import "./Ownable.sol";
interface IIncubator {
struct TokenDataView {
string name;
string symbol;
uint8 decimals;
uint24 maxBalance;
uint24 fee;
uint24 tax;
uint24 ref;
uint24 holders;
uint32 creation;
uint32 launch;
uint32 escaped;
uint112 ethReserveEscapeTarget;
uint112 ethReserveEscaped;
uint112 ethReserveVirtualInitial;
uint112 ethReserve;
uint112 tokenReserveInitial;
uint112 tokenReserve;
uint256 tokenReserveEscaped;
uint256 initialSupply;
uint256 totalSupply;
uint256 creationFee;
uint256 escapeFee;
address creator;
address referral;
address routerIncubator;
address pairIncubator;
address routerFinal;
}
function getTokenData(address token) external view returns (TokenDataView memory data);
}
contract Incubator_Booster is Ownable {
IIncubator private _INCUBATOR;
address private _TREASURY;
uint256 private _ethPrice;
uint256 private _tokenBoostCnt;
mapping(uint32 => uint256) private _boostPrice;
mapping(uint256 => TokenBoostData) private _tokenBoost;
struct TokenBoostData {
address token;
uint32 duration;
uint32 start;
uint256 price;
}
event TokenBoosted(address indexed token, uint32 start, uint32 duration, uint256 price);
event WithdrawnETH(address indexed to, uint256 value);
error ErrorUnknownToken(address token);
error ErrorTransfer(address to, uint256 value);
error ErrorInvalidRange();
error TokenInvalidBoostAmount();
error TokenInvalidBoostStart();
modifier isCreator(address token) {
IIncubator.TokenDataView memory tokenData = _INCUBATOR.getTokenData(token);
if (msg.sender != tokenData.creator) { revert ErrorUnauthorized(msg.sender); }
_;
}
constructor(address incubator) payable {
_INCUBATOR = IIncubator(incubator);
_transferOwnership(msg.sender);
unchecked {
_boostPrice[6*60*60] = 50 * 1 ether;
_boostPrice[12*60*60] = 90 * 1 ether;
_boostPrice[24*60*60] = 150 * 1 ether;
_boostPrice[48*60*60] = 250 * 1 ether;
}
}
function setIncubator(address incubator) external onlyOwner {
_INCUBATOR = IIncubator(incubator);
}
function setTreasury(address treasury) external onlyOwner {
_TREASURY = treasury;
}
function setEthPrice(uint256 value) external onlyOwner {
_ethPrice = value;
}
function setBoostDurationPrice(uint32 duration, uint256 price) external onlyOwner {
_boostPrice[duration] = price;
}
function getBoostDurationPrice(uint32 duration) external view returns (uint256) {
return _boostPrice[duration];
}
function boostToken(address token, uint32 duration) external payable isCreator(token) {
uint256 price = _boostPrice[duration];
uint256 value;
unchecked {
value = price * 1e18 / _ethPrice;
}
if (price == 0 || value > msg.value) { revert TokenInvalidBoostAmount(); }
if (_TREASURY != address(0)) {
(bool success,) = _TREASURY.call{ value: value }("");
if (!success) { revert ErrorTransfer(_TREASURY, value); }
}
uint32 start = _timestamp();
if (_tokenBoostCnt > 0) {
unchecked {
TokenBoostData memory lastTokenBoost = _tokenBoost[_tokenBoostCnt];
if (lastTokenBoost.start + lastTokenBoost.duration > start) { start = lastTokenBoost.start + lastTokenBoost.duration + 1; }
}
}
unchecked {
++_tokenBoostCnt;
}
TokenBoostData storage _newTokenBoost = _tokenBoost[_tokenBoostCnt];
_newTokenBoost.token = token;
_newTokenBoost.start = start;
_newTokenBoost.duration = duration;
_newTokenBoost.price = price;
emit TokenBoosted(token, start, duration, price);
}
function listBoostedTokens(uint256 offset, uint256 limit) external view returns (TokenBoostData[] memory) {
if (offset >= _tokenBoostCnt) { revert ErrorInvalidRange(); }
uint256 total;
unchecked {
if (offset + limit > _tokenBoostCnt) { limit = _tokenBoostCnt - offset; }
total = offset - limit;
}
TokenBoostData[] memory data = new TokenBoostData[](total);
unchecked {
uint256 j;
for (uint256 i = offset; i < limit; i++) {
TokenBoostData storage tokenBoostData = _tokenBoost[i];
data[j++] = TokenBoostData(tokenBoostData.token, tokenBoostData.start, tokenBoostData.duration, tokenBoostData.price);
}
}
return data;
}
function withdrawETH(address to, uint256 value) external onlyOwner {
(bool success,) = to.call{ value: value }("");
if (!success) { revert ErrorTransfer(to, value); }
emit WithdrawnETH(to, value);
}
function getEthPrice() external view returns (uint256) {
return _ethPrice;
}
function _timestamp() private view returns (uint32) {
unchecked {
return uint32(block.timestamp % 2**32);
}
}
receive() external payable {}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
abstract contract Ownable {
address internal _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
error ErrorUnauthorized(address sender);
modifier onlyOwner() {
if (msg.sender != _owner) { revert ErrorUnauthorized(msg.sender); }
_;
}
function renounceOwnership() external onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0));
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
function owner() external view returns (address) {
return _owner;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
interface IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function balanceOf(address account) external view returns (uint256);
function totalSupply() external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value) external returns (bool);
function burn(uint256 value) external returns (bool);
}