// SPDX-License-Identifier: MIT

pragma solidity ^0.7.6;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./SafeMath.sol";

contract AccessControl is Ownable, ReentrancyGuard {
    using SafeMath for uint256;

    address public constant ZERO_ADDRESS = address(0);
    address[] public admins;
    
    // fix rate swap switch 
    bool public isFRSwapOn = true;

    // dex swap switch
    bool public isSwapOn = true;

    constructor() {
        setAdmin(_msgSender());
    }

    modifier onlyAdmin() {
        bool isAdmin;

        for (uint i; i<admins.length; i++) {
            if (msg.sender == admins[i]) {
                isAdmin = true;
            }
        }
        require(isAdmin, "Invalid Admin: caller is not the admin");
        _;
    }

    modifier notZeroAddr(address addr_) {
        require(addr_ != ZERO_ADDRESS, "Zero address");
        _;
    }

    modifier onlyFRSwapOn() {
        require(isFRSwapOn, "Fix Rate Swap Is Off");
        _;
    }

    modifier onlySwapOn() {
        require(isSwapOn, "Swap Is Off");
        _;
    }

    /* ---------------------------- Writes --------------------------------- */

    function setAdmin(address newAdmin) onlyOwner public {
        for (uint i; i<admins.length; i++) {
            if (newAdmin == admins[i]) {
                revert("Already Admin");
            }
        }

        admins.push(newAdmin);

        emit SetAdmin(newAdmin);
    }

    function deleteAdmin(address oldAdmin) onlyOwner external {
        for (uint i; i<admins.length; i++) {
            if (oldAdmin == admins[i]) {
                admins[i] = admins[admins.length-1];
                admins.pop();
                break;
            }
        }

        emit DeleteAdmin(oldAdmin);
    }

    function flipSwap() onlyAdmin external {
        isSwapOn = !isSwapOn;

        emit FlipSwap(isSwapOn);
    }
    
    /* ---------------------------- Events --------------------------------- */

    event SetAdmin(address newAdmin);
    event DeleteAdmin(address oldAdmin);
    event FlipSwap(bool isSwapOn);
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAdmin","type":"address"}],"name":"DeleteAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"}],"name":"FRSwapPANDAForDAI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isSwapOn","type":"bool"}],"name":"FlipSwap","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":"newAdmin","type":"address"}],"name":"SetAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"setter","type":"address"},{"indexed":false,"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"SetDefendPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"SetMaxDefendPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"swapper","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"SwapDAIForPANDA","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"swapper","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"SwapETHForPANDA","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"WithdrawERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawEther","type":"event"},{"inputs":[],"name":"CORE_TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAIBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PANDA","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOLFEE_DAI_ETH","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOLFEE_PANDA_ETH","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH9","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ZERO_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"admins","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint24[]","name":"fees","type":"uint24[]"},{"internalType":"uint32","name":"twapInterval","type":"uint32"}],"name":"checkP","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"twapInterval","type":"uint32"}],"name":"checkPANDAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defendPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oldAdmin","type":"address"}],"name":"deleteAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"fRSwapPANDAForDAI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factoryV3","outputs":[{"internalType":"contract IUniswapV3Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"uniswapV3Pool","type":"address"},{"internalType":"uint32","name":"twapInterval","type":"uint32"}],"name":"getTWAP","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"getWETHPos","outputs":[{"internalType":"uint256[]","name":"WETHPos","type":"uint256[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"isFRSwapOn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSwapOn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDefendPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"newAdmin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setDefendPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setMaxDefendPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"swapDAIForPANDA","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"swapETHForPANDA","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint24[]","name":"fees","type":"uint24[]"},{"internalType":"uint32","name":"twapInterval","type":"uint32"},{"internalType":"bool","name":"isCheckDp","type":"bool"}],"name":"swapExactInputMultihop","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint24[]","name":"fees","type":"uint24[]"},{"internalType":"uint32","name":"twapInterval","type":"uint32"},{"internalType":"bool","name":"isCheckDp","type":"bool"}],"name":"swapExactInputSingle02","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"swapRouter02","outputs":[{"internalType":"contract IV3SwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]