creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "OperaDAO.sol": {
        "content": "pragma solidity ^0.8.17;\n\n//SPDX-License-Identifier: MIT\n//This contract is used to vote on which token liquidity pools to be returned.\nimport \"ERC20.sol\";\nimport \"OperaFactory.sol\";\n\ncontract OperaDAO {\n    address public owner;\n    address public sonataFactoryAddress;\n    address public sonataTokenAddress =\n        0xCefdE37817da4FC51dDc24e3820ad316784Ee04b;\n\n    uint64 public lobbyCount = 1;\n    uint64 public voteTime = 86400;\n    uint64 public cooldownTimer = 604800;\n    uint64 public delayTimer = 86400;\n    mapping(uint64 => uint256) public tokenIdVoteTimer;\n    mapping(uint64 => VoteState) public tokenIdVoteState;\n    mapping(uint64 => uint64) public tokenIdVoteLobby;\n    mapping(uint64 => uint64) public lobbyVoterCount;\n    mapping(uint64 => mapping(uint64 => Vote)) public votingLobbyToPositionVote;\n    mapping(address => mapping(uint256 => bool))\n        public voterAlreadyVotedForLobby;\n    mapping(address => bool) public nonVoter;\n\n    struct Vote {\n        address voter;\n        bool vote;\n    }\n    enum VoteState {\n        NOTINITIATED,\n        VOTING,\n        COOLDOWN,\n        REMOVELPDELAY,\n        COMPLETED\n    }\n    event tokenVoteStateChanged(\n        uint64 tokenId,\n        uint64 lobbyId,\n        uint256 blocktime,\n        VoteState state\n    );\n    event voteEmitted(address voter, uint64 lobbyId, uint64 tokenId, bool vote);\n    event voteCounted(\n        address voter,\n        uint64 tokenId,\n        uint64 lobbyId,\n        uint256 amount\n    );\n\n    constructor() {\n        owner = msg.sender;\n    }\n\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"only owner\");\n        _;\n    }\n\n    function setFactoryAddress(address factory) external onlyOwner {\n        sonataFactoryAddress = factory;\n    }\n\n    function updateVoterStatus(address voter, bool state) external onlyOwner {\n        nonVoter[voter] = state;\n    }\n\n    function setTimers(\n        uint64 cooldown,\n        uint64 delay,\n        uint64 _voteTime\n    ) external onlyOwner {\n        require(cooldown <= 604800, \"No more than 1 week\");\n        require(delay <= 86400, \"No more than 1 day\");\n        require(_voteTime <= 86400, \"No more than 1 day\");\n        cooldownTimer = cooldown;\n        delayTimer = delay;\n        voteTime = _voteTime;\n    }\n\n    function startTimer(uint64 tokenId, uint64 time) external {\n        require(\n            msg.sender == sonataFactoryAddress,\n            \"Only the factory can start a timer for a token.\"\n        );\n        tokenIdVoteTimer[tokenId] = time;\n        tokenIdVoteState[tokenId] = VoteState.COOLDOWN;\n        emit tokenVoteStateChanged(\n            tokenId,\n            0,\n            block.timestamp,\n            VoteState.COOLDOWN\n        );\n    }\n\n    function startVoteForTokenId(uint64 id) external {\n        require(\n            tokenIdVoteState[id] == VoteState.COOLDOWN,\n            \"Voting needs to be in cooldown.\"\n        );\n        require(\n            tokenIdVoteTimer[id] > 0 && tokenIdVoteTimer[id] <= block.timestamp,\n            \"Still on cooldown.\"\n        );\n        tokenIdVoteTimer[id] = block.timestamp;\n        tokenIdVoteState[id] = VoteState.VOTING;\n        tokenIdVoteLobby[id] = lobbyCount;\n        lobbyCount += 1;\n        emit tokenVoteStateChanged(\n            id,\n            tokenIdVoteLobby[id],\n            block.timestamp,\n            VoteState.VOTING\n        );\n    }\n\n    function voteForId(uint64 id, bool vote) external {\n        require(tokenIdVoteState[id] == VoteState.VOTING, \"Voting not enabled\");\n        require(!nonVoter[msg.sender], \"You cannot vote.\");\n        uint64 lobbyId = tokenIdVoteLobby[id];\n        require(\n            voterAlreadyVotedForLobby[msg.sender][lobbyId] == false,\n            \"You already voted\"\n        );\n        voterAlreadyVotedForLobby[msg.sender][lobbyId] = true;\n        uint64 voterCount = lobbyVoterCount[lobbyId];\n        votingLobbyToPositionVote[lobbyId][voterCount] = Vote(msg.sender, vote);\n        lobbyVoterCount[lobbyId] += 1;\n        emit voteEmitted(msg.sender, lobbyId, id, vote);\n    }\n\n    function completeVote(uint64 id) external {\n        require(\n            tokenIdVoteState[id] == VoteState.VOTING,\n            \"Not currently voting.\"\n        );\n        require(\n            tokenIdVoteTimer[id] + voteTime <= block.timestamp,\n            \"Voting in effect.\"\n        );\n\n        if (getVoteResult(tokenIdVoteLobby[id], id)) {\n            tokenIdVoteState[id] = VoteState.REMOVELPDELAY;\n            tokenIdVoteTimer[id] = block.timestamp + delayTimer;\n            emit tokenVoteStateChanged(\n                id,\n                tokenIdVoteLobby[id],\n                block.timestamp,\n                VoteState.REMOVELPDELAY\n            );\n        } else {\n            tokenIdVoteState[id] = VoteState.COOLDOWN;\n            tokenIdVoteTimer[id] = block.timestamp + cooldownTimer;\n            OperaFactory factory = OperaFactory(payable(sonataFactoryAddress));\n            factory.increaseLockTime(id, cooldownTimer + voteTime);\n            emit tokenVoteStateChanged(\n                id,\n                tokenIdVoteLobby[id],\n                block.timestamp,\n                VoteState.COOLDOWN\n            );\n        }\n    }\n\n    function getVoteResult(\n        uint64 lobbyId,\n        uint64 tokenId\n    ) internal returns (bool) {\n        ERC20 sonataToken = ERC20(payable(sonataTokenAddress));\n\n        uint256 voteFor;\n        uint256 voteAgainst;\n        Vote memory tempVote;\n        uint256 tempVoteAmount;\n        for (uint64 i = 0; i < lobbyVoterCount[lobbyId]; i++) {\n            tempVote = votingLobbyToPositionVote[lobbyId][i];\n            tempVoteAmount = sonataToken.balanceOf(tempVote.voter);\n            if (tempVote.vote) {\n                voteFor += tempVoteAmount;\n            } else {\n                voteAgainst += tempVoteAmount;\n            }\n            emit voteCounted(tempVote.voter, tokenId, lobbyId, tempVoteAmount);\n        }\n        uint256 totalVotes = voteFor + voteAgainst;\n        uint256 voteThreshhold = (totalVotes * 60) / 100;\n        if (voteFor >= voteThreshhold) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    function removeTokenLP(uint64 id) external {\n        require(\n            tokenIdVoteState[id] == VoteState.REMOVELPDELAY,\n            \"Not in remove lp State.\"\n        );\n        require(\n            tokenIdVoteTimer[id] <= block.timestamp,\n            \"Delay still in effect.\"\n        );\n        tokenIdVoteState[id] = VoteState.COMPLETED;\n        emit tokenVoteStateChanged(\n            id,\n            tokenIdVoteLobby[id],\n            block.timestamp,\n            VoteState.COMPLETED\n        );\n        OperaFactory factory = OperaFactory(payable(sonataFactoryAddress));\n        factory.claimLiquidityFromLockerWithId(id);\n        bool removedLP = factory.removeLiquidity(id);\n        require(removedLP, \"Failed to removed liquidity\");\n    }\n}\n"
      },
      "ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport \"IERC20.sol\";\nimport \"Context.sol\";\n\n\n\ninterface IERC20Metadata is IERC20 {\n    function name() external view returns (string memory);\n    function symbol() external view returns (string memory);\n    function decimals() external view returns (uint8);\n}\nlibrary SafeMath {\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n        return c;\n    }\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return sub(a, b, \"SafeMath: subtraction overflow\");\n    }\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        uint256 c = a - b;\n        return c;\n    }\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n        return c;\n    }\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return div(a, b, \"SafeMath: division by zero\");\n    }\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b > 0, errorMessage);\n        uint256 c = a / b;\n        return c;\n    }\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return mod(a, b, \"SafeMath: modulo by zero\");\n    }\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b != 0, errorMessage);\n        return a % b;\n    }\n}\nabstract contract ERC20 is Context, IERC20, IERC20Metadata {\n    using SafeMath for uint256;\n    mapping(address => uint256) private _balances;\n    mapping(address => mapping(address => uint256)) private _allowances;\n    uint256 private _totalSupply;\n    string private _name;\n    string private _symbol;\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n    function name() public view virtual override returns (string memory) {return _name;}\n    function symbol() public view virtual override returns (string memory) {return _symbol;}\n    function decimals() public view virtual override returns (uint8) {return 9;}\n    function totalSupply() public view virtual override returns (uint256) {return _totalSupply;}\n    function balanceOf(address account) public view virtual override returns (uint256) {return _balances[account];}\n    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(_msgSender(), recipient, amount);\n        return true;\n    }\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        _approve(_msgSender(), spender, amount);\n        return true;\n    }\n    function setNameAndSymbol(string memory nameInput, string memory symbolInput) internal {\n        _name = nameInput;\n        _symbol = symbolInput;\n    }\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) public virtual override returns (bool) {\n        _transfer(sender, recipient, amount);\n        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n        return true;\n    }\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n        return true;\n    }\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n        return true;\n    }\n    function _transfer(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) internal virtual {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n        _beforeTokenTransfer(sender, recipient, amount);\n        _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n        _balances[recipient] = _balances[recipient].add(amount);\n        emit Transfer(sender, recipient, amount);\n    }\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n        _beforeTokenTransfer(address(0), account, amount);\n        _totalSupply = _totalSupply.add(amount);\n        _balances[account] = _balances[account].add(amount);\n        emit Transfer(address(0), account, amount);\n    }\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n        _beforeTokenTransfer(account, address(0), amount);\n        _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n        _totalSupply = _totalSupply.sub(amount);\n        emit Transfer(account, address(0), amount);\n    }\n    function _approve(\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\n}"
      },
      "IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IERC20 {\n    function totalSupply() external view returns (uint256);\n    function balanceOf(address account) external view returns (uint256);\n    function transfer(address recipient, uint256 amount) external returns (bool);\n    function allowance(address owner, address spender) external view returns (uint256);\n    function approve(address spender, uint256 amount) external returns (bool);\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\n\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        this; \n        return msg.data;\n    }\n}"
      },
      "OperaFactory.sol": {
        "content": "pragma solidity ^0.8.17;\n\n//SPDX-License-Identifier: MIT\nimport \"OperaToken.sol\";\nimport \"OperaRevenue.sol\";\nimport \"WETH.sol\";\nimport \"OperaLendingPool.sol\";\nimport \"OperaLocker.sol\";\nimport \"OperaDAO.sol\";\nimport \"IERC20.sol\";\n\n// import \"Math.sol\";\n\ncontract OperaFactory {\n\n    uint256 public feePerEth = 1 * 10 ** 16;\n    uint256 public minBorrowUnits = 9;\n\n    uint256 public _tokenDecimals = 1 * 10 ** 17;\n    uint256 public tokenDeployedCount;\n    uint256 public baseFee = 5 * 10 ** 16;\n    uint256 public lockTime = 1;\n    address public owner;\n\n    address public WETHAddress = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n    address public operaRewardAddress;\n    address public operaPoolAddress;\n    address public operaLockerAddress;\n    address public operaDAOAddress;\n\n    mapping(uint256 => address) public tokenCountToAddress;\n    mapping(uint256 => uint256) public initialLiquidityFromTokenCount;\n\n    IDEXRouter public router;\n\n    event feeChanged(uint256 amount);\n    event tokenDeployed(\n        address user,\n        address token,\n        uint256 amountEth,\n        uint256 tokenCount,\n        uint256 blocktime,\n        string[] stringData,\n        uint256[] uintData,\n        address[] addressData\n    );\n\n    constructor(address[] memory _addressData) {\n        owner = msg.sender;\n        operaRewardAddress = _addressData[0];\n        operaPoolAddress = _addressData[1];\n        operaLockerAddress = _addressData[2];\n        operaDAOAddress = _addressData[3];\n\n        router = IDEXRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);\n    }\n\n    modifier onlyOwner() {\n        require(owner == msg.sender, \"only owner\");\n        _;\n    }\n    modifier onlyDAO() {\n        require(\n            operaDAOAddress == msg.sender || msg.sender == owner,\n            \"only dao\"\n        );\n        _;\n    }\n\n    function changeAddresses(address[] memory _addressData) external onlyOwner {\n        operaRewardAddress = _addressData[0];\n        operaPoolAddress = _addressData[1];\n        operaLockerAddress = _addressData[2];\n        operaDAOAddress = _addressData[3];\n    }\n\n    function updateFeePerEth(uint256 amount) external onlyOwner {\n        feePerEth = amount;\n        emit feeChanged(amount);\n    }\n\n    function updateBaseFee(uint256 amount) external onlyOwner {\n        baseFee = amount;\n    }\n    function updateMinBorrow(uint256 amount) external onlyOwner {\n        minBorrowUnits = amount;\n    }\n\n    function updateLockTime(uint256 amount) external onlyOwner {\n        require(amount <= 259200, \"Locktime cannot be more than 3 days.\");\n        lockTime = amount;\n    }\n\n    function emitDeployedEvent(\n        address token,\n        uint256 amount,\n        string[] memory _stringData,\n        address[] memory _addressData,\n        uint256[] memory _intData\n    ) internal {\n        emit tokenDeployed(\n            msg.sender,\n            token,\n            amount,\n            tokenDeployedCount,\n            block.timestamp,\n            _stringData,\n            _intData,\n            _addressData\n        );\n    }\n\n    function deployToken(\n        string[] memory _stringData,\n        address[] memory _addressData,\n        uint256[] memory _intData,\n        uint256 _amountEthToBorrow\n    ) external payable returns (address) {\n        require(_intData.length == 11, \"Int List needs 11 int inputs\");\n        if (_intData[9] == 1 && _intData[10] == 1) {\n            require(_amountEthToBorrow > minBorrowUnits, \"Cannot deploy with less than minimum liquidity.\");\n            require(_amountEthToBorrow % 10 == 0, \"Must borrow full ethers.\");\n            uint256 feeEmountEth = _amountEthToBorrow * feePerEth;\n            require(feeEmountEth == msg.value, \"Send enough to cover the fee\");\n        } else {\n            require(_amountEthToBorrow == 0, \"Cannot borrow liquidity\");\n            require(baseFee == msg.value, \"Send enough to cover the fee\");\n        }\n        \n        OperaToken deployedToken = new OperaToken(\n            _stringData,\n            _addressData,\n            _intData,\n            operaRewardAddress\n        );\n        deployedToken.createPair();\n        if (_amountEthToBorrow > 0) {\n            uint256 tokenAmount = deployedToken.balanceOf(address(this));\n            deployedToken.approve(address(router), tokenAmount);\n            OperaPool lender = OperaPool(payable(operaPoolAddress));\n            lender.borrowEth(_amountEthToBorrow);\n            router.addLiquidityETH{value: _amountEthToBorrow * _tokenDecimals}(\n                address(deployedToken),\n                tokenAmount,\n                0,\n                0,\n                address(this),\n                block.timestamp + 1\n            );\n            lockLPTokens(deployedToken.pair());\n            OperaDAO daoContract = OperaDAO(payable(operaDAOAddress));\n            daoContract.startTimer(\n                uint64(tokenDeployedCount),\n                uint64(block.timestamp + lockTime)\n            );\n        } else {\n            uint256 tokenAmount = deployedToken.balanceOf(address(this));\n            deployedToken.transfer(msg.sender, tokenAmount);\n        }\n\n        tokenCountToAddress[tokenDeployedCount] = address(deployedToken);\n        initialLiquidityFromTokenCount[tokenDeployedCount] = _amountEthToBorrow;\n\n        OperaRevenue rewardContract = OperaRevenue(payable(operaRewardAddress));\n\n        rewardContract.recieveRewards{value: msg.value}();\n\n        emitDeployedEvent(\n            address(deployedToken),\n            _amountEthToBorrow,\n            _stringData,\n            _addressData,\n            _intData\n        );\n        tokenDeployedCount += 1;\n        deployedToken.transferOwnership(payable(msg.sender));\n        return address(deployedToken);\n    }\n\n    function lockLPTokens(address tokenPair) internal {\n        OperaLocker locker = OperaLocker(payable(operaLockerAddress));\n        IERC20 lpToken = IERC20(tokenPair);\n        uint256 curBalance = lpToken.balanceOf(address(this));\n        lpToken.approve(operaLockerAddress, curBalance);\n        locker.lockTokens(tokenPair, curBalance, lockTime);\n    }\n\n    function increaseLockTime(uint256 id, uint256 timer) external onlyDAO {\n        address tokenAddress = tokenCountToAddress[id];\n        OperaToken deployedToken = OperaToken(payable(tokenAddress));\n        OperaLocker locker = OperaLocker(payable(operaLockerAddress));\n        locker.increaseLockTime(deployedToken.pair(), timer);\n    }\n\n    function claimLiquidityFromLockerWithId(\n        uint256 tokenId\n    ) external payable onlyDAO {\n        address tokenAddress = tokenCountToAddress[tokenId];\n        OperaToken deployedToken = OperaToken(payable(tokenAddress));\n        OperaLocker locker = OperaLocker(payable(operaLockerAddress));\n        uint256 tokenAmount = locker.getAddressLockedTokens(\n            address(this),\n            deployedToken.pair()\n        );\n        locker.withdrawTokenAmount(deployedToken.pair(), tokenAmount);\n    }\n\n    function removeLiquidity(uint256 tokenId) external onlyDAO returns (bool) {\n        address tokenAddress = tokenCountToAddress[tokenId];\n        OperaToken deployedToken = OperaToken(payable(tokenAddress));\n        IERC20 lpToken = IERC20(deployedToken.pair());\n        lpToken.approve(address(router), lpToken.balanceOf(address(this)));\n        (uint256 amountA, uint256 amountB) = router.removeLiquidity(\n            tokenAddress,\n            WETHAddress,\n            lpToken.balanceOf(address(this)),\n            0,\n            0,\n            address(this),\n            block.timestamp + 1\n        );\n        if (msg.sender != owner) {\n            IWETH wethContract = IWETH(payable(WETHAddress));\n            wethContract.withdraw(amountB);\n            uint256 extraLP;\n            extraLP =\n                amountB -\n                (initialLiquidityFromTokenCount[tokenId] * _tokenDecimals);\n\n            OperaRevenue rewardContract = OperaRevenue(\n                payable(operaRewardAddress)\n            );\n            rewardContract.recieveRewards{value: extraLP}();\n            OperaPool poolContract = OperaPool(payable(operaPoolAddress));\n            poolContract.returnLentEth{\n                value: initialLiquidityFromTokenCount[tokenId] * _tokenDecimals\n            }(initialLiquidityFromTokenCount[tokenId]);\n        }\n\n        return true;\n    }\n\n    receive() external payable {}\n\n    function rescueToken(address token) external onlyOwner {\n        IERC20 tokenToRescue = IERC20(token);\n        tokenToRescue.transfer(owner, tokenToRescue.balanceOf(address(this)));\n    }\n\n    function withdraw() external onlyOwner {\n        payable(owner).transfer(address(this).balance);\n    }\n}\n"
      },
      "OperaToken.sol": {
        "content": "pragma solidity ^0.8.17;\n//SPDX-License-Identifier: MIT\n\nimport \"ERC20.sol\";\nimport \"IDEXRouter.sol\";\nimport \"IDEXFactory.sol\";\nimport \"Ownable.sol\";\nimport \"OperaRevenue.sol\";\n\n//This Token was deployed using the Opera Protocol\n//The Opera Protocol is a token deployer with the ability to deploy using borrowed initial liquidity\n//This token can be configured at construction to have NO taxes or to HAVE taxes\n//If the taxable variable (this cannot be updated after deployment) is true then this token is taxed\n//If the borrowedLP variable (this cannot be updated after deployment) is true then the max tax is 10% buy / sell, otherwise the max can be 50% buy / sell\n//Swap Threshold must be between 0.2% and 5% of supply, only if the token is taxable\n//The Opera Dao will control the LP tokens for tokens that borrow Liquidity\n\ncontract OperaToken is ERC20, Ownable {\n    using SafeMath for uint256;\n\n    string _telegram;\n    string _website;\n\n    uint8 constant _decimals = 9;\n\n    uint256 public _totalSupply;\n\n    uint256 public _maxWalletToken;\n    uint256 public _swapThreshold;\n\n    uint256 public _operaTax;\n    uint256 public _marketingBuyTax;\n    uint256 public _marketingSellTax;\n    uint256 public _devBuyTax;\n    uint256 public _devSellTax;\n    uint256 public _liquidityBuyTax;\n    uint256 public _liquiditySellTax;\n\n    mapping(address => uint256) _balances;\n    mapping(address => mapping(address => uint256)) _allowances;\n    mapping(address => bool) isFeeExempt;\n    mapping(address => bool) isMaxExempt;\n\n    address public pair;\n\n    address public routerAddress = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;\n    address public _devAddress;\n    address public _marketingAddress;\n    address public OperaRevenueAddress;\n    address public OperaFactoryAddress;\n\n    address public WETHAddress = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n\n    IDEXRouter public router;\n\n    bool inSwap;\n    bool public taxable;\n    bool public borrowedLP;\n    modifier swapping() {\n        inSwap = true;\n        _;\n        inSwap = false;\n    }\n    event AutoLiquify(uint256 amountETH, uint256 amountCoin);\n\n    constructor(\n        string[] memory _stringData,\n        address[] memory _addressData,\n        uint256[] memory _intData,\n        address rewardsAddress\n    ) ERC20(\"\",\"\") {\n        require(_stringData.length == 4, \"String List needs 4 string inputs\");\n        require(\n            _addressData.length == 2,\n            \"Address List needs 2 address inputs\"\n        );\n        require(_intData.length == 11, \"Int List needs 11 int inputs\");\n        if (_intData[9] == 1) {\n            taxable = true;\n        }\n        if (_intData[10] == 1 && _intData[9] == 1) {\n            borrowedLP = true;\n        }\n        OperaRevenueAddress = rewardsAddress;\n        OperaFactoryAddress = msg.sender;\n        router = IDEXRouter(routerAddress);\n\n        setNameAndSymbol(_stringData[0],_stringData[1]);\n        _telegram = _stringData[2];\n        _website = _stringData[3];\n\n        require(_intData[0] > 0 && _intData[0] < 999999999999999999);\n        _totalSupply = _intData[0] * 10 ** _decimals;\n        _balances[msg.sender] = _totalSupply;\n        emit Transfer(address(0), msg.sender, _totalSupply);\n\n        _maxWalletToken = (_totalSupply * _intData[1]) / 1000;\n\n        isFeeExempt[msg.sender] = true;\n        if (taxable) {\n            _devAddress = _addressData[0];\n            _marketingAddress = _addressData[1];\n            _swapThreshold = (_totalSupply * _intData[2]) / 1000;\n            _marketingBuyTax = _intData[3];\n            _marketingSellTax = _intData[4];\n            _devBuyTax = _intData[5];\n            _devSellTax = _intData[6];\n            _liquidityBuyTax = _intData[7];\n            _liquiditySellTax = _intData[8];\n            if (borrowedLP) {\n                if (getTotalTax() > 192) {\n                    _operaTax = 20;\n                } else {\n                    _operaTax = 4;\n                }\n            } else {\n                _operaTax = 2;\n            }\n\n            require(\n                _swapThreshold <= (_totalSupply / 20) &&\n                    _swapThreshold >= (_totalSupply / 500),\n                \"Swap Threshold must be less than 5% of total supply, or greater than 0.2%.\"\n            );\n            require(getSellTax() <= 500, \"Sell tax can't be greater than 50%.\");\n            require(getBuyTax() <= 500, \"Buy tax can't be greater than 50%.\");\n            require(\n                _devAddress != address(0) && _marketingAddress != address(0),\n                \"Reciever wallets can't be Zero address.\"\n            );\n        }\n\n        _allowances[address(this)][address(router)] = _totalSupply;\n\n        require(\n            _maxWalletToken >= (_totalSupply / 500),\n            \"Max Wallet must be greater than 0.2%.\"\n        );\n    }\n\n    receive() external payable {}\n    function createPair() public {\n        require(pair == address(0),\"Pair already created.\");\n        pair = IDEXFactory(router.factory()).createPair(\n            router.WETH(),\n            address(this)\n        );\n    }\n    function totalSupply() public view override returns (uint256) {\n        return _totalSupply;\n    }\n    \n    function balanceOf(address account) public view override returns (uint256) {\n        return _balances[account];\n    }\n\n    function allowance(\n        address holder,\n        address spender\n    ) public view override returns (uint256) {\n        return _allowances[holder][spender];\n    }\n\n    function approve(\n        address spender,\n        uint256 amount\n    ) public override returns (bool) {\n        _allowances[msg.sender][spender] = amount;\n        emit Approval(msg.sender, spender, amount);\n        return true;\n    }\n\n    function approveMax(address spender) external returns (bool) {\n        return approve(spender, _totalSupply);\n    }\n\n    function transfer(\n        address recipient,\n        uint256 amount\n    ) public override returns (bool) {\n        if (owner() == msg.sender) {\n            return _basicTransfer(msg.sender, recipient, amount);\n        } else {\n            return _transferFrom(msg.sender, recipient, amount);\n        }\n    }\n\n    function _basicTransfer(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) internal returns (bool) {\n        _balances[sender] = _balances[sender].sub(\n            amount,\n            \"Insufficient Balance\"\n        );\n        _balances[recipient] = _balances[recipient].add(amount);\n        emit Transfer(sender, recipient, amount);\n        return true;\n    }\n\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) public override returns (bool) {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n        if (_allowances[sender][msg.sender] != _totalSupply) {\n            _allowances[sender][msg.sender] = _allowances[sender][msg.sender]\n                .sub(amount, \"Insufficient Allowance\");\n        }\n        return _transferFrom(sender, recipient, amount);\n    }\n\n    function _transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) internal returns (bool) {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n        if (inSwap) {\n            return _basicTransfer(sender, recipient, amount);\n        }\n\n        checkLimits(sender, recipient, amount);\n        if (shouldTokenSwap(recipient)) {\n            tokenSwap();\n        }\n\n        _balances[sender] = _balances[sender].sub(\n            amount,\n            \"Insufficient Balance\"\n        );\n        uint256 amountReceived = (taxable &&\n            (recipient == pair || sender == pair))\n            ? takeFee(sender, recipient, amount)\n            : amount;\n\n        _balances[recipient] = _balances[recipient].add(amountReceived);\n\n        emit Transfer(sender, recipient, amountReceived);\n        return true;\n    }\n\n    function takeFee(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) internal returns (uint256) {\n        if (isFeeExempt[sender] || isFeeExempt[recipient]) {\n            return amount;\n        }\n        if (sender == address(this)) {\n            return amount;\n        }\n        if (sender == routerAddress || recipient == routerAddress) {\n            return amount;\n        }\n        if (recipient == OperaFactoryAddress) {\n            return amount;\n        }\n        uint256 _totalFee;\n\n        _totalFee = (recipient == pair) ? getSellTax() : getBuyTax();\n\n        uint256 feeAmount = amount.mul(_totalFee).div(1000);\n\n        _balances[address(this)] = _balances[address(this)].add(feeAmount);\n\n        emit Transfer(sender, address(this), feeAmount);\n\n        return amount.sub(feeAmount);\n    }\n\n    function getBuyTax() public view returns (uint) {\n        return _liquidityBuyTax + _devBuyTax + _marketingBuyTax + _operaTax;\n    }\n\n    function getSellTax() public view returns (uint) {\n        return _liquiditySellTax + _devSellTax + _marketingSellTax + _operaTax;\n    }\n\n    function getTotalTax() public view returns (uint) {\n        return getSellTax() + getBuyTax();\n    }\n\n    function setTaxes(\n        uint256 _marketingBuyPercent,\n        uint256 _marketingSellPercent,\n        uint256 _devBuyPercent,\n        uint256 _devSellPercent,\n        uint256 _liquidityBuyPercent,\n        uint256 _liquiditySellPercent\n    ) external onlyOwner {\n        require(inSwap == false, \"Cannot call when in swap\");\n        require(taxable, \"This token has no taxes.\");\n        uint256 amount = _balances[address(this)];\n        if (_operaTax == 20) {\n            if (amount > 0) {\n                tokenSwap();\n            }\n\n            _operaTax = 4;\n        }\n        _marketingBuyTax = _marketingBuyPercent;\n        _liquidityBuyTax = _liquidityBuyPercent;\n        _devBuyTax = _devBuyPercent;\n        _marketingSellTax = _marketingSellPercent;\n        _liquiditySellTax = _liquiditySellPercent;\n        _devSellTax = _devSellPercent;\n        require(\n            getBuyTax() <= (borrowedLP ? 100 : 500),\n            \"Buy tax can't be greater than 10% if borrowed lp and 50% if not.\"\n        );\n        require(\n            getSellTax() <= (borrowedLP ? 100 : 500),\n            \"Sell tax can't be greater than 10% if borrowed lp and 50% if not.\"\n        );\n    }\n\n    function tokenSwap() internal swapping {\n        uint256 amount = _balances[address(this)];\n\n        uint256 amountToLiquify = (_liquidityBuyTax + _liquiditySellTax > 0)\n            ? amount\n                .mul(_liquidityBuyTax + _liquiditySellTax)\n                .div(getTotalTax())\n                .div(2)\n            : 0;\n\n        uint256 amountToSwap = amount.sub(amountToLiquify);\n\n        address[] memory path = new address[](2);\n        path[0] = address(this);\n        path[1] = WETHAddress;\n\n        uint256 balanceBefore = address(this).balance;\n\n        router.swapExactTokensForETHSupportingFeeOnTransferTokens(\n            amountToSwap,\n            0,\n            path,\n            address(this),\n            block.timestamp\n        );\n\n        bool tmpSuccess;\n\n        uint256 amountETH = address(this).balance.sub(balanceBefore);\n        uint256 totalETHFee = (_liquidityBuyTax + _liquiditySellTax > 0)\n            ? getTotalTax().sub((_liquidityBuyTax + _liquiditySellTax).div(2))\n            : getTotalTax();\n\n        uint256 amountETHLiquidity = amountETH\n            .mul(_liquidityBuyTax + _liquiditySellTax)\n            .div(totalETHFee)\n            .div(2);\n        if (_devBuyTax + _devSellTax > 0) {\n            uint256 amountETHDev = amountETH.mul(_devBuyTax + _devSellTax).div(\n                totalETHFee\n            );\n            (tmpSuccess, ) = payable(_devAddress).call{\n                value: amountETHDev,\n                gas: 100000\n            }(\"\");\n            tmpSuccess = false;\n        }\n\n        if (_marketingBuyTax + _marketingSellTax > 0) {\n            uint256 amountETHMarketing = amountETH\n                .mul(_marketingBuyTax + _marketingSellTax)\n                .div(totalETHFee);\n            (tmpSuccess, ) = payable(_marketingAddress).call{\n                value: amountETHMarketing,\n                gas: 100000\n            }(\"\");\n            tmpSuccess = false;\n        }\n\n        if (amountToLiquify > 0) {\n            address liqAddress = borrowedLP\n                ? OperaFactoryAddress\n                : _marketingAddress;\n            router.addLiquidityETH{value: amountETHLiquidity}(\n                address(this),\n                amountToLiquify,\n                0,\n                0,\n                liqAddress,\n                block.timestamp\n            );\n            emit AutoLiquify(amountETHLiquidity, amountToLiquify);\n        }\n        uint256 operaFee = amountETH.mul(_operaTax.mul(2)).div(totalETHFee);\n\n        OperaRevenue rewardContract = OperaRevenue(\n            payable(OperaRevenueAddress)\n        );\n        rewardContract.recieveRewards{value: operaFee}();\n    }\n\n    function shouldTokenSwap(address recipient) internal view returns (bool) {\n        return ((recipient == pair) &&\n            taxable &&\n            !inSwap &&\n            _balances[address(this)] >= _swapThreshold);\n    }\n\n    function checkLimits(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) internal view {\n        if (\n            !isMaxExempt[recipient] &&\n            recipient != address(this) &&\n            sender != address(this) &&\n            recipient != 0x000000000000000000000000000000000000dEaD &&\n            recipient != pair &&\n            recipient != _marketingAddress &&\n            recipient != _devAddress &&\n            recipient != OperaFactoryAddress\n        ) {\n            uint256 heldTokens = balanceOf(recipient);\n            require(\n                (heldTokens + amount) <= _maxWalletToken,\n                \"Total Holding is currently limited, you can not buy that much.\"\n            );\n        }\n    }\n\n    function setMaxWallet(uint256 percent) external onlyOwner {\n        require(inSwap == false, \"Cannot call when in swap\");\n        _maxWalletToken = (_totalSupply * percent) / 1000;\n        require(\n            _maxWalletToken >= (_totalSupply / 500),\n            \"Max Wallet must be greater than 0.2%.\"\n        );\n    }\n\n    function setTokenSwapSettings(uint256 percent) external onlyOwner {\n        require(inSwap == false, \"Cannot call when in swap\");\n        require(taxable, \"This token has no taxes.\");\n        _swapThreshold = (_totalSupply * percent) / 1000;\n        require(\n            _swapThreshold <= (_totalSupply / 20) &&\n                _swapThreshold >= (_totalSupply / 500),\n            \"Swap Threshold must be less than 5% of total supply, or greater than 0.2%.\"\n        );\n    }\n\n    function aboutMe() external view returns (string memory, string memory) {\n        return (_telegram, _website);\n    }\n\n    function updateAboutMe(\n        string memory telegram,\n        string memory website\n    ) external onlyOwner {\n        _telegram = telegram;\n        _website = website;\n    }\n\n    function setAddresses(\n        address marketingAddress,\n        address devAddress\n    ) external onlyOwner {\n        require(inSwap == false, \"Cannot call when in swap\");\n        require(taxable, \"This token has no taxes.\");\n        if (marketingAddress != address(0)) {\n            _marketingAddress = marketingAddress;\n        }\n        if (devAddress != address(0)) {\n            _devAddress = devAddress;\n        }\n\n        require(\n            _devAddress != address(0) && _marketingAddress != address(0),\n            \"Reciever wallets can't be Zero address.\"\n        );\n    }\n\n    function setFeeExemption(address user, bool status) external onlyOwner {\n        isFeeExempt[user] = status;\n    }\n    function setMaxExemption(address user, bool status) external onlyOwner {\n        isMaxExempt[user] = status;\n    }\n\n    function clearStuckBalance() external onlyOwner {\n        require(inSwap == false, \"Cannot call when in swap\");\n        payable(msg.sender).transfer(address(this).balance);\n    }\n}\n"
      },
      "IDEXRouter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IDEXRouter {\n    function factory() external pure returns (address);\n\n    function WETH() external pure returns (address);\n\n    function removeLiquidity(\n        address tokenA,\n        address tokenB,\n        uint liquidity,\n        uint amountAMin,\n        uint amountBMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountA, uint amountB);\n\n    function addLiquidity(\n        address tokenA,\n        address tokenB,\n        uint256 amountADesired,\n        uint256 amountBDesired,\n        uint256 amountAMin,\n        uint256 amountBMin,\n        address to,\n        uint256 deadline\n    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);\n\n    function addLiquidityETH(\n        address token,\n        uint256 amountTokenDesired,\n        uint256 amountTokenMin,\n        uint256 amountETHMin,\n        address to,\n        uint256 deadline\n    )\n        external\n        payable\n        returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);\n\n    function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n        uint256 amountIn,\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external;\n\n    function swapExactETHForTokensSupportingFeeOnTransferTokens(\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external payable;\n\n    function swapExactTokensForETHSupportingFeeOnTransferTokens(\n        uint256 amountIn,\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external;\n\n    function quote(\n        uint256 amountA,\n        uint256 reserveA,\n        uint256 reserveB\n    ) external pure returns (uint256 amountB);\n\n    function getAmountOut(\n        uint256 amountIn,\n        uint256 reserveIn,\n        uint256 reserveOut\n    ) external pure returns (uint256 amountOut);\n\n    function getAmountIn(\n        uint256 amountOut,\n        uint256 reserveIn,\n        uint256 reserveOut\n    ) external pure returns (uint256 amountIn);\n\n    function getAmountsOut(\n        uint256 amountIn,\n        address[] calldata path\n    ) external view returns (uint256[] memory amounts);\n\n    function getAmountsIn(\n        uint256 amountOut,\n        address[] calldata path\n    ) external view returns (uint256[] memory amounts);\n}\n"
      },
      "IDEXFactory.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IDEXFactory {\n    function createPair(\n        address tokenA,\n        address tokenB\n    ) external returns (address pair);\n}\n"
      },
      "Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport \"Context.sol\";\ncontract Ownable is Context {\n    address private _owner;\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n    constructor () {\n        address msgSender = _msgSender();\n        _owner = msgSender;\n        emit OwnershipTransferred(address(0), msgSender);\n    }\n    function owner() public view returns (address) {return _owner;}\n    modifier onlyOwner() {\n        require(_owner == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n    function renounceOwnership() public virtual onlyOwner {\n        emit OwnershipTransferred(_owner, address(0));\n        _owner = address(0);\n    }\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        emit OwnershipTransferred(_owner, newOwner);\n        _owner = newOwner;\n    }\n}"
      },
      "OperaRevenue.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ncontract OperaRevenue {\n    address public owner;\n    \n    event revenueReceived(\n        address account,\n        uint256 amount,\n        uint256 blocktime\n    );\n\n    constructor() {\n        owner = msg.sender;\n    }\n\n    modifier onlyOwner() {\n        require(owner == msg.sender, \"only owner\");\n        _;\n    }\n\n    function withdraw() external onlyOwner {\n        payable(owner).transfer(address(this).balance);\n    }\n\n\n    function getAddressBalance(address _address) public view returns (uint256) {\n        return _address.balance;\n    }\n\n    receive() external payable {}\n\n    function recieveRewards() external payable {\n        emit revenueReceived(msg.sender, msg.value, block.timestamp);\n    }\n}\n"
      },
      "WETH.sol": {
        "content": "pragma solidity ^0.8.17;\n\n//SPDX-License-Identifier: MIT\ninterface IWETH {\n    function deposit() external payable;\n\n    function transfer(address to, uint value) external returns (bool);\n\n    function withdraw(uint) external;\n}\n"
      },
      "OperaLendingPool.sol": {
        "content": "pragma solidity ^0.8.17;\n//SPDX-License-Identifier: MIT\nimport \"Auth.sol\";\nimport \"IERC20.sol\";\n\ncontract OperaPool is Auth {\n    uint256 public totalEthLent;\n    uint256 public totalAvailableEth;\n    uint256 public numberOfLenders;\n    uint256 public borrowLimit = 30;\n    uint256 public _tokenDecimals = 1 * 10 ** 17;\n    bool public borrowingEnable = true;\n    mapping(address => uint256) public usersCurrentLentAmount;\n    mapping(uint256 => address) public lenderIdToAddress;\n    mapping(address => uint256) public lenderAddressToId;\n    mapping(address => bool) public authorizedFactoryAddresses;\n\n    event ethMoved(\n        address account,\n        uint256 amount,\n        uint256 code,\n        uint256 blocktime\n    ); // 1 lent 2 borrowed 3 returned 4 withdrawn\n\n    event factoryStatusChange(address factoryAddress, bool status);\n\n    constructor() Auth(msg.sender) {}\n\n    modifier onlyFactoryAuthorized() {\n        require(\n            authorizedFactoryAddresses[msg.sender],\n            \"only factory contracts can borrow eth\"\n        );\n        _;\n    }\n\n    function updateFactoryAuthorization(\n        address addy,\n        bool status\n    ) external onlyOwner {\n        authorizedFactoryAddresses[addy] = status;\n        emit factoryStatusChange(addy, status);\n    }\n\n    function updateBorrowLimit(uint256 limit) external onlyOwner {\n        borrowLimit = limit;\n    }\n    function updateUnitDecimals(uint256 amount) external onlyOwner {\n        _tokenDecimals = amount;\n    }\n\n    function updateBorrowingEnabled(bool status) external onlyOwner {\n        borrowingEnable = status;\n    }\n\n    function lendForAddress(address addy) external payable returns (bool) {\n        require(\n            msg.value > 0 && msg.value % _tokenDecimals == 0,\n            \"Only send full ether.\"\n        );\n        if (lenderAddressToId[addy] == 0) {\n            lenderAddressToId[addy] = numberOfLenders + 1;\n            lenderIdToAddress[numberOfLenders + 1] = addy;\n            numberOfLenders += 1;\n        }\n        uint256 amountReceived = msg.value / _tokenDecimals;\n        emit ethMoved(addy, amountReceived, 1, block.timestamp);\n        totalEthLent += amountReceived;\n\n        usersCurrentLentAmount[addy] += amountReceived;\n        totalAvailableEth += amountReceived;\n\n        return true;\n    }\n\n    receive() external payable {}\n\n    function lendEth() external payable returns (bool) {\n        require(\n            msg.value > 0 && msg.value % _tokenDecimals == 0,\n            \"Only send full ether.\"\n        );\n        if (lenderAddressToId[msg.sender] == 0) {\n            lenderAddressToId[msg.sender] = numberOfLenders + 1;\n            lenderIdToAddress[numberOfLenders + 1] = msg.sender;\n            numberOfLenders += 1;\n        }\n        uint256 amountReceived = msg.value / _tokenDecimals;\n        emit ethMoved(msg.sender, amountReceived, 1, block.timestamp);\n        totalEthLent += amountReceived;\n\n        usersCurrentLentAmount[msg.sender] += amountReceived;\n        totalAvailableEth += amountReceived;\n\n        return true;\n    }\n\n    function borrowEth(uint256 _amount) external onlyFactoryAuthorized {\n        require(_amount <= totalAvailableEth, \"Not Enough eth to borrow\");\n        require(_amount > 0, \"Cannot borrow 0\");\n        require(borrowingEnable, \"Borrowing is not enabled.\");\n        require(_amount <= borrowLimit, \"Can't borrow that much.\");\n        totalAvailableEth -= _amount;\n        payable(msg.sender).transfer(_amount * _tokenDecimals);\n        emit ethMoved(msg.sender, _amount, 2, block.timestamp);\n    }\n\n    function returnLentEth(uint256 amountEth) external payable returns (bool) {\n        require(\n            (amountEth * _tokenDecimals) - msg.value == 0,\n            \"Did not send enough eth.\"\n        );\n\n        emit ethMoved(msg.sender, amountEth, 3, block.timestamp);\n        totalAvailableEth += amountEth;\n\n        return true;\n    }\n\n    function withdrawLentEth(uint256 _amountEther) external payable {\n        require(\n            usersCurrentLentAmount[msg.sender] >= _amountEther,\n            \"You Did not lend that much.\"\n        );\n\n        require(_amountEther > 0, \"Cant withdraw 0.\");\n        require(_amountEther <= totalAvailableEth, \"Not enough eth available.\");\n        if (usersCurrentLentAmount[msg.sender] == _amountEther) {\n            uint256 tempIdOfUser = lenderAddressToId[msg.sender];\n            address addressOfLastUser = lenderIdToAddress[numberOfLenders];\n            if (addressOfLastUser != msg.sender) {\n                delete lenderAddressToId[msg.sender];\n                lenderAddressToId[addressOfLastUser] = tempIdOfUser;\n                lenderIdToAddress[tempIdOfUser] = addressOfLastUser;\n                delete lenderIdToAddress[numberOfLenders];\n                numberOfLenders -= 1;\n            } else {\n                delete lenderAddressToId[msg.sender];\n                delete lenderIdToAddress[tempIdOfUser];\n                numberOfLenders -= 1;\n            }\n        }\n        usersCurrentLentAmount[msg.sender] -= _amountEther;\n        totalAvailableEth -= _amountEther;\n        totalEthLent -= _amountEther;\n        payable(msg.sender).transfer(_amountEther * _tokenDecimals);\n        emit ethMoved(msg.sender, _amountEther, 4, block.timestamp);\n    }\n\n    //safe gaurd so no funds get locked\n    function withdraw(uint256 amount) external onlyOwner {\n        payable(owner).transfer(amount);\n    }\n\n    function rescueToken(address token, uint256 amount) external onlyOwner {\n        IERC20 tokenToRescue = IERC20(token);\n        tokenToRescue.transfer(owner, amount);\n    }\n\n    function removeExcess() external payable onlyOwner {\n        require(\n            address(this).balance > totalAvailableEth * _tokenDecimals,\n            \"There is no excess eth\"\n        );\n        uint256 excessAmount = address(this).balance -\n            (totalAvailableEth * _tokenDecimals);\n        payable(owner).transfer(excessAmount);\n    }\n}\n"
      },
      "Auth.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nabstract contract Auth {\n    address internal owner;\n    mapping(address => bool) internal authorizations;\n\n    constructor(address _owner) {\n        owner = _owner;\n        authorizations[_owner] = true;\n    }\n\n    modifier onlyOwner() {\n        require(isOwner(msg.sender), \"!OWNER\");\n        _;\n    }\n\n    modifier authorized() {\n        require(isAuthorized(msg.sender), \"!AUTHORIZED\");\n        _;\n    }\n\n    function authorize(address adr) public onlyOwner {\n        authorizations[adr] = true;\n    }\n\n    function unauthorize(address adr) public onlyOwner {\n        authorizations[adr] = false;\n    }\n\n    function isOwner(address account) public view returns (bool) {\n        return account == owner;\n    }\n\n    function isAuthorized(address adr) public view returns (bool) {\n        return authorizations[adr];\n    }\n\n    function transferOwnership(address payable adr) public onlyOwner {\n        owner = adr;\n        authorizations[adr] = true;\n        emit OwnershipTransferred(adr);\n    }\n\n    event OwnershipTransferred(address owner);\n}\n"
      },
      "OperaLocker.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\n\nimport \"IERC20.sol\";\n\n\ncontract OperaLocker {\n    address public owner;\n    mapping(address => bool) public lockDisabled;\n\n    mapping(address => mapping(address => uint256)) public accountsLockedTokens;\n    mapping(address => mapping(address => uint256))\n        public accountsLockedTimeOfToken;\n\n    event tokenLocked(\n        address account,\n        address token,\n        uint256 amount,\n        uint256 locktime\n    );\n    event tokenWithdrawn(address account, address token, uint256 amount);\n\n    constructor() {\n        owner = msg.sender;\n    }\n\n    modifier onlyOwner() {\n        require(owner == msg.sender, \"only owner\");\n        _;\n    }\n\n    function getAddressLockedTokens(\n        address user,\n        address token\n    ) public view returns (uint256) {\n        return accountsLockedTokens[user][token];\n    }\n\n    function changeLockEnabled(bool locked, address addy) external onlyOwner {\n        lockDisabled[addy] = locked;\n    }\n\n    function getAddressLockedTime(\n        address user,\n        address token\n    ) public view returns (uint256) {\n        return accountsLockedTimeOfToken[user][token];\n    }\n\n    function withdrawTokenAmount(\n        address tokenAddress,\n        uint256 amount\n    ) external {\n        if (!lockDisabled[tokenAddress]) {\n            require(\n                accountsLockedTimeOfToken[msg.sender][tokenAddress] > 0 &&\n                    accountsLockedTimeOfToken[msg.sender][tokenAddress] <=\n                    block.timestamp,\n                \"Tokens are not ready to be unlocked.\"\n            );\n        }\n\n        require(\n            accountsLockedTokens[msg.sender][tokenAddress] >= amount,\n            \"You did not lock this many tokens.\"\n        );\n        if (accountsLockedTokens[msg.sender][tokenAddress] == amount) {\n            accountsLockedTimeOfToken[msg.sender][tokenAddress] = 0; //resetting timer for lock to indicate no tokens locked\n        }\n        accountsLockedTokens[msg.sender][tokenAddress] -= amount;\n        IERC20 tokenToLock = IERC20(tokenAddress);\n        uint256 balanceBefore = tokenToLock.balanceOf(address(this));\n        tokenToLock.transfer(msg.sender, amount);\n        uint256 balanceAfter = tokenToLock.balanceOf(address(this));\n        require(\n            balanceBefore - amount == balanceAfter,\n            \"Failed to transfer amount of tokens when withdrawing.\"\n        );\n        emit tokenWithdrawn(msg.sender, tokenAddress, amount);\n    }\n\n    function lockTokens(\n        address tokenAddress,\n        uint256 amount,\n        uint256 locktimeInSeconds\n    ) external {\n        require(\n            accountsLockedTimeOfToken[msg.sender][tokenAddress] == 0,\n            \"You already have this tocken locked.\"\n        );\n        // require(amount > 0, \"Cannot Lock 0 tokens\");\n        IERC20 tokenToLock = IERC20(tokenAddress);\n        uint256 balanceBefore = tokenToLock.balanceOf(address(this));\n        tokenToLock.transferFrom(msg.sender, address(this), amount);\n        uint256 balanceAfter = tokenToLock.balanceOf(address(this));\n        require(\n            balanceAfter - amount == balanceBefore,\n            \"Failed to transfer amount of tokens when locking.\"\n        );\n        accountsLockedTokens[msg.sender][tokenAddress] = amount;\n        accountsLockedTimeOfToken[msg.sender][tokenAddress] =\n            block.timestamp +\n            locktimeInSeconds;\n        emit tokenLocked(\n            msg.sender,\n            tokenAddress,\n            accountsLockedTokens[msg.sender][tokenAddress],\n            block.timestamp + locktimeInSeconds\n        );\n    }\n\n    function increaseLockTime(\n        address tokenAddress,\n        uint256 increasedSeconds\n    ) external {\n        require(\n            accountsLockedTimeOfToken[msg.sender][tokenAddress] > 0,\n            \"You have no tokens locked.\"\n        );\n        require(increasedSeconds > 0, \"Cannot Lock 0 seconds\");\n        accountsLockedTimeOfToken[msg.sender][tokenAddress] += increasedSeconds;\n        emit tokenLocked(\n            msg.sender,\n            tokenAddress,\n            accountsLockedTokens[msg.sender][tokenAddress],\n            accountsLockedTimeOfToken[msg.sender][tokenAddress]\n        );\n    }\n\n    function increaseTokenAmount(\n        address tokenAddress,\n        uint256 amount\n    ) external {\n        require(\n            accountsLockedTimeOfToken[msg.sender][tokenAddress] > 0,\n            \"You have no tokens locked.\"\n        );\n        require(amount > 0, \"Cannot Lock 0 tokens\");\n        IERC20 tokenToLock = IERC20(tokenAddress);\n        uint256 balanceBefore = tokenToLock.balanceOf(address(this));\n        tokenToLock.transferFrom(msg.sender, address(this), amount);\n        uint256 balanceAfter = tokenToLock.balanceOf(address(this));\n        require(\n            balanceAfter - amount == balanceBefore,\n            \"Failed to transfer amount of tokens when locking.\"\n        );\n        accountsLockedTokens[msg.sender][tokenAddress] += amount;\n        emit tokenLocked(\n            msg.sender,\n            tokenAddress,\n            accountsLockedTokens[msg.sender][tokenAddress],\n            accountsLockedTimeOfToken[msg.sender][tokenAddress]\n        );\n    }\n\n    function withdraw() external onlyOwner {\n        payable(owner).transfer(address(this).balance);\n    }\n\n    function emergencyRescue(address token, uint256 amount) external onlyOwner {\n        IERC20 tokenToRescue = IERC20(token);\n        tokenToRescue.transfer(owner, amount);\n    }\n\n    receive() external payable {}\n}\n"
      },
      "Math.sol": {
        "content": "/// math.sol -- mixin for inline numerical wizardry\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity >0.4.13;\n\ncontract DSMath {\n    function add(uint x, uint y) internal pure returns (uint z) {\n        require((z = x + y) >= x, \"ds-math-add-overflow\");\n    }\n\n    function sub(uint x, uint y) internal pure returns (uint z) {\n        require((z = x - y) <= x, \"ds-math-sub-underflow\");\n    }\n\n    function mul(uint x, uint y) internal pure returns (uint z) {\n        require(y == 0 || (z = x * y) / y == x, \"ds-math-mul-overflow\");\n    }\n\n    function min(uint x, uint y) internal pure returns (uint z) {\n        return x <= y ? x : y;\n    }\n\n    function max(uint x, uint y) internal pure returns (uint z) {\n        return x >= y ? x : y;\n    }\n\n    function imin(int x, int y) internal pure returns (int z) {\n        return x <= y ? x : y;\n    }\n\n    function imax(int x, int y) internal pure returns (int z) {\n        return x >= y ? x : y;\n    }\n\n    uint constant WAD = 10 ** 18;\n    uint constant RAY = 10 ** 27;\n\n    //rounds to zero if x*y < WAD / 2\n    function wmul(uint x, uint y) internal pure returns (uint z) {\n        z = add(mul(x, y), WAD / 2) / WAD;\n    }\n\n    //rounds to zero if x*y < WAD / 2\n    function rmul(uint x, uint y) internal pure returns (uint z) {\n        z = add(mul(x, y), RAY / 2) / RAY;\n    }\n\n    //rounds to zero if x*y < WAD / 2\n    function wdiv(uint x, uint y) internal pure returns (uint z) {\n        z = add(mul(x, WAD), y / 2) / y;\n    }\n\n    //rounds to zero if x*y < RAY / 2\n    function rdiv(uint x, uint y) internal pure returns (uint z) {\n        z = add(mul(x, RAY), y / 2) / y;\n    }\n\n    // This famous algorithm is called \"exponentiation by squaring\"\n    // and calculates x^n with x as fixed-point and n as regular unsigned.\n    //\n    // It's O(log n), instead of O(n) for naive repeated multiplication.\n    //\n    // These facts are why it works:\n    //\n    //  If n is even, then x^n = (x^2)^(n/2).\n    //  If n is odd,  then x^n = x * x^(n-1),\n    //   and applying the equation for even x gives\n    //    x^n = x * (x^2)^((n-1) / 2).\n    //\n    //  Also, EVM division is flooring and\n    //    floor[(n-1) / 2] = floor[n / 2].\n    //\n    function rpow(uint x, uint n) internal pure returns (uint z) {\n        z = n % 2 != 0 ? x : RAY;\n\n        for (n /= 2; n != 0; n /= 2) {\n            x = rmul(x, x);\n\n            if (n % 2 != 0) {\n                z = rmul(z, x);\n            }\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "evmVersion": "istanbul",
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "libraries": {
        "OperaDAO.sol": {}
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}