Contract Diff Checker

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);
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):