// SPDX-License-Identifier: MIT
//
//      ___         ___         ___      ___         ___         ___
//     /\  \       /\  \       /\  \    /\  \       /\  \       /\__\
//    /::\  \     /::\  \     /::\  \   \:\  \     /::\  \     /:/  /
//   /:/\:\  \   /:/\:\  \   /:/\:\  \   \:\  \   /:/\:\  \   /:/  /
//  /::\~\:\  \ /:/  \:\  \ /::\~\:\  \  /::\  \ /::\~\:\  \ /:/  /
// /:/\:\ \:\__/:/__/ \:\__/:/\:\ \:\__\/:/\:\__/:/\:\ \:\__/:/__/
// \/__\:\/:/  \:\  \ /:/  \/_|::\/:/  /:/  \/__\/__\:\/:/  \:\  \
//      \::/  / \:\  /:/  /   |:|::/  /:/  /         \::/  / \:\  \
//       \/__/   \:\/:/  /    |:|\/__/\/__/          /:/  /   \:\  \
//                \::/  /     |:|  |                /:/  /     \:\__\
//                 \/__/       \|__|                \/__/       \/__/
//
pragma solidity 0.8.23;

import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
import {ReentrancyGuard} from "openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol";
import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";

error ZeroAddress();
error ZeroBalance();

contract PortalPreSale is Ownable, ReentrancyGuard {
    address public constant PROCESSING_ADDRESS = 0x8603E8e5dF0C79C32f59785e89255a4518436485;
    address public withdrawAddress = 0xc238153C6a742dE9029927859868d106e44Ffe76;

    constructor(address owner) Ownable(owner) {}

    receive() external payable {}

    fallback() external payable {}

    function setWithdrawAddress(address newWithdrawAddress) external onlyOwner {
        if (newWithdrawAddress == address(0)) revert ZeroAddress();
        withdrawAddress = newWithdrawAddress;
    }

    function calculateDistribution(uint256 totalAmount) internal pure returns (uint256, uint256) {
        uint256 amountForProcessing = totalAmount / 100;
        uint256 amountForWithdrawal = totalAmount - amountForProcessing;
        return (amountForWithdrawal, amountForProcessing);
    }

    function withdrawETH() external onlyOwner nonReentrant {
        if (withdrawAddress == address(0)) revert ZeroAddress();
        uint256 balance = address(this).balance;
        if (balance == 0) revert ZeroBalance();
        (uint256 withdrawAmount, uint256 processingAmount) = calculateDistribution(balance);
        payable(PROCESSING_ADDRESS).transfer(processingAmount);
        payable(withdrawAddress).transfer(withdrawAmount);
    }

    function withdrawERC20(address tokenAddress) external onlyOwner nonReentrant {
        if (withdrawAddress == address(0)) revert ZeroAddress();
        uint256 balance = IERC20(tokenAddress).balanceOf(address(this));
        if (IERC20(tokenAddress).balanceOf(address(this)) == 0) revert ZeroBalance();
        (uint256 withdrawAmount, uint256 processingAmount) = calculateDistribution(balance);
        IERC20(tokenAddress).transfer(PROCESSING_ADDRESS, processingAmount);
        IERC20(tokenAddress).transfer(withdrawAddress, withdrawAmount);
    }
}
[{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroBalance","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"PROCESSING_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newWithdrawAddress","type":"address"}],"name":"setWithdrawAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]