creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "/Users/k06a/Projects/mooniswap-v2/contracts/Mooniswap.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/math/Math.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./interfaces/IFeeCollector.sol\";\nimport \"./libraries/UniERC20.sol\";\nimport \"./libraries/Sqrt.sol\";\nimport \"./libraries/VirtualBalance.sol\";\nimport \"./governance/MooniswapGovernance.sol\";\n\n\ncontract Mooniswap is MooniswapGovernance {\n    using Sqrt for uint256;\n    using SafeMath for uint256;\n    using UniERC20 for IERC20;\n    using VirtualBalance for VirtualBalance.Data;\n\n    struct Balances {\n        uint256 src;\n        uint256 dst;\n    }\n\n    struct SwapVolumes {\n        uint128 confirmed;\n        uint128 result;\n    }\n\n    struct Fees {\n        uint256 fee;\n        uint256 slippageFee;\n    }\n\n    event Error(string reason);\n\n    event Deposited(\n        address indexed sender,\n        address indexed receiver,\n        uint256 share,\n        uint256 token0Amount,\n        uint256 token1Amount\n    );\n\n    event Withdrawn(\n        address indexed sender,\n        address indexed receiver,\n        uint256 share,\n        uint256 token0Amount,\n        uint256 token1Amount\n    );\n\n    event Swapped(\n        address indexed sender,\n        address indexed receiver,\n        address indexed srcToken,\n        address dstToken,\n        uint256 amount,\n        uint256 result,\n        uint256 srcAdditionBalance,\n        uint256 dstRemovalBalance,\n        address referral\n    );\n\n    event Sync(\n        uint256 srcBalance,\n        uint256 dstBalance,\n        uint256 fee,\n        uint256 slippageFee,\n        uint256 referralShare,\n        uint256 governanceShare\n    );\n\n    uint256 private constant _BASE_SUPPLY = 1000;  // Total supply on first deposit\n\n    IERC20 public immutable token0;\n    IERC20 public immutable token1;\n    mapping(IERC20 => SwapVolumes) public volumes;\n    mapping(IERC20 => VirtualBalance.Data) public virtualBalancesForAddition;\n    mapping(IERC20 => VirtualBalance.Data) public virtualBalancesForRemoval;\n\n    modifier whenNotShutdown {\n        require(mooniswapFactoryGovernance.isActive(), \"Mooniswap: factory shutdown\");\n        _;\n    }\n\n    constructor(\n        IERC20 _token0,\n        IERC20 _token1,\n        string memory name,\n        string memory symbol,\n        IMooniswapFactoryGovernance _mooniswapFactoryGovernance\n    )\n        public\n        ERC20(name, symbol)\n        MooniswapGovernance(_mooniswapFactoryGovernance)\n    {\n        require(bytes(name).length > 0, \"Mooniswap: name is empty\");\n        require(bytes(symbol).length > 0, \"Mooniswap: symbol is empty\");\n        require(_token0 != _token1, \"Mooniswap: duplicate tokens\");\n        token0 = _token0;\n        token1 = _token1;\n    }\n\n    function getTokens() external view returns(IERC20[] memory tokens) {\n        tokens = new IERC20[](2);\n        tokens[0] = token0;\n        tokens[1] = token1;\n    }\n\n    function tokens(uint256 i) external view returns(IERC20) {\n        if (i == 0) {\n            return token0;\n        } else if (i == 1) {\n            return token1;\n        } else {\n            revert(\"Pool has two tokens\");\n        }\n    }\n\n    function getBalanceForAddition(IERC20 token) public view returns(uint256) {\n        uint256 balance = token.uniBalanceOf(address(this));\n        return Math.max(virtualBalancesForAddition[token].current(decayPeriod(), balance), balance);\n    }\n\n    function getBalanceForRemoval(IERC20 token) public view returns(uint256) {\n        uint256 balance = token.uniBalanceOf(address(this));\n        return Math.min(virtualBalancesForRemoval[token].current(decayPeriod(), balance), balance);\n    }\n\n    function getReturn(IERC20 src, IERC20 dst, uint256 amount) external view returns(uint256) {\n        return _getReturn(src, dst, amount, getBalanceForAddition(src), getBalanceForRemoval(dst), fee(), slippageFee());\n    }\n\n    function deposit(uint256[2] memory maxAmounts, uint256[2] memory minAmounts) external payable returns(uint256 fairSupply, uint256[2] memory receivedAmounts) {\n        return depositFor(maxAmounts, minAmounts, msg.sender);\n    }\n\n    function depositFor(uint256[2] memory maxAmounts, uint256[2] memory minAmounts, address target) public payable nonReentrant returns(uint256 fairSupply, uint256[2] memory receivedAmounts) {\n        IERC20[2] memory _tokens = [token0, token1];\n        require(msg.value == (_tokens[0].isETH() ? maxAmounts[0] : (_tokens[1].isETH() ? maxAmounts[1] : 0)), \"Mooniswap: wrong value usage\");\n\n        uint256 totalSupply = totalSupply();\n\n        if (totalSupply == 0) {\n            fairSupply = _BASE_SUPPLY.mul(99);\n            _mint(address(this), _BASE_SUPPLY); // Donate up to 1%\n\n            for (uint i = 0; i < maxAmounts.length; i++) {\n                fairSupply = Math.max(fairSupply, maxAmounts[i]);\n\n                require(maxAmounts[i] > 0, \"Mooniswap: amount is zero\");\n                require(maxAmounts[i] >= minAmounts[i], \"Mooniswap: minAmount not reached\");\n\n                _tokens[i].uniTransferFrom(msg.sender, address(this), maxAmounts[i]);\n                receivedAmounts[i] = maxAmounts[i];\n            }\n        }\n        else {\n            uint256[2] memory realBalances;\n            for (uint i = 0; i < realBalances.length; i++) {\n                realBalances[i] = _tokens[i].uniBalanceOf(address(this)).sub(_tokens[i].isETH() ? msg.value : 0);\n            }\n\n            // Pre-compute fair supply\n            fairSupply = type(uint256).max;\n            for (uint i = 0; i < maxAmounts.length; i++) {\n                fairSupply = Math.min(fairSupply, totalSupply.mul(maxAmounts[i]).div(realBalances[i]));\n            }\n\n            uint256 fairSupplyCached = fairSupply;\n\n            for (uint i = 0; i < maxAmounts.length; i++) {\n                require(maxAmounts[i] > 0, \"Mooniswap: amount is zero\");\n                uint256 amount = realBalances[i].mul(fairSupplyCached).add(totalSupply - 1).div(totalSupply);\n                require(amount >= minAmounts[i], \"Mooniswap: minAmount not reached\");\n\n                _tokens[i].uniTransferFrom(msg.sender, address(this), amount);\n                receivedAmounts[i] = _tokens[i].uniBalanceOf(address(this)).sub(realBalances[i]);\n                fairSupply = Math.min(fairSupply, totalSupply.mul(receivedAmounts[i]).div(realBalances[i]));\n            }\n\n            uint256 _decayPeriod = decayPeriod();  // gas savings\n            for (uint i = 0; i < maxAmounts.length; i++) {\n                virtualBalancesForRemoval[_tokens[i]].scale(_decayPeriod, realBalances[i], totalSupply.add(fairSupply), totalSupply);\n                virtualBalancesForAddition[_tokens[i]].scale(_decayPeriod, realBalances[i], totalSupply.add(fairSupply), totalSupply);\n            }\n        }\n\n        require(fairSupply > 0, \"Mooniswap: result is not enough\");\n        _mint(target, fairSupply);\n\n        emit Deposited(msg.sender, target, fairSupply, receivedAmounts[0], receivedAmounts[1]);\n    }\n\n    function withdraw(uint256 amount, uint256[] memory minReturns) external returns(uint256[2] memory withdrawnAmounts) {\n        return withdrawFor(amount, minReturns, msg.sender);\n    }\n\n    function withdrawFor(uint256 amount, uint256[] memory minReturns, address payable target) public nonReentrant returns(uint256[2] memory withdrawnAmounts) {\n        IERC20[2] memory _tokens = [token0, token1];\n\n        uint256 totalSupply = totalSupply();\n        uint256 _decayPeriod = decayPeriod();  // gas savings\n        _burn(msg.sender, amount);\n\n        for (uint i = 0; i < _tokens.length; i++) {\n            IERC20 token = _tokens[i];\n\n            uint256 preBalance = token.uniBalanceOf(address(this));\n            uint256 value = preBalance.mul(amount).div(totalSupply);\n            token.uniTransfer(target, value);\n            withdrawnAmounts[i] = value;\n            require(i >= minReturns.length || value >= minReturns[i], \"Mooniswap: result is not enough\");\n\n            virtualBalancesForAddition[token].scale(_decayPeriod, preBalance, totalSupply.sub(amount), totalSupply);\n            virtualBalancesForRemoval[token].scale(_decayPeriod, preBalance, totalSupply.sub(amount), totalSupply);\n        }\n\n        emit Withdrawn(msg.sender, target, amount, withdrawnAmounts[0], withdrawnAmounts[1]);\n    }\n\n    function swap(IERC20 src, IERC20 dst, uint256 amount, uint256 minReturn, address referral) external payable returns(uint256 result) {\n        return swapFor(src, dst, amount, minReturn, referral, msg.sender);\n    }\n\n    function swapFor(IERC20 src, IERC20 dst, uint256 amount, uint256 minReturn, address referral, address payable receiver) public payable nonReentrant whenNotShutdown returns(uint256 result) {\n        require(msg.value == (src.isETH() ? amount : 0), \"Mooniswap: wrong value usage\");\n\n        Balances memory balances = Balances({\n            src: src.uniBalanceOf(address(this)).sub(src.isETH() ? msg.value : 0),\n            dst: dst.uniBalanceOf(address(this))\n        });\n        uint256 confirmed;\n        Balances memory virtualBalances;\n        Fees memory fees = Fees({\n            fee: fee(),\n            slippageFee: slippageFee()\n        });\n        (confirmed, result, virtualBalances) = _doTransfers(src, dst, amount, minReturn, receiver, balances, fees);\n        emit Swapped(msg.sender, receiver, address(src), address(dst), confirmed, result, virtualBalances.src, virtualBalances.dst, referral);\n        _mintRewards(confirmed, result, referral, balances, fees);\n\n        // Overflow of uint128 is desired\n        volumes[src].confirmed += uint128(confirmed);\n        volumes[src].result += uint128(result);\n    }\n\n    function _doTransfers(IERC20 src, IERC20 dst, uint256 amount, uint256 minReturn, address payable receiver, Balances memory balances, Fees memory fees)\n        private returns(uint256 confirmed, uint256 result, Balances memory virtualBalances)\n    {\n        uint256 _decayPeriod = decayPeriod();\n        virtualBalances.src = virtualBalancesForAddition[src].current(_decayPeriod, balances.src);\n        virtualBalances.src = Math.max(virtualBalances.src, balances.src);\n        virtualBalances.dst = virtualBalancesForRemoval[dst].current(_decayPeriod, balances.dst);\n        virtualBalances.dst = Math.min(virtualBalances.dst, balances.dst);\n        src.uniTransferFrom(msg.sender, address(this), amount);\n        confirmed = src.uniBalanceOf(address(this)).sub(balances.src);\n        result = _getReturn(src, dst, confirmed, virtualBalances.src, virtualBalances.dst, fees.fee, fees.slippageFee);\n        require(result > 0 && result >= minReturn, \"Mooniswap: return is not enough\");\n        dst.uniTransfer(receiver, result);\n\n        // Update virtual balances to the same direction only at imbalanced state\n        if (virtualBalances.src != balances.src) {\n            virtualBalancesForAddition[src].set(virtualBalances.src.add(confirmed));\n        }\n        if (virtualBalances.dst != balances.dst) {\n            virtualBalancesForRemoval[dst].set(virtualBalances.dst.sub(result));\n        }\n        // Update virtual balances to the opposite direction\n        virtualBalancesForRemoval[src].update(_decayPeriod, balances.src);\n        virtualBalancesForAddition[dst].update(_decayPeriod, balances.dst);\n    }\n\n    function _mintRewards(uint256 confirmed, uint256 result, address referral, Balances memory balances, Fees memory fees) private {\n        (uint256 referralShare, uint256 governanceShare, address govWallet, address feeCollector) = mooniswapFactoryGovernance.shareParameters();\n\n        uint256 refReward;\n        uint256 govReward;\n\n        uint256 invariantRatio = uint256(1e36);\n        invariantRatio = invariantRatio.mul(balances.src.add(confirmed)).div(balances.src);\n        invariantRatio = invariantRatio.mul(balances.dst.sub(result)).div(balances.dst);\n        if (invariantRatio > 1e36) {\n            // calculate share only if invariant increased\n            invariantRatio = invariantRatio.sqrt();\n            uint256 invIncrease = totalSupply().mul(invariantRatio.sub(1e18)).div(invariantRatio);\n\n            refReward = (referral != address(0)) ? invIncrease.mul(referralShare).div(MooniswapConstants._FEE_DENOMINATOR) : 0;\n            govReward = (govWallet != address(0)) ? invIncrease.mul(governanceShare).div(MooniswapConstants._FEE_DENOMINATOR) : 0;\n\n            if (feeCollector == address(0)) {\n                if (refReward > 0) {\n                    _mint(referral, refReward);\n                }\n                if (govReward > 0) {\n                    _mint(govWallet, govReward);\n                }\n            }\n            else if (refReward > 0 || govReward > 0) {\n                uint256 len = (refReward > 0 ? 1 : 0) + (govReward > 0 ? 1 : 0);\n                address[] memory wallets = new address[](len);\n                uint256[] memory rewards = new uint256[](len);\n\n                wallets[0] = referral;\n                rewards[0] = refReward;\n                if (govReward > 0) {\n                    wallets[len - 1] = govWallet;\n                    rewards[len - 1] = govReward;\n                }\n\n                try IFeeCollector(feeCollector).updateRewards(wallets, rewards) {\n                    _mint(feeCollector, refReward.add(govReward));\n                }\n                catch {\n                    emit Error(\"updateRewards() failed\");\n                }\n            }\n        }\n\n        emit Sync(balances.src, balances.dst, fees.fee, fees.slippageFee, refReward, govReward);\n    }\n\n    /*\n        spot_ret = dx * y / x\n        uni_ret = dx * y / (x + dx)\n        slippage = (spot_ret - uni_ret) / spot_ret\n        slippage = dx * dx * y / (x * (x + dx)) / (dx * y / x)\n        slippage = dx / (x + dx)\n        ret = uni_ret * (1 - slip_fee * slippage)\n        ret = dx * y / (x + dx) * (1 - slip_fee * dx / (x + dx))\n        ret = dx * y / (x + dx) * (x + dx - slip_fee * dx) / (x + dx)\n\n        x = amount * denominator\n        dx = amount * (denominator - fee)\n    */\n    function _getReturn(IERC20 src, IERC20 dst, uint256 amount, uint256 srcBalance, uint256 dstBalance, uint256 fee, uint256 slippageFee) internal view returns(uint256) {\n        if (src > dst) {\n            (src, dst) = (dst, src);\n        }\n        if (amount > 0 && src == token0 && dst == token1) {\n            uint256 taxedAmount = amount.sub(amount.mul(fee).div(MooniswapConstants._FEE_DENOMINATOR));\n            uint256 srcBalancePlusTaxedAmount = srcBalance.add(taxedAmount);\n            uint256 ret = taxedAmount.mul(dstBalance).div(srcBalancePlusTaxedAmount);\n            uint256 feeNumerator = MooniswapConstants._FEE_DENOMINATOR.mul(srcBalancePlusTaxedAmount).sub(slippageFee.mul(taxedAmount));\n            uint256 feeDenominator = MooniswapConstants._FEE_DENOMINATOR.mul(srcBalancePlusTaxedAmount);\n            return ret.mul(feeNumerator).div(feeDenominator);\n        }\n    }\n\n    function rescueFunds(IERC20 token, uint256 amount) external nonReentrant onlyOwner {\n        uint256 balance0 = token0.uniBalanceOf(address(this));\n        uint256 balance1 = token1.uniBalanceOf(address(this));\n\n        token.uniTransfer(msg.sender, amount);\n\n        require(token0.uniBalanceOf(address(this)) >= balance0, \"Mooniswap: access denied\");\n        require(token1.uniBalanceOf(address(this)) >= balance1, \"Mooniswap: access denied\");\n        require(balanceOf(address(this)) >= _BASE_SUPPLY, \"Mooniswap: access denied\");\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/MooniswapFactory.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./interfaces/IMooniswapDeployer.sol\";\nimport \"./interfaces/IMooniswapFactory.sol\";\nimport \"./libraries/UniERC20.sol\";\nimport \"./Mooniswap.sol\";\nimport \"./governance/MooniswapFactoryGovernance.sol\";\n\n\ncontract MooniswapFactory is IMooniswapFactory, MooniswapFactoryGovernance {\n    using UniERC20 for IERC20;\n\n    event Deployed(\n        Mooniswap indexed mooniswap,\n        IERC20 indexed token1,\n        IERC20 indexed token2\n    );\n\n    IMooniswapDeployer public immutable mooniswapDeployer;\n    address public immutable poolOwner;\n    Mooniswap[] public allPools;\n    mapping(Mooniswap => bool) public override isPool;\n    mapping(IERC20 => mapping(IERC20 => Mooniswap)) private _pools;\n\n    constructor (address _poolOwner, IMooniswapDeployer _mooniswapDeployer, address _governanceMothership) public MooniswapFactoryGovernance(_governanceMothership) {\n        poolOwner = _poolOwner;\n        mooniswapDeployer = _mooniswapDeployer;\n    }\n\n    function getAllPools() external view returns(Mooniswap[] memory) {\n        return allPools;\n    }\n\n    function pools(IERC20 tokenA, IERC20 tokenB) external view override returns (Mooniswap pool) {\n        (IERC20 token1, IERC20 token2) = sortTokens(tokenA, tokenB);\n        return _pools[token1][token2];\n    }\n\n    function deploy(IERC20 tokenA, IERC20 tokenB) public returns(Mooniswap pool) {\n        require(tokenA != tokenB, \"Factory: not support same tokens\");\n        (IERC20 token1, IERC20 token2) = sortTokens(tokenA, tokenB);\n        require(_pools[token1][token2] == Mooniswap(0), \"Factory: pool already exists\");\n\n        string memory symbol1 = token1.uniSymbol();\n        string memory symbol2 = token2.uniSymbol();\n\n        pool = mooniswapDeployer.deploy(\n            token1,\n            token2,\n            string(abi.encodePacked(\"1inch Liquidity Pool (\", symbol1, \"-\", symbol2, \")\")),\n            string(abi.encodePacked(\"1LP-\", symbol1, \"-\", symbol2)),\n            poolOwner\n        );\n\n        _pools[token1][token2] = pool;\n        allPools.push(pool);\n        isPool[pool] = true;\n\n        emit Deployed(pool, token1, token2);\n    }\n\n    function sortTokens(IERC20 tokenA, IERC20 tokenB) public pure returns(IERC20, IERC20) {\n        if (tokenA < tokenB) {\n            return (tokenA, tokenB);\n        }\n        return (tokenB, tokenA);\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/governance/BaseGovernanceModule.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../interfaces/IGovernanceModule.sol\";\n\n\nabstract contract BaseGovernanceModule is IGovernanceModule {\n    address public immutable mothership;\n\n    modifier onlyMothership {\n        require(msg.sender == mothership, \"Access restricted to mothership\");\n\n        _;\n    }\n\n    constructor(address _mothership) public {\n        mothership = _mothership;\n    }\n\n    function notifyStakesChanged(address[] calldata accounts, uint256[] calldata newBalances) external override onlyMothership {\n        require(accounts.length == newBalances.length, \"Arrays length should be equal\");\n\n        for(uint256 i = 0; i < accounts.length; ++i) {\n            _notifyStakeChanged(accounts[i], newBalances[i]);\n        }\n    }\n\n    function notifyStakeChanged(address account, uint256 newBalance) external override onlyMothership {\n        _notifyStakeChanged(account, newBalance);\n    }\n\n    function _notifyStakeChanged(address account, uint256 newBalance) internal virtual;\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/governance/MooniswapFactoryGovernance.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Pausable.sol\";\nimport \"../interfaces/IMooniswapFactoryGovernance.sol\";\nimport \"../libraries/ExplicitLiquidVoting.sol\";\nimport \"../libraries/MooniswapConstants.sol\";\nimport \"../libraries/SafeCast.sol\";\nimport \"../utils/BalanceAccounting.sol\";\nimport \"./BaseGovernanceModule.sol\";\n\n\ncontract MooniswapFactoryGovernance is IMooniswapFactoryGovernance, BaseGovernanceModule, BalanceAccounting, Ownable, Pausable {\n    using Vote for Vote.Data;\n    using ExplicitLiquidVoting for ExplicitLiquidVoting.Data;\n    using VirtualVote for VirtualVote.Data;\n    using SafeMath for uint256;\n    using SafeCast for uint256;\n\n    event DefaultFeeVoteUpdate(address indexed user, uint256 fee, bool isDefault, uint256 amount);\n    event DefaultSlippageFeeVoteUpdate(address indexed user, uint256 slippageFee, bool isDefault, uint256 amount);\n    event DefaultDecayPeriodVoteUpdate(address indexed user, uint256 decayPeriod, bool isDefault, uint256 amount);\n    event ReferralShareVoteUpdate(address indexed user, uint256 referralShare, bool isDefault, uint256 amount);\n    event GovernanceShareVoteUpdate(address indexed user, uint256 governanceShare, bool isDefault, uint256 amount);\n    event GovernanceWalletUpdate(address governanceWallet);\n    event FeeCollectorUpdate(address feeCollector);\n\n    ExplicitLiquidVoting.Data private _defaultFee;\n    ExplicitLiquidVoting.Data private _defaultSlippageFee;\n    ExplicitLiquidVoting.Data private _defaultDecayPeriod;\n    ExplicitLiquidVoting.Data private _referralShare;\n    ExplicitLiquidVoting.Data private _governanceShare;\n    address public override governanceWallet;\n    address public override feeCollector;\n\n    mapping(address => bool) public override isFeeCollector;\n\n    constructor(address _mothership) public BaseGovernanceModule(_mothership) {\n        _defaultFee.data.result = MooniswapConstants._DEFAULT_FEE.toUint104();\n        _defaultSlippageFee.data.result = MooniswapConstants._DEFAULT_SLIPPAGE_FEE.toUint104();\n        _defaultDecayPeriod.data.result = MooniswapConstants._DEFAULT_DECAY_PERIOD.toUint104();\n        _referralShare.data.result = MooniswapConstants._DEFAULT_REFERRAL_SHARE.toUint104();\n        _governanceShare.data.result = MooniswapConstants._DEFAULT_GOVERNANCE_SHARE.toUint104();\n    }\n\n    function shutdown() external onlyOwner {\n        _pause();\n    }\n\n    function isActive() external view override returns (bool) {\n        return !paused();\n    }\n\n    function shareParameters() external view override returns(uint256, uint256, address, address) {\n        return (_referralShare.data.current(), _governanceShare.data.current(), governanceWallet, feeCollector);\n    }\n\n    function defaults() external view override returns(uint256, uint256, uint256) {\n        return (_defaultFee.data.current(), _defaultSlippageFee.data.current(), _defaultDecayPeriod.data.current());\n    }\n\n    function defaultFee() external view override returns(uint256) {\n        return _defaultFee.data.current();\n    }\n\n    function defaultFeeVotes(address user) external view returns(uint256) {\n        return _defaultFee.votes[user].get(MooniswapConstants._DEFAULT_FEE);\n    }\n\n    function virtualDefaultFee() external view returns(uint104, uint104, uint48) {\n        return (_defaultFee.data.oldResult, _defaultFee.data.result, _defaultFee.data.time);\n    }\n\n    function defaultSlippageFee() external view override returns(uint256) {\n        return _defaultSlippageFee.data.current();\n    }\n\n    function defaultSlippageFeeVotes(address user) external view returns(uint256) {\n        return _defaultSlippageFee.votes[user].get(MooniswapConstants._DEFAULT_SLIPPAGE_FEE);\n    }\n\n    function virtualDefaultSlippageFee() external view returns(uint104, uint104, uint48) {\n        return (_defaultSlippageFee.data.oldResult, _defaultSlippageFee.data.result, _defaultSlippageFee.data.time);\n    }\n\n    function defaultDecayPeriod() external view override returns(uint256) {\n        return _defaultDecayPeriod.data.current();\n    }\n\n    function defaultDecayPeriodVotes(address user) external view returns(uint256) {\n        return _defaultDecayPeriod.votes[user].get(MooniswapConstants._DEFAULT_DECAY_PERIOD);\n    }\n\n    function virtualDefaultDecayPeriod() external view returns(uint104, uint104, uint48) {\n        return (_defaultDecayPeriod.data.oldResult, _defaultDecayPeriod.data.result, _defaultDecayPeriod.data.time);\n    }\n\n    function referralShare() external view override returns(uint256) {\n        return _referralShare.data.current();\n    }\n\n    function referralShareVotes(address user) external view returns(uint256) {\n        return _referralShare.votes[user].get(MooniswapConstants._DEFAULT_REFERRAL_SHARE);\n    }\n\n    function virtualReferralShare() external view returns(uint104, uint104, uint48) {\n        return (_referralShare.data.oldResult, _referralShare.data.result, _referralShare.data.time);\n    }\n\n    function governanceShare() external view override returns(uint256) {\n        return _governanceShare.data.current();\n    }\n\n    function governanceShareVotes(address user) external view returns(uint256) {\n        return _governanceShare.votes[user].get(MooniswapConstants._DEFAULT_GOVERNANCE_SHARE);\n    }\n\n    function virtualGovernanceShare() external view returns(uint104, uint104, uint48) {\n        return (_governanceShare.data.oldResult, _governanceShare.data.result, _governanceShare.data.time);\n    }\n\n    function setGovernanceWallet(address newGovernanceWallet) external onlyOwner {\n        governanceWallet = newGovernanceWallet;\n        isFeeCollector[newGovernanceWallet] = true;\n        emit GovernanceWalletUpdate(newGovernanceWallet);\n    }\n\n    function setFeeCollector(address newFeeCollector) external onlyOwner {\n        feeCollector = newFeeCollector;\n        isFeeCollector[newFeeCollector] = true;\n        emit FeeCollectorUpdate(newFeeCollector);\n    }\n\n    function defaultFeeVote(uint256 vote) external {\n        require(vote <= MooniswapConstants._MAX_FEE, \"Fee vote is too high\");\n        _defaultFee.updateVote(msg.sender, _defaultFee.votes[msg.sender], Vote.init(vote), balanceOf(msg.sender), MooniswapConstants._DEFAULT_FEE, _emitDefaultFeeVoteUpdate);\n    }\n\n    function discardDefaultFeeVote() external {\n       _defaultFee.updateVote(msg.sender, _defaultFee.votes[msg.sender], Vote.init(), balanceOf(msg.sender), MooniswapConstants._DEFAULT_FEE, _emitDefaultFeeVoteUpdate);\n    }\n\n    function defaultSlippageFeeVote(uint256 vote) external {\n        require(vote <= MooniswapConstants._MAX_SLIPPAGE_FEE, \"Slippage fee vote is too high\");\n        _defaultSlippageFee.updateVote(msg.sender, _defaultSlippageFee.votes[msg.sender], Vote.init(vote), balanceOf(msg.sender), MooniswapConstants._DEFAULT_SLIPPAGE_FEE, _emitDefaultSlippageFeeVoteUpdate);\n    }\n\n   function discardDefaultSlippageFeeVote() external {\n        _defaultSlippageFee.updateVote(msg.sender, _defaultSlippageFee.votes[msg.sender], Vote.init(), balanceOf(msg.sender), MooniswapConstants._DEFAULT_SLIPPAGE_FEE, _emitDefaultSlippageFeeVoteUpdate);\n    }\n\n    function defaultDecayPeriodVote(uint256 vote) external {\n        require(vote <= MooniswapConstants._MAX_DECAY_PERIOD, \"Decay period vote is too high\");\n        require(vote >= MooniswapConstants._MIN_DECAY_PERIOD, \"Decay period vote is too low\");\n        _defaultDecayPeriod.updateVote(msg.sender, _defaultDecayPeriod.votes[msg.sender], Vote.init(vote), balanceOf(msg.sender), MooniswapConstants._DEFAULT_DECAY_PERIOD, _emitDefaultDecayPeriodVoteUpdate);\n    }\n\n    function discardDefaultDecayPeriodVote() external {\n        _defaultDecayPeriod.updateVote(msg.sender, _defaultDecayPeriod.votes[msg.sender], Vote.init(), balanceOf(msg.sender), MooniswapConstants._DEFAULT_DECAY_PERIOD, _emitDefaultDecayPeriodVoteUpdate);\n    }\n\n    function referralShareVote(uint256 vote) external {\n        require(vote <= MooniswapConstants._MAX_SHARE, \"Referral share vote is too high\");\n        require(vote >= MooniswapConstants._MIN_REFERRAL_SHARE, \"Referral share vote is too low\");\n        _referralShare.updateVote(msg.sender, _referralShare.votes[msg.sender], Vote.init(vote), balanceOf(msg.sender), MooniswapConstants._DEFAULT_REFERRAL_SHARE, _emitReferralShareVoteUpdate);\n    }\n\n    function discardReferralShareVote() external {\n        _referralShare.updateVote(msg.sender, _referralShare.votes[msg.sender], Vote.init(), balanceOf(msg.sender), MooniswapConstants._DEFAULT_REFERRAL_SHARE, _emitReferralShareVoteUpdate);\n    }\n\n    function governanceShareVote(uint256 vote) external {\n        require(vote <= MooniswapConstants._MAX_SHARE, \"Gov share vote is too high\");\n        _governanceShare.updateVote(msg.sender, _governanceShare.votes[msg.sender], Vote.init(vote), balanceOf(msg.sender), MooniswapConstants._DEFAULT_GOVERNANCE_SHARE, _emitGovernanceShareVoteUpdate);\n    }\n\n    function discardGovernanceShareVote() external {\n        _governanceShare.updateVote(msg.sender, _governanceShare.votes[msg.sender], Vote.init(), balanceOf(msg.sender), MooniswapConstants._DEFAULT_GOVERNANCE_SHARE, _emitGovernanceShareVoteUpdate);\n    }\n\n    function _notifyStakeChanged(address account, uint256 newBalance) internal override {\n        uint256 balance = _set(account, newBalance);\n        if (newBalance == balance) {\n            return;\n        }\n\n        _defaultFee.updateBalance(account, _defaultFee.votes[account], balance, newBalance, MooniswapConstants._DEFAULT_FEE, _emitDefaultFeeVoteUpdate);\n        _defaultSlippageFee.updateBalance(account, _defaultSlippageFee.votes[account], balance, newBalance, MooniswapConstants._DEFAULT_SLIPPAGE_FEE, _emitDefaultSlippageFeeVoteUpdate);\n        _defaultDecayPeriod.updateBalance(account, _defaultDecayPeriod.votes[account], balance, newBalance, MooniswapConstants._DEFAULT_DECAY_PERIOD, _emitDefaultDecayPeriodVoteUpdate);\n        _referralShare.updateBalance(account, _referralShare.votes[account], balance, newBalance, MooniswapConstants._DEFAULT_REFERRAL_SHARE, _emitReferralShareVoteUpdate);\n        _governanceShare.updateBalance(account, _governanceShare.votes[account], balance, newBalance, MooniswapConstants._DEFAULT_GOVERNANCE_SHARE, _emitGovernanceShareVoteUpdate);\n    }\n\n    function _emitDefaultFeeVoteUpdate(address user, uint256 newDefaultFee, bool isDefault, uint256 balance) private {\n        emit DefaultFeeVoteUpdate(user, newDefaultFee, isDefault, balance);\n    }\n\n    function _emitDefaultSlippageFeeVoteUpdate(address user, uint256 newDefaultSlippageFee, bool isDefault, uint256 balance) private {\n        emit DefaultSlippageFeeVoteUpdate(user, newDefaultSlippageFee, isDefault, balance);\n    }\n\n    function _emitDefaultDecayPeriodVoteUpdate(address user, uint256 newDefaultDecayPeriod, bool isDefault, uint256 balance) private {\n        emit DefaultDecayPeriodVoteUpdate(user, newDefaultDecayPeriod, isDefault, balance);\n    }\n\n    function _emitReferralShareVoteUpdate(address user, uint256 newReferralShare, bool isDefault, uint256 balance) private {\n        emit ReferralShareVoteUpdate(user, newReferralShare, isDefault, balance);\n    }\n\n    function _emitGovernanceShareVoteUpdate(address user, uint256 newGovernanceShare, bool isDefault, uint256 balance) private {\n        emit GovernanceShareVoteUpdate(user, newGovernanceShare, isDefault, balance);\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/governance/MooniswapGovernance.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../interfaces/IMooniswapFactoryGovernance.sol\";\nimport \"../libraries/LiquidVoting.sol\";\nimport \"../libraries/MooniswapConstants.sol\";\nimport \"../libraries/SafeCast.sol\";\n\n\nabstract contract MooniswapGovernance is ERC20, Ownable, ReentrancyGuard {\n    using Vote for Vote.Data;\n    using LiquidVoting for LiquidVoting.Data;\n    using VirtualVote for VirtualVote.Data;\n    using SafeCast for uint256;\n\n    event FeeVoteUpdate(address indexed user, uint256 fee, bool isDefault, uint256 amount);\n    event SlippageFeeVoteUpdate(address indexed user, uint256 slippageFee, bool isDefault, uint256 amount);\n    event DecayPeriodVoteUpdate(address indexed user, uint256 decayPeriod, bool isDefault, uint256 amount);\n\n    IMooniswapFactoryGovernance public mooniswapFactoryGovernance;\n    LiquidVoting.Data private _fee;\n    LiquidVoting.Data private _slippageFee;\n    LiquidVoting.Data private _decayPeriod;\n\n    constructor(IMooniswapFactoryGovernance _mooniswapFactoryGovernance) internal {\n        mooniswapFactoryGovernance = _mooniswapFactoryGovernance;\n        _fee.data.result = _mooniswapFactoryGovernance.defaultFee().toUint104();\n        _slippageFee.data.result = _mooniswapFactoryGovernance.defaultSlippageFee().toUint104();\n        _decayPeriod.data.result = _mooniswapFactoryGovernance.defaultDecayPeriod().toUint104();\n    }\n\n    function setMooniswapFactoryGovernance(IMooniswapFactoryGovernance newMooniswapFactoryGovernance) external onlyOwner {\n        mooniswapFactoryGovernance = newMooniswapFactoryGovernance;\n        this.discardFeeVote();\n        this.discardSlippageFeeVote();\n        this.discardDecayPeriodVote();\n    }\n\n    function fee() public view returns(uint256) {\n        return _fee.data.current();\n    }\n\n    function slippageFee() public view returns(uint256) {\n        return _slippageFee.data.current();\n    }\n\n    function decayPeriod() public view returns(uint256) {\n        return _decayPeriod.data.current();\n    }\n\n    function virtualFee() external view returns(uint104, uint104, uint48) {\n        return (_fee.data.oldResult, _fee.data.result, _fee.data.time);\n    }\n\n    function virtualSlippageFee() external view returns(uint104, uint104, uint48) {\n        return (_slippageFee.data.oldResult, _slippageFee.data.result, _slippageFee.data.time);\n    }\n\n    function virtualDecayPeriod() external view returns(uint104, uint104, uint48) {\n        return (_decayPeriod.data.oldResult, _decayPeriod.data.result, _decayPeriod.data.time);\n    }\n\n    function feeVotes(address user) external view returns(uint256) {\n        return _fee.votes[user].get(mooniswapFactoryGovernance.defaultFee);\n    }\n\n    function slippageFeeVotes(address user) external view returns(uint256) {\n        return _slippageFee.votes[user].get(mooniswapFactoryGovernance.defaultSlippageFee);\n    }\n\n    function decayPeriodVotes(address user) external view returns(uint256) {\n        return _decayPeriod.votes[user].get(mooniswapFactoryGovernance.defaultDecayPeriod);\n    }\n\n    function feeVote(uint256 vote) external {\n        require(vote <= MooniswapConstants._MAX_FEE, \"Fee vote is too high\");\n\n        _fee.updateVote(msg.sender, _fee.votes[msg.sender], Vote.init(vote), balanceOf(msg.sender), totalSupply(), mooniswapFactoryGovernance.defaultFee(), _emitFeeVoteUpdate);\n    }\n\n    function slippageFeeVote(uint256 vote) external {\n        require(vote <= MooniswapConstants._MAX_SLIPPAGE_FEE, \"Slippage fee vote is too high\");\n\n        _slippageFee.updateVote(msg.sender, _slippageFee.votes[msg.sender], Vote.init(vote), balanceOf(msg.sender), totalSupply(), mooniswapFactoryGovernance.defaultSlippageFee(), _emitSlippageFeeVoteUpdate);\n    }\n\n    function decayPeriodVote(uint256 vote) external {\n        require(vote <= MooniswapConstants._MAX_DECAY_PERIOD, \"Decay period vote is too high\");\n        require(vote >= MooniswapConstants._MIN_DECAY_PERIOD, \"Decay period vote is too low\");\n\n        _decayPeriod.updateVote(msg.sender, _decayPeriod.votes[msg.sender], Vote.init(vote), balanceOf(msg.sender), totalSupply(), mooniswapFactoryGovernance.defaultDecayPeriod(), _emitDecayPeriodVoteUpdate);\n    }\n\n    function discardFeeVote() external {\n        _fee.updateVote(msg.sender, _fee.votes[msg.sender], Vote.init(), balanceOf(msg.sender), totalSupply(), mooniswapFactoryGovernance.defaultFee(), _emitFeeVoteUpdate);\n    }\n\n    function discardSlippageFeeVote() external {\n        _slippageFee.updateVote(msg.sender, _slippageFee.votes[msg.sender], Vote.init(), balanceOf(msg.sender), totalSupply(), mooniswapFactoryGovernance.defaultSlippageFee(), _emitSlippageFeeVoteUpdate);\n    }\n\n    function discardDecayPeriodVote() external {\n        _decayPeriod.updateVote(msg.sender, _decayPeriod.votes[msg.sender], Vote.init(), balanceOf(msg.sender), totalSupply(), mooniswapFactoryGovernance.defaultDecayPeriod(), _emitDecayPeriodVoteUpdate);\n    }\n\n    function _emitFeeVoteUpdate(address account, uint256 newFee, bool isDefault, uint256 newBalance) private {\n        emit FeeVoteUpdate(account, newFee, isDefault, newBalance);\n    }\n\n    function _emitSlippageFeeVoteUpdate(address account, uint256 newSlippageFee, bool isDefault, uint256 newBalance) private {\n        emit SlippageFeeVoteUpdate(account, newSlippageFee, isDefault, newBalance);\n    }\n\n    function _emitDecayPeriodVoteUpdate(address account, uint256 newDecayPeriod, bool isDefault, uint256 newBalance) private {\n        emit DecayPeriodVoteUpdate(account, newDecayPeriod, isDefault, newBalance);\n    }\n\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal override {\n        if (from == to) {\n            // ignore transfers to self\n            return;\n        }\n\n        IMooniswapFactoryGovernance _mooniswapFactoryGovernance = mooniswapFactoryGovernance;\n        bool updateFrom = !(from == address(0) || _mooniswapFactoryGovernance.isFeeCollector(from));\n        bool updateTo = !(to == address(0) || _mooniswapFactoryGovernance.isFeeCollector(to));\n\n        if (!updateFrom && !updateTo) {\n            // mint to feeReceiver or burn from feeReceiver\n            return;\n        }\n\n        uint256 balanceFrom = (from != address(0)) ? balanceOf(from) : 0;\n        uint256 balanceTo = (to != address(0)) ? balanceOf(to) : 0;\n        uint256 newTotalSupply = totalSupply()\n            .add(from == address(0) ? amount : 0)\n            .sub(to == address(0) ? amount : 0);\n\n        ParamsHelper memory params = ParamsHelper({\n            from: from,\n            to: to,\n            updateFrom: updateFrom,\n            updateTo: updateTo,\n            amount: amount,\n            balanceFrom: balanceFrom,\n            balanceTo: balanceTo,\n            newTotalSupply: newTotalSupply\n        });\n\n        (uint256 defaultFee, uint256 defaultSlippageFee, uint256 defaultDecayPeriod) = _mooniswapFactoryGovernance.defaults();\n\n        _updateOnTransfer(params, defaultFee, _emitFeeVoteUpdate, _fee);\n        _updateOnTransfer(params, defaultSlippageFee, _emitSlippageFeeVoteUpdate, _slippageFee);\n        _updateOnTransfer(params, defaultDecayPeriod, _emitDecayPeriodVoteUpdate, _decayPeriod);\n    }\n\n    struct ParamsHelper {\n        address from;\n        address to;\n        bool updateFrom;\n        bool updateTo;\n        uint256 amount;\n        uint256 balanceFrom;\n        uint256 balanceTo;\n        uint256 newTotalSupply;\n    }\n\n    function _updateOnTransfer(\n        ParamsHelper memory params,\n        uint256 defaultValue,\n        function(address, uint256, bool, uint256) internal emitEvent,\n        LiquidVoting.Data storage votingData\n    ) private {\n        Vote.Data memory voteFrom = votingData.votes[params.from];\n        Vote.Data memory voteTo = votingData.votes[params.to];\n\n        if (voteFrom.isDefault() && voteTo.isDefault() && params.updateFrom && params.updateTo) {\n            emitEvent(params.from, voteFrom.get(defaultValue), true, params.balanceFrom.sub(params.amount));\n            emitEvent(params.to, voteTo.get(defaultValue), true, params.balanceTo.add(params.amount));\n            return;\n        }\n\n        if (params.updateFrom) {\n            votingData.updateBalance(params.from, voteFrom, params.balanceFrom, params.balanceFrom.sub(params.amount), params.newTotalSupply, defaultValue, emitEvent);\n        }\n\n        if (params.updateTo) {\n            votingData.updateBalance(params.to, voteTo, params.balanceTo, params.balanceTo.add(params.amount), params.newTotalSupply, defaultValue, emitEvent);\n        }\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/interfaces/IFeeCollector.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\ninterface IFeeCollector {\n    function updateReward(address receiver, uint256 amount) external;\n    function updateRewards(address[] calldata receivers, uint256[] calldata amounts) external;\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/interfaces/IGovernanceModule.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\ninterface IGovernanceModule {\n    function notifyStakeChanged(address account, uint256 newBalance) external;\n    function notifyStakesChanged(address[] calldata accounts, uint256[] calldata newBalances) external;\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/interfaces/IMooniswapDeployer.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../Mooniswap.sol\";\n\ninterface IMooniswapDeployer {\n    function deploy(\n        IERC20 token1,\n        IERC20 token2,\n        string calldata name,\n        string calldata symbol,\n        address poolOwner\n    ) external returns(Mooniswap pool);\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/interfaces/IMooniswapFactory.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../Mooniswap.sol\";\n\ninterface IMooniswapFactory is IMooniswapFactoryGovernance {\n    function pools(IERC20 token0, IERC20 token1) external view returns (Mooniswap);\n    function isPool(Mooniswap mooniswap) external view returns (bool);\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/interfaces/IMooniswapFactoryGovernance.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\ninterface IMooniswapFactoryGovernance {\n    function shareParameters() external view returns(uint256 referralShare, uint256 governanceShare, address governanceWallet, address referralFeeReceiver);\n    function defaults() external view returns(uint256 defaultFee, uint256 defaultSlippageFee, uint256 defaultDecayPeriod);\n\n    function defaultFee() external view returns(uint256);\n    function defaultSlippageFee() external view returns(uint256);\n    function defaultDecayPeriod() external view returns(uint256);\n    function referralShare() external view returns(uint256);\n    function governanceShare() external view returns(uint256);\n    function governanceWallet() external view returns(address);\n    function feeCollector() external view returns(address);\n\n    function isFeeCollector(address) external view returns(bool);\n    function isActive() external view returns (bool);\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/libraries/ExplicitLiquidVoting.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"./SafeCast.sol\";\nimport \"./VirtualVote.sol\";\nimport \"./Vote.sol\";\n\n\nlibrary ExplicitLiquidVoting {\n    using SafeMath for uint256;\n    using SafeCast for uint256;\n    using Vote for Vote.Data;\n    using VirtualVote for VirtualVote.Data;\n\n    struct Data {\n        VirtualVote.Data data;\n        uint256 _weightedSum;\n        uint256 _votedSupply;\n        mapping(address => Vote.Data) votes;\n    }\n\n    function updateVote(\n        ExplicitLiquidVoting.Data storage self,\n        address user,\n        Vote.Data memory oldVote,\n        Vote.Data memory newVote,\n        uint256 balance,\n        uint256 defaultVote,\n        function(address, uint256, bool, uint256) emitEvent\n    ) internal {\n        return _update(self, user, oldVote, newVote, balance, balance, defaultVote, emitEvent);\n    }\n\n    function updateBalance(\n        ExplicitLiquidVoting.Data storage self,\n        address user,\n        Vote.Data memory oldVote,\n        uint256 oldBalance,\n        uint256 newBalance,\n        uint256 defaultVote,\n        function(address, uint256, bool, uint256) emitEvent\n    ) internal {\n        return _update(self, user, oldVote, newBalance == 0 ? Vote.init() : oldVote, oldBalance, newBalance, defaultVote, emitEvent);\n    }\n\n    function _update(\n        ExplicitLiquidVoting.Data storage self,\n        address user,\n        Vote.Data memory oldVote,\n        Vote.Data memory newVote,\n        uint256 oldBalance,\n        uint256 newBalance,\n        uint256 defaultVote,\n        function(address, uint256, bool, uint256) emitEvent\n    ) private {\n        uint256 oldWeightedSum = self._weightedSum;\n        uint256 newWeightedSum = oldWeightedSum;\n        uint256 oldVotedSupply = self._votedSupply;\n        uint256 newVotedSupply = oldVotedSupply;\n\n        if (!oldVote.isDefault()) {\n            newWeightedSum = newWeightedSum.sub(oldBalance.mul(oldVote.get(defaultVote)));\n            newVotedSupply = newVotedSupply.sub(oldBalance);\n        }\n\n        if (!newVote.isDefault()) {\n            newWeightedSum = newWeightedSum.add(newBalance.mul(newVote.get(defaultVote)));\n            newVotedSupply = newVotedSupply.add(newBalance);\n        }\n\n        if (newWeightedSum != oldWeightedSum) {\n            self._weightedSum = newWeightedSum;\n        }\n\n        if (newVotedSupply != oldVotedSupply) {\n            self._votedSupply = newVotedSupply;\n        }\n\n        {\n            uint256 newResult = newVotedSupply == 0 ? defaultVote : newWeightedSum.div(newVotedSupply);\n            VirtualVote.Data memory data = self.data;\n\n            if (newResult != data.result) {\n                VirtualVote.Data storage sdata = self.data;\n                (sdata.oldResult, sdata.result, sdata.time) = (\n                    data.current().toUint104(),\n                    newResult.toUint104(),\n                    block.timestamp.toUint48()\n                );\n            }\n        }\n\n        if (!newVote.eq(oldVote)) {\n            self.votes[user] = newVote;\n        }\n\n        emitEvent(user, newVote.get(defaultVote), newVote.isDefault(), newBalance);\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/libraries/LiquidVoting.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"./SafeCast.sol\";\nimport \"./VirtualVote.sol\";\nimport \"./Vote.sol\";\n\n\nlibrary LiquidVoting {\n    using SafeMath for uint256;\n    using SafeCast for uint256;\n    using Vote for Vote.Data;\n    using VirtualVote for VirtualVote.Data;\n\n    struct Data {\n        VirtualVote.Data data;\n        uint256 _weightedSum;\n        uint256 _defaultVotes;\n        mapping(address => Vote.Data) votes;\n    }\n\n    function updateVote(\n        LiquidVoting.Data storage self,\n        address user,\n        Vote.Data memory oldVote,\n        Vote.Data memory newVote,\n        uint256 balance,\n        uint256 totalSupply,\n        uint256 defaultVote,\n        function(address, uint256, bool, uint256) emitEvent\n    ) internal {\n        return _update(self, user, oldVote, newVote, balance, balance, totalSupply, defaultVote, emitEvent);\n    }\n\n    function updateBalance(\n        LiquidVoting.Data storage self,\n        address user,\n        Vote.Data memory oldVote,\n        uint256 oldBalance,\n        uint256 newBalance,\n        uint256 newTotalSupply,\n        uint256 defaultVote,\n        function(address, uint256, bool, uint256) emitEvent\n    ) internal {\n        return _update(self, user, oldVote, newBalance == 0 ? Vote.init() : oldVote, oldBalance, newBalance, newTotalSupply, defaultVote, emitEvent);\n    }\n\n    function _update(\n        LiquidVoting.Data storage self,\n        address user,\n        Vote.Data memory oldVote,\n        Vote.Data memory newVote,\n        uint256 oldBalance,\n        uint256 newBalance,\n        uint256 newTotalSupply,\n        uint256 defaultVote,\n        function(address, uint256, bool, uint256) emitEvent\n    ) private {\n        uint256 oldWeightedSum = self._weightedSum;\n        uint256 newWeightedSum = oldWeightedSum;\n        uint256 oldDefaultVotes = self._defaultVotes;\n        uint256 newDefaultVotes = oldDefaultVotes;\n\n        if (oldVote.isDefault()) {\n            newDefaultVotes = newDefaultVotes.sub(oldBalance);\n        } else {\n            newWeightedSum = newWeightedSum.sub(oldBalance.mul(oldVote.get(defaultVote)));\n        }\n\n        if (newVote.isDefault()) {\n            newDefaultVotes = newDefaultVotes.add(newBalance);\n        } else {\n            newWeightedSum = newWeightedSum.add(newBalance.mul(newVote.get(defaultVote)));\n        }\n\n        if (newWeightedSum != oldWeightedSum) {\n            self._weightedSum = newWeightedSum;\n        }\n\n        if (newDefaultVotes != oldDefaultVotes) {\n            self._defaultVotes = newDefaultVotes;\n        }\n\n        {\n            uint256 newResult = newTotalSupply == 0 ? defaultVote : newWeightedSum.add(newDefaultVotes.mul(defaultVote)).div(newTotalSupply);\n            VirtualVote.Data memory data = self.data;\n\n            if (newResult != data.result) {\n                VirtualVote.Data storage sdata = self.data;\n                (sdata.oldResult, sdata.result, sdata.time) = (\n                    data.current().toUint104(),\n                    newResult.toUint104(),\n                    block.timestamp.toUint48()\n                );\n            }\n        }\n\n        if (!newVote.eq(oldVote)) {\n            self.votes[user] = newVote;\n        }\n\n        emitEvent(user, newVote.get(defaultVote), newVote.isDefault(), newBalance);\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/libraries/MooniswapConstants.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\nlibrary MooniswapConstants {\n    uint256 internal constant _FEE_DENOMINATOR = 1e18;\n\n    uint256 internal constant _MIN_REFERRAL_SHARE = 0.05e18; // 5%\n    uint256 internal constant _MIN_DECAY_PERIOD = 1 minutes;\n\n    uint256 internal constant _MAX_FEE = 0.01e18; // 1%\n    uint256 internal constant _MAX_SLIPPAGE_FEE = 1e18;  // 100%\n    uint256 internal constant _MAX_SHARE = 0.1e18; // 10%\n    uint256 internal constant _MAX_DECAY_PERIOD = 5 minutes;\n\n    uint256 internal constant _DEFAULT_FEE = 0;\n    uint256 internal constant _DEFAULT_SLIPPAGE_FEE = 1e18;  // 100%\n    uint256 internal constant _DEFAULT_REFERRAL_SHARE = 0.1e18; // 10%\n    uint256 internal constant _DEFAULT_GOVERNANCE_SHARE = 0;\n    uint256 internal constant _DEFAULT_DECAY_PERIOD = 1 minutes;\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/libraries/SafeCast.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nlibrary SafeCast {\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        require(value < 2**216, \"value does not fit in 216 bits\");\n        return uint216(value);\n    }\n\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        require(value < 2**104, \"value does not fit in 104 bits\");\n        return uint104(value);\n    }\n\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        require(value < 2**48, \"value does not fit in 48 bits\");\n        return uint48(value);\n    }\n\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        require(value < 2**40, \"value does not fit in 40 bits\");\n        return uint40(value);\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/libraries/Sqrt.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\nlibrary Sqrt {\n    // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)\n    function sqrt(uint256 y) internal pure returns (uint256) {\n        if (y > 3) {\n            uint256 z = y;\n            uint256 x = y / 2 + 1;\n            while (x < z) {\n                z = x;\n                x = (y / x + x) / 2;\n            }\n            return z;\n        } else if (y != 0) {\n            return 1;\n        } else {\n            return 0;\n        }\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/libraries/UniERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\n\nlibrary UniERC20 {\n    using SafeMath for uint256;\n    using SafeERC20 for IERC20;\n\n    function isETH(IERC20 token) internal pure returns(bool) {\n        return (address(token) == address(0));\n    }\n\n    function uniBalanceOf(IERC20 token, address account) internal view returns (uint256) {\n        if (isETH(token)) {\n            return account.balance;\n        } else {\n            return token.balanceOf(account);\n        }\n    }\n\n    function uniTransfer(IERC20 token, address payable to, uint256 amount) internal {\n        if (amount > 0) {\n            if (isETH(token)) {\n                to.transfer(amount);\n            } else {\n                token.safeTransfer(to, amount);\n            }\n        }\n    }\n\n    function uniTransferFrom(IERC20 token, address payable from, address to, uint256 amount) internal {\n        if (amount > 0) {\n            if (isETH(token)) {\n                require(msg.value >= amount, \"UniERC20: not enough value\");\n                require(from == msg.sender, \"from is not msg.sender\");\n                require(to == address(this), \"to is not this\");\n                if (msg.value > amount) {\n                    // Return remainder if exist\n                    from.transfer(msg.value.sub(amount));\n                }\n            } else {\n                token.safeTransferFrom(from, to, amount);\n            }\n        }\n    }\n\n    function uniSymbol(IERC20 token) internal view returns(string memory) {\n        if (isETH(token)) {\n            return \"ETH\";\n        }\n\n        (bool success, bytes memory data) = address(token).staticcall{ gas: 20000 }(\n            abi.encodeWithSignature(\"symbol()\")\n        );\n        if (!success) {\n            (success, data) = address(token).staticcall{ gas: 20000 }(\n                abi.encodeWithSignature(\"SYMBOL()\")\n            );\n        }\n\n        if (success && data.length >= 96) {\n            (uint256 offset, uint256 len) = abi.decode(data, (uint256, uint256));\n            if (offset == 0x20 && len > 0 && len <= 256) {\n                return string(abi.decode(data, (bytes)));\n            }\n        }\n\n        if (success && data.length == 32) {\n            uint len = 0;\n            while (len < data.length && data[len] >= 0x20 && data[len] <= 0x7E) {\n                len++;\n            }\n\n            if (len > 0) {\n                bytes memory result = new bytes(len);\n                for (uint i = 0; i < len; i++) {\n                    result[i] = data[i];\n                }\n                return string(result);\n            }\n        }\n\n        return _toHex(address(token));\n    }\n\n    function _toHex(address account) private pure returns(string memory) {\n        return _toHex(abi.encodePacked(account));\n    }\n\n    function _toHex(bytes memory data) private pure returns(string memory) {\n        bytes memory str = new bytes(2 + data.length * 2);\n        str[0] = \"0\";\n        str[1] = \"x\";\n        uint j = 2;\n        for (uint i = 0; i < data.length; i++) {\n            uint a = uint8(data[i]) >> 4;\n            uint b = uint8(data[i]) & 0x0f;\n            str[j++] = byte(uint8(a + 48 + (a/10)*39));\n            str[j++] = byte(uint8(b + 48 + (b/10)*39));\n        }\n\n        return string(str);\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/libraries/VirtualBalance.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.12;\n\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/math/Math.sol\";\nimport \"./SafeCast.sol\";\n\n\nlibrary VirtualBalance {\n    using SafeMath for uint256;\n    using SafeCast for uint256;\n\n    struct Data {\n        uint216 balance;\n        uint40 time;\n    }\n\n    function set(VirtualBalance.Data storage self, uint256 balance) internal {\n        (self.balance, self.time) = (\n            balance.toUint216(),\n            block.timestamp.toUint40()\n        );\n    }\n\n    function update(VirtualBalance.Data storage self, uint256 decayPeriod, uint256 realBalance) internal {\n        set(self, current(self, decayPeriod, realBalance));\n    }\n\n    function scale(VirtualBalance.Data storage self, uint256 decayPeriod, uint256 realBalance, uint256 num, uint256 denom) internal {\n        set(self, current(self, decayPeriod, realBalance).mul(num).add(denom.sub(1)).div(denom));\n    }\n\n    function current(VirtualBalance.Data memory self, uint256 decayPeriod, uint256 realBalance) internal view returns(uint256) {\n        uint256 timePassed = Math.min(decayPeriod, block.timestamp.sub(self.time));\n        uint256 timeRemain = decayPeriod.sub(timePassed);\n        return uint256(self.balance).mul(timeRemain).add(\n            realBalance.mul(timePassed)\n        ).div(decayPeriod);\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/libraries/VirtualVote.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts/math/Math.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\n\n\nlibrary VirtualVote {\n    using SafeMath for uint256;\n\n    uint256 private constant _VOTE_DECAY_PERIOD = 1 days;\n\n    struct Data {\n        uint104 oldResult;\n        uint104 result;\n        uint48 time;\n    }\n\n    function current(VirtualVote.Data memory self) internal view returns(uint256) {\n        uint256 timePassed = Math.min(_VOTE_DECAY_PERIOD, block.timestamp.sub(self.time));\n        uint256 timeRemain = _VOTE_DECAY_PERIOD.sub(timePassed);\n        return uint256(self.oldResult).mul(timeRemain).add(\n            uint256(self.result).mul(timePassed)\n        ).div(_VOTE_DECAY_PERIOD);\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/libraries/Vote.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.12;\n\n\nlibrary Vote {\n    struct Data {\n        uint256 value;\n    }\n\n    function eq(Vote.Data memory self, Vote.Data memory vote) internal pure returns(bool) {\n        return self.value == vote.value;\n    }\n\n    function init() internal pure returns(Vote.Data memory data) {\n        return Vote.Data({\n            value: 0\n        });\n    }\n\n    function init(uint256 vote) internal pure returns(Vote.Data memory data) {\n        return Vote.Data({\n            value: vote + 1\n        });\n    }\n\n    function isDefault(Data memory self) internal pure returns(bool) {\n        return self.value == 0;\n    }\n\n    function get(Data memory self, uint256 defaultVote) internal pure returns(uint256) {\n        if (self.value > 0) {\n            return self.value - 1;\n        }\n        return defaultVote;\n    }\n\n    function get(Data memory self, function() external view returns(uint256) defaultVoteFn) internal view returns(uint256) {\n        if (self.value > 0) {\n            return self.value - 1;\n        }\n        return defaultVoteFn();\n    }\n}\n"
      },
      "/Users/k06a/Projects/mooniswap-v2/contracts/utils/BalanceAccounting.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\n\n\ncontract BalanceAccounting {\n    using SafeMath for uint256;\n\n    uint256 private _totalSupply;\n    mapping(address => uint256) private _balances;\n\n    function totalSupply() public view returns (uint256) {\n        return _totalSupply;\n    }\n\n    function balanceOf(address account) public view returns (uint256) {\n        return _balances[account];\n    }\n\n    function _mint(address account, uint256 amount) internal virtual {\n        _totalSupply = _totalSupply.add(amount);\n        _balances[account] = _balances[account].add(amount);\n    }\n\n    function _burn(address account, uint256 amount) internal virtual {\n        _balances[account] = _balances[account].sub(amount, \"Burn amount exceeds balance\");\n        _totalSupply = _totalSupply.sub(amount);\n    }\n\n    function _set(address account, uint256 amount) internal virtual returns(uint256 oldAmount) {\n        oldAmount = _balances[account];\n        if (oldAmount != amount) {\n            _balances[account] = amount;\n            _totalSupply = _totalSupply.add(amount).sub(oldAmount);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/GSN/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address payable) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes memory) {\n        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n        return msg.data;\n    }\n}\n"
      },
      "@openzeppelin/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor () internal {\n        address msgSender = _msgSender();\n        _owner = msgSender;\n        emit OwnershipTransferred(address(0), msgSender);\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(_owner == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        emit OwnershipTransferred(_owner, address(0));\n        _owner = address(0);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\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}\n"
      },
      "@openzeppelin/contracts/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a >= b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow, so we distribute\n        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\n    }\n}\n"
      },
      "@openzeppelin/contracts/math/SafeMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return sub(a, b, \"SafeMath: subtraction overflow\");\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot 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\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return div(a, b, \"SafeMath: division by zero\");\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be 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        // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return mod(a, b, \"SafeMath: modulo by zero\");\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts with custom message when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be 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}\n"
      },
      "@openzeppelin/contracts/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n    using SafeMath for uint256;\n    using Address for address;\n\n    mapping (address => uint256) private _balances;\n\n    mapping (address => mapping (address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n    uint8 private _decimals;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n     * a default value of 18.\n     *\n     * To select a different value for {decimals}, use {_setupDecimals}.\n     *\n     * All three of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor (string memory name, string memory symbol) public {\n        _name = name;\n        _symbol = symbol;\n        _decimals = 18;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n     * called.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view returns (uint8) {\n        return _decimals;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `recipient` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(_msgSender(), recipient, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        _approve(_msgSender(), spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20};\n     *\n     * Requirements:\n     * - `sender` and `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``sender``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) 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\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\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\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\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\n    /**\n     * @dev Moves tokens `amount` from `sender` to `recipient`.\n     *\n     * This is internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `sender` cannot be the zero address.\n     * - `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     */\n    function _transfer(address sender, address recipient, uint256 amount) 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\n        _beforeTokenTransfer(sender, recipient, amount);\n\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\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements\n     *\n     * - `to` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply = _totalSupply.add(amount);\n        _balances[account] = _balances[account].add(amount);\n        emit Transfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\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\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n     *\n     * This is internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) 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\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Sets {decimals} to a value other than the default one of 18.\n     *\n     * WARNING: This function should only be called from the constructor. Most\n     * applications that interact with token contracts will not expect\n     * {decimals} to ever change, and may work incorrectly if it does.\n     */\n    function _setupDecimals(uint8 decimals_) internal {\n        _decimals = decimals_;\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be to transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using SafeMath for uint256;\n    using Address for address;\n\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        // solhint-disable-next-line max-line-length\n        require((value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 newAllowance = token.allowance(address(this), spender).add(value);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) { // Return data is optional\n            // solhint-disable-next-line max-line-length\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n        // for accounts without code, i.e. `keccak256('')`\n        bytes32 codehash;\n        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n        // solhint-disable-next-line no-inline-assembly\n        assembly { codehash := extcodehash(account) }\n        return (codehash != accountHash && codehash != 0x0);\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n        (bool success, ) = recipient.call{ value: amount }(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain`call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n      return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n        return _functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        return _functionCallWithValue(target, data, value, errorMessage);\n    }\n\n    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n        require(isContract(target), \"Address: call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Pausable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\ncontract Pausable is Context {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    constructor () internal {\n        _paused = false;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        require(!_paused, \"Pausable: paused\");\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        require(_paused, \"Pausable: not paused\");\n        _;\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/ReentrancyGuard.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\ncontract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    constructor () internal {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and make it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [],
      "optimizer": {
        "enabled": true,
        "runs": 1000
      },
      "evmVersion": "istanbul",
      "libraries": {},
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}