creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/base/LiquidityPool.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity 0.6.12;\n\nimport \"./LpToken.sol\";\nimport \"./Math.sol\";\nimport \"../interfaces/IBFactory.sol\";\nimport \"../interfaces/IConfigurableRightsPool.sol\";\nimport \"../libraries/Address.sol\";\nimport \"../libraries/SafeERC20.sol\";\n\ncontract LiquidityPool is BBronze, LpToken, Math {\n    using Address for address;\n    using SafeERC20 for IERC20;\n\n    struct Record {\n        bool bound; // is token bound to pool\n        uint index; // private\n        uint denorm; // denormalized weight\n        uint balance;\n    }\n\n    event LOG_JOIN(address indexed caller, address indexed tokenIn, uint tokenAmountIn);\n\n    event LOG_EXIT(address indexed caller, address indexed tokenOut, uint tokenAmountOut);\n\n    event LOG_REBALANCE(address indexed tokenA, address indexed tokenB, uint newWeightA, uint newWeightB, uint newBalanceA, uint newBalanceB, bool isSoldout);\n\n    event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\n\n    modifier _logs_() {\n        emit LOG_CALL(msg.sig, msg.sender, msg.data);\n        _;\n    }\n\n    modifier _lock_() {\n        require(!_mutex, \"ERR_REENTRY\");\n        _mutex = true;\n        _;\n        _mutex = false;\n    }\n\n    modifier _viewlock_() {\n        require(!_mutex, \"ERR_REENTRY\");\n        _;\n    }\n\n    bool private _mutex;\n\n    IBFactory private _factory; // Factory address to push token exitFee to\n    address private _controller; // has CONTROL role\n    bool private _publicSwap; // true if PUBLIC can call SWAP functions\n\n    // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\n    bool private _finalized;\n\n    address[] private _tokens;\n    mapping(address => Record) private _records;\n    uint private _totalWeight;\n\n    constructor() public {\n        _controller = msg.sender;\n        _factory = IBFactory(msg.sender);\n        _publicSwap = false;\n        _finalized = false;\n    }\n\n    function isPublicSwap() external view returns (bool) {\n        return _publicSwap;\n    }\n\n    function isFinalized() external view returns (bool) {\n        return _finalized;\n    }\n\n    function isBound(address t) external view returns (bool) {\n        return _records[t].bound;\n    }\n\n    function getNumTokens() external view returns (uint) {\n        return _tokens.length;\n    }\n\n    function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\n        return _tokens;\n    }\n\n    function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\n        require(_finalized, \"ERR_NOT_FINALIZED\");\n        return _tokens;\n    }\n\n    function getDenormalizedWeight(address token) external view _viewlock_ returns (uint) {\n        // require(_records[token].bound, \"ERR_NOT_BOUND\");\n        return _records[token].denorm;\n    }\n\n    function getTotalDenormalizedWeight() external view _viewlock_ returns (uint) {\n        return _totalWeight;\n    }\n\n    function getNormalizedWeight(address token) external _viewlock_ returns (uint) {\n        require(_records[token].bound, \"ERR_NOT_BOUND\");\n        Oracles oracle = Oracles(_factory.getOracleAddress());\n        uint denorm = _records[token].denorm;\n        uint price = oracle.getPrice(token);\n\n        uint[] memory _balances = new uint[](_tokens.length);\n        for (uint i = 0; i < _tokens.length; i++) {\n            _balances[i] = getBalance(_tokens[i]);\n        }\n        uint totalValue = oracle.getAllPrice(_tokens, _balances);\n        uint currentValue = bmul(price, getBalance(token));\n        return bdiv(currentValue, totalValue);\n    }\n\n    function getBalance(address token) public view _viewlock_ returns (uint) {\n        // require(_records[token].bound, \"ERR_NOT_BOUND\");\n        return _records[token].balance;\n    }\n\n    function getController() external view _viewlock_ returns (address) {\n        return _controller;\n    }\n\n    function setController(address manager) external _logs_ _lock_ {\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n        require(manager != address(0), \"ERR_ZERO_ADDRESS\");\n        _controller = manager;\n    }\n\n    function setPublicSwap(bool public_) external _logs_ _lock_ {\n        require(!_finalized, \"ERR_IS_FINALIZED\");\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n        _publicSwap = public_;\n    }\n\n    function finalize() external _logs_ _lock_ {\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n        require(!_finalized, \"ERR_IS_FINALIZED\");\n        require(_tokens.length >= MIN_BOUND_TOKENS, \"ERR_MIN_TOKENS\");\n\n        _finalized = true;\n        _publicSwap = true;\n\n        _mintPoolShare(INIT_POOL_SUPPLY);\n        _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\n    }\n\n    function bind(\n        address token,\n        uint balance,\n        uint denorm\n    )\n        external\n        _logs_ // _lock_  Bind does not lock because it jumps to `rebind`, which does\n    {\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n        require(!_records[token].bound, \"ERR_IS_BOUND\");\n        require(!_finalized, \"ERR_IS_FINALIZED\");\n\n        require(_tokens.length < MAX_BOUND_TOKENS, \"ERR_MAX_TOKENS\");\n\n        _records[token] = Record({\n            bound: true,\n            index: _tokens.length,\n            denorm: 0, // balance and denorm will be validated\n            balance: 0 // and set by `rebind`\n        });\n        _tokens.push(token);\n        rebind(token, balance, denorm);\n    }\n\n    function rebind(\n        address token,\n        uint balance,\n        uint denorm\n    ) public _logs_ _lock_ {\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n        require(_records[token].bound, \"ERR_NOT_BOUND\");\n        require(!_finalized, \"ERR_IS_FINALIZED\");\n\n        require(denorm >= MIN_WEIGHT, \"ERR_MIN_WEIGHT\");\n        require(denorm <= MAX_WEIGHT, \"ERR_MAX_WEIGHT\");\n        require(balance >= MIN_BALANCE, \"ERR_MIN_BALANCE\");\n\n        // Adjust the denorm and totalWeight\n        uint oldWeight = _records[token].denorm;\n        if (denorm > oldWeight) {\n            _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\n            require(_totalWeight <= MAX_TOTAL_WEIGHT, \"ERR_MAX_TOTAL_WEIGHT\");\n        } else if (denorm < oldWeight) {\n            _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\n        }\n        _records[token].denorm = denorm;\n\n        // Adjust the balance record and actual token balance\n        uint oldBalance = _records[token].balance;\n        _records[token].balance = balance;\n        if (balance > oldBalance) {\n            _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\n        } else if (balance < oldBalance) {\n            // In this case liquidity is being withdrawn, so charge EXIT_FEE\n            uint tokenBalanceWithdrawn = bsub(oldBalance, balance);\n            _pushUnderlying(token, msg.sender, tokenBalanceWithdrawn);\n        }\n    }\n\n    function execute(\n        address _target,\n        uint _value,\n        bytes calldata _data\n    ) external _logs_ _lock_ returns (bytes memory _returnValue) {\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n        require(!_finalized, \"ERR_IS_FINALIZED\");\n\n        _returnValue = _target.functionCallWithValue(_data, _value);\n\n        return _returnValue;\n    }\n\n    function unbind(address token) external _logs_ _lock_ {\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n        require(_records[token].bound, \"ERR_NOT_BOUND\");\n        require(!_finalized, \"ERR_IS_FINALIZED\");\n\n        uint tokenBalance = _records[token].balance;\n\n        _totalWeight = bsub(_totalWeight, _records[token].denorm);\n\n        // Swap the token-to-unbind with the last token,\n        // then delete the last token\n        uint index = _records[token].index;\n        uint last = _tokens.length - 1;\n        _tokens[index] = _tokens[last];\n        _records[_tokens[index]].index = index;\n        _tokens.pop();\n        _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\n\n        _pushUnderlying(token, msg.sender, tokenBalance);\n    }\n\n    function unbindPure(address token) external _logs_ _lock_ {\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n        require(_records[token].bound, \"ERR_NOT_BOUND\");\n        require(!_finalized, \"ERR_IS_FINALIZED\");\n\n        // Swap the token-to-unbind with the last token,\n        // then delete the last token\n        uint index = _records[token].index;\n        uint last = _tokens.length - 1;\n        _tokens[index] = _tokens[last];\n        _records[_tokens[index]].index = index;\n        _tokens.pop();\n        _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\n    }\n\n    function rebindPure(\n        address token,\n        uint balance,\n        uint denorm,\n        bool isBound\n    ) public _logs_ _lock_ {\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n\n        if (!isBound) {\n            require(_tokens.length < MAX_BOUND_TOKENS, \"ERR_MAX_TOKENS\");\n\n            _records[token] = Record({\n                bound: true,\n                index: _tokens.length,\n                denorm: denorm,\n                balance: balance\n            });\n            _tokens.push(token);\n        } else {\n            _records[token].denorm = denorm;\n            _records[token].balance = balance;\n        }\n    }\n\n    // Absorb any tokens that have been sent to this contract into the pool\n    function gulp(address token) external _logs_ _lock_ {\n        require(IConfigurableRightsPool(_controller).adminList(msg.sender), 'NOT_ADMIN');\n        require(_records[token].bound, \"ERR_NOT_BOUND\");\n        _records[token].balance = IERC20(token).balanceOf(address(this));\n    }\n\n    function joinPool(uint poolAmountOut, uint[] calldata maxAmountsIn) external _logs_ _lock_ {\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n        require(_finalized, \"ERR_NOT_FINALIZED\");\n\n        uint poolTotal = this.totalSupply();\n        uint ratio = bdiv(poolAmountOut, poolTotal);\n        require(ratio != 0, \"ERR_MATH_APPROX\");\n\n        for (uint i = 0; i < _tokens.length; i++) {\n            address t = _tokens[i];\n            uint bal = _records[t].balance;\n            uint tokenAmountIn = bmul(ratio, bal);\n            require(tokenAmountIn != 0, \"ERR_MATH_APPROX\");\n            require(tokenAmountIn <= maxAmountsIn[i], \"ERR_LIMIT_IN\");\n            _records[t].balance = badd(_records[t].balance, tokenAmountIn);\n            emit LOG_JOIN(msg.sender, t, tokenAmountIn);\n            _pullUnderlying(t, msg.sender, tokenAmountIn);\n        }\n        _mintPoolShare(poolAmountOut);\n        _pushPoolShare(msg.sender, poolAmountOut);\n    }\n\n    function exitPool(uint poolAmountIn, uint[] calldata minAmountsOut) external _logs_ _lock_ {\n        require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n        require(_finalized, \"ERR_NOT_FINALIZED\");\n\n        uint poolTotal = this.totalSupply();\n        uint ratio = bdiv(poolAmountIn, poolTotal);\n        require(ratio != 0, \"ERR_MATH_APPROX\");\n\n        _pullPoolShare(msg.sender, poolAmountIn);\n        _burnPoolShare(poolAmountIn);\n\n        for (uint i = 0; i < _tokens.length; i++) {\n            address t = _tokens[i];\n            uint bal = _records[t].balance;\n            uint tokenAmountOut = bmul(ratio, bal);\n            require(tokenAmountOut != 0, \"ERR_MATH_APPROX\");\n            require(tokenAmountOut >= minAmountsOut[i], \"ERR_LIMIT_OUT\");\n            _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\n            emit LOG_EXIT(msg.sender, t, tokenAmountOut);\n            _pushUnderlying(t, msg.sender, tokenAmountOut);\n        }\n    }\n\n    function _pullUnderlying(\n        address erc20,\n        address from,\n        uint amount\n    ) internal {\n        IERC20(erc20).safeTransferFrom(from, address(this), amount);\n    }\n\n    function _pushUnderlying(\n        address erc20,\n        address to,\n        uint amount\n    ) internal {\n        IERC20(erc20).safeTransfer(to, amount);\n    }\n\n    function _pullPoolShare(address from, uint amount) internal {\n        _pull(from, amount);\n    }\n\n    function _pushPoolShare(address to, uint amount) internal {\n        _push(to, amount);\n    }\n\n    function _mintPoolShare(uint amount) internal {\n        _mint(amount);\n    }\n\n    function _burnPoolShare(uint amount) internal {\n        _burn(amount);\n    }\n\n    receive() external payable {}\n}\n"
      },
      "contracts/base/LpToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity 0.6.12;\n\nimport \"./Num.sol\";\nimport \"../interfaces/IERC20.sol\";\n\n// Highly opinionated token implementation\n\ncontract LpTokenBase is Num {\n    mapping(address => uint) internal _balance;\n    mapping(address => mapping(address => uint)) internal _allowance;\n    uint internal _totalSupply;\n\n    event Approval(address indexed src, address indexed dst, uint amt);\n    event Transfer(address indexed src, address indexed dst, uint amt);\n\n    function _mint(uint amt) internal {\n        _balance[address(this)] = badd(_balance[address(this)], amt);\n        _totalSupply = badd(_totalSupply, amt);\n        emit Transfer(address(0), address(this), amt);\n    }\n\n    function _burn(uint amt) internal {\n        require(_balance[address(this)] >= amt, \"ERR_INSUFFICIENT_BAL\");\n        _balance[address(this)] = bsub(_balance[address(this)], amt);\n        _totalSupply = bsub(_totalSupply, amt);\n        emit Transfer(address(this), address(0), amt);\n    }\n\n    function _move(\n        address src,\n        address dst,\n        uint amt\n    ) internal {\n        require(_balance[src] >= amt, \"ERR_INSUFFICIENT_BAL\");\n        _balance[src] = bsub(_balance[src], amt);\n        _balance[dst] = badd(_balance[dst], amt);\n        emit Transfer(src, dst, amt);\n    }\n\n    function _push(address to, uint amt) internal {\n        _move(address(this), to, amt);\n    }\n\n    function _pull(address from, uint amt) internal {\n        _move(from, address(this), amt);\n    }\n}\n\ncontract LpToken is LpTokenBase, IERC20 {\n    string private _name = \"Desyn Pool Token\";\n    string private _symbol = \"DPT\";\n    uint8 private _decimals = 18;\n\n    function name() external view returns (string memory) {\n        return _name;\n    }\n\n    function symbol() external view override returns (string memory) {\n        return _symbol;\n    }\n\n    function decimals() external view override returns (uint8) {\n        return _decimals;\n    }\n\n    function allowance(address src, address dst) external view override returns (uint) {\n        return _allowance[src][dst];\n    }\n\n    function balanceOf(address whom) external view override returns (uint) {\n        return _balance[whom];\n    }\n\n    function totalSupply() external view override returns (uint) {\n        return _totalSupply;\n    }\n\n    function approve(address dst, uint amt) external override returns (bool) {\n        _allowance[msg.sender][dst] = amt;\n        emit Approval(msg.sender, dst, amt);\n        return true;\n    }\n\n    function increaseApproval(address dst, uint amt) external returns (bool) {\n        _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\n        emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\n        return true;\n    }\n\n    function decreaseApproval(address dst, uint amt) external returns (bool) {\n        uint oldValue = _allowance[msg.sender][dst];\n        if (amt > oldValue) {\n            _allowance[msg.sender][dst] = 0;\n        } else {\n            _allowance[msg.sender][dst] = bsub(oldValue, amt);\n        }\n        emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\n        return true;\n    }\n\n    function transfer(address dst, uint amt) external override returns (bool) {\n        require(dst != address(0),\"ERR_BAD_RECIVER\");\n        _move(msg.sender, dst, amt);\n        return true;\n    }\n\n    function transferFrom(\n        address src,\n        address dst,\n        uint amt\n    ) external override returns (bool) {\n        require(dst != address(0),\"ERR_BAD_RECIVER\");\n        require(msg.sender == src || amt <= _allowance[src][msg.sender], \"ERR_LPTOKEN_BAD_CALLER\");\n        _move(src, dst, amt);\n        if (msg.sender != src && _allowance[src][msg.sender] != uint(-1)) {\n            _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\n            emit Approval(src, msg.sender, _allowance[src][msg.sender]);\n        }\n        return true;\n    }\n}\n"
      },
      "contracts/base/Math.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity 0.6.12;\n\nimport \"./Num.sol\";\n\ncontract Math is BBronze, Const, Num {\n    /**********************************************************************************************\n    // calcSpotPrice                                                                             //\n    // sP = spotPrice                                                                            //\n    // bI = tokenBalanceIn                ( bI / wI )         1                                  //\n    // bO = tokenBalanceOut         sP =  -----------  *  ----------                             //\n    // wI = tokenWeightIn                 ( bO / wO )     ( 1 - sF )                             //\n    // wO = tokenWeightOut                                                                       //\n    // sF = swapFee                                                                              //\n    **********************************************************************************************/\n    function calcSpotPrice(\n        uint tokenBalanceIn,\n        uint tokenWeightIn,\n        uint tokenBalanceOut,\n        uint tokenWeightOut,\n        uint swapFee\n    ) external pure returns (uint spotPrice) {\n        uint numer = bdiv(tokenBalanceIn, tokenWeightIn);\n        uint denom = bdiv(tokenBalanceOut, tokenWeightOut);\n        uint ratio = bdiv(numer, denom);\n        uint scale = bdiv(BONE, bsub(BONE, swapFee));\n        return (spotPrice = bmul(ratio, scale));\n    }\n\n    /**********************************************************************************************\n    // calcOutGivenIn                                                                            //\n    // aO = tokenAmountOut                                                                       //\n    // bO = tokenBalanceOut                                                                      //\n    // bI = tokenBalanceIn              /      /            bI             \\    (wI / wO) \\      //\n    // aI = tokenAmountIn    aO = bO * |  1 - | --------------------------  | ^            |     //\n    // wI = tokenWeightIn               \\      \\ ( bI + ( aI * ( 1 - sF )) /              /      //\n    // wO = tokenWeightOut                                                                       //\n    // sF = swapFee                                                                              //\n    **********************************************************************************************/\n    function calcOutGivenIn(\n        uint tokenBalanceIn,\n        uint tokenWeightIn,\n        uint tokenBalanceOut,\n        uint tokenWeightOut,\n        uint tokenAmountIn,\n        uint swapFee\n    ) external pure returns (uint tokenAmountOut) {\n        uint weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\n        uint adjustedIn = bsub(BONE, swapFee);\n        adjustedIn = bmul(tokenAmountIn, adjustedIn);\n        uint y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\n        uint foo = bpow(y, weightRatio);\n        uint bar = bsub(BONE, foo);\n        tokenAmountOut = bmul(tokenBalanceOut, bar);\n        return tokenAmountOut;\n    }\n\n    /**********************************************************************************************\n    // calcInGivenOut                                                                            //\n    // aI = tokenAmountIn                                                                        //\n    // bO = tokenBalanceOut               /  /     bO      \\    (wO / wI)      \\                 //\n    // bI = tokenBalanceIn          bI * |  | ------------  | ^            - 1  |                //\n    // aO = tokenAmountOut    aI =        \\  \\ ( bO - aO ) /                   /                 //\n    // wI = tokenWeightIn           --------------------------------------------                 //\n    // wO = tokenWeightOut                          ( 1 - sF )                                   //\n    // sF = swapFee                                                                              //\n    **********************************************************************************************/\n    function calcInGivenOut(\n        uint tokenBalanceIn,\n        uint tokenWeightIn,\n        uint tokenBalanceOut,\n        uint tokenWeightOut,\n        uint tokenAmountOut,\n        uint swapFee\n    ) external pure returns (uint tokenAmountIn) {\n        uint weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\n        uint diff = bsub(tokenBalanceOut, tokenAmountOut);\n        uint y = bdiv(tokenBalanceOut, diff);\n        uint foo = bpow(y, weightRatio);\n        foo = bsub(foo, BONE);\n        tokenAmountIn = bsub(BONE, swapFee);\n        tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\n        return tokenAmountIn;\n    }\n\n    /**********************************************************************************************\n    // calcPoolOutGivenSingleIn                                                                  //\n    // pAo = poolAmountOut         /                                              \\              //\n    // tAi = tokenAmountIn        ///      /     //    wI \\      \\\\       \\     wI \\             //\n    // wI = tokenWeightIn        //| tAi *| 1 - || 1 - --  | * sF || + tBi \\    --  \\            //\n    // tW = totalWeight     pAo=||  \\      \\     \\\\    tW /      //         | ^ tW   | * pS - pS //\n    // tBi = tokenBalanceIn      \\\\  ------------------------------------- /        /            //\n    // pS = poolSupply            \\\\                    tBi               /        /             //\n    // sF = swapFee                \\                                              /              //\n    **********************************************************************************************/\n    function calcPoolOutGivenSingleIn(\n        uint tokenBalanceIn,\n        uint tokenWeightIn,\n        uint poolSupply,\n        uint totalWeight,\n        uint tokenAmountIn,\n        uint swapFee\n    ) external pure returns (uint poolAmountOut) {\n        // Charge the trading fee for the proportion of tokenAi\n        //  which is implicitly traded to the other pool tokens.\n        // That proportion is (1- weightTokenIn)\n        // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\n        uint normalizedWeight = bdiv(tokenWeightIn, totalWeight);\n        uint zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\n        uint tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\n\n        uint newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\n        uint tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\n\n        // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\n        uint poolRatio = bpow(tokenInRatio, normalizedWeight);\n        uint newPoolSupply = bmul(poolRatio, poolSupply);\n        poolAmountOut = bsub(newPoolSupply, poolSupply);\n        return poolAmountOut;\n    }\n\n    /**********************************************************************************************\n    // calcSingleInGivenPoolOut                                                                  //\n    // tAi = tokenAmountIn              //(pS + pAo)\\     /    1    \\\\                           //\n    // pS = poolSupply                 || ---------  | ^ | --------- || * bI - bI                //\n    // pAo = poolAmountOut              \\\\    pS    /     \\(wI / tW)//                           //\n    // bI = balanceIn          tAi =  --------------------------------------------               //\n    // wI = weightIn                              /      wI  \\                                   //\n    // tW = totalWeight                          |  1 - ----  |  * sF                            //\n    // sF = swapFee                               \\      tW  /                                   //\n    **********************************************************************************************/\n    function calcSingleInGivenPoolOut(\n        uint tokenBalanceIn,\n        uint tokenWeightIn,\n        uint poolSupply,\n        uint totalWeight,\n        uint poolAmountOut,\n        uint swapFee\n    ) external pure returns (uint tokenAmountIn) {\n        uint normalizedWeight = bdiv(tokenWeightIn, totalWeight);\n        uint newPoolSupply = badd(poolSupply, poolAmountOut);\n        uint poolRatio = bdiv(newPoolSupply, poolSupply);\n\n        //uint newBalTi = poolRatio^(1/weightTi) * balTi;\n        uint boo = bdiv(BONE, normalizedWeight);\n        uint tokenInRatio = bpow(poolRatio, boo);\n        uint newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\n        uint tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\n        // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\n        //     ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\n        //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\n        uint zar = bmul(bsub(BONE, normalizedWeight), swapFee);\n        tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\n        return tokenAmountIn;\n    }\n\n    /**********************************************************************************************\n    // calcSingleOutGivenPoolIn                                                                  //\n    // tAo = tokenAmountOut            /      /                                             \\\\   //\n    // bO = tokenBalanceOut           /      // pS - (pAi * (1 - eF)) \\     /    1    \\      \\\\  //\n    // pAi = poolAmountIn            | bO - || ----------------------- | ^ | --------- | * b0 || //\n    // ps = poolSupply                \\      \\\\          pS           /     \\(wO / tW)/      //  //\n    // wI = tokenWeightIn      tAo =   \\      \\                                             //   //\n    // tW = totalWeight                    /     /      wO \\       \\                             //\n    // sF = swapFee                    *  | 1 - |  1 - ---- | * sF  |                            //\n    // eF = exitFee                        \\     \\      tW /       /                             //\n    **********************************************************************************************/\n    function calcSingleOutGivenPoolIn(\n        uint tokenBalanceOut,\n        uint tokenWeightOut,\n        uint poolSupply,\n        uint totalWeight,\n        uint poolAmountIn,\n        uint swapFee\n    ) external pure returns (uint tokenAmountOut) {\n        uint normalizedWeight = bdiv(tokenWeightOut, totalWeight);\n        // charge exit fee on the pool token side\n        // pAiAfterExitFee = pAi*(1-exitFee)\n        uint poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\n        uint newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\n        uint poolRatio = bdiv(newPoolSupply, poolSupply);\n\n        // newBalTo = poolRatio^(1/weightTo) * balTo;\n        uint tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\n        uint newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\n\n        uint tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\n\n        // charge swap fee on the output token side\n        //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\n        uint zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\n        tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\n        return tokenAmountOut;\n    }\n\n    /**********************************************************************************************\n    // calcPoolInGivenSingleOut                                                                  //\n    // pAi = poolAmountIn               // /               tAo             \\\\     / wO \\     \\   //\n    // bO = tokenBalanceOut            // | bO - -------------------------- |\\   | ---- |     \\  //\n    // tAo = tokenAmountOut      pS - ||   \\     1 - ((1 - (tO / tW)) * sF)/  | ^ \\ tW /  * pS | //\n    // ps = poolSupply                 \\\\ -----------------------------------/                /  //\n    // wO = tokenWeightOut  pAi =       \\\\               bO                 /                /   //\n    // tW = totalWeight           -------------------------------------------------------------  //\n    // sF = swapFee                                        ( 1 - eF )                            //\n    // eF = exitFee                                                                              //\n    **********************************************************************************************/\n    function calcPoolInGivenSingleOut(\n        uint tokenBalanceOut,\n        uint tokenWeightOut,\n        uint poolSupply,\n        uint totalWeight,\n        uint tokenAmountOut,\n        uint swapFee\n    ) external pure returns (uint poolAmountIn) {\n        // charge swap fee on the output token side\n        uint normalizedWeight = bdiv(tokenWeightOut, totalWeight);\n        //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\n        uint zoo = bsub(BONE, normalizedWeight);\n        uint zar = bmul(zoo, swapFee);\n        uint tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\n\n        uint newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\n        uint tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\n\n        //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\n        uint poolRatio = bpow(tokenOutRatio, normalizedWeight);\n        uint newPoolSupply = bmul(poolRatio, poolSupply);\n        uint poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\n\n        // charge exit fee on the pool token side\n        // pAi = pAiAfterExitFee/(1-exitFee)\n        poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\n        return poolAmountIn;\n    }\n}\n"
      },
      "contracts/interfaces/IConfigurableRightsPool.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.6.12;\n\n// Interface declarations\n\n// Introduce to avoid circularity (otherwise, the CRP and SmartPoolManager include each other)\n// Removing circularity allows flattener tools to work, which enables Etherscan verification\ninterface IConfigurableRightsPool {\n    function mintPoolShareFromLib(uint amount) external;\n\n    function pushPoolShareFromLib(address to, uint amount) external;\n\n    function pullPoolShareFromLib(address from, uint amount) external;\n\n    function burnPoolShareFromLib(uint amount) external;\n\n    function balanceOf(address account) external view returns (uint);\n\n    function totalSupply() external view returns (uint);\n\n    function adminList(address) external view returns (bool);\n\n    function getController() external view returns (address);\n\n    function vaultAddress() external view returns (address);\n}\n"
      },
      "contracts/interfaces/IBFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\ninterface IBPool {\n    function rebind(\n        address token,\n        uint balance,\n        uint denorm\n    ) external;\n\n    function execute(\n        address _target,\n        uint _value,\n        bytes calldata _data\n    ) external returns (bytes memory _returnValue);\n\n    function bind(\n        address token,\n        uint balance,\n        uint denorm\n    ) external;\n\n    function unbind(address token) external;\n\n    function unbindPure(address token) external;\n\n    function isBound(address token) external view returns (bool);\n\n    function getBalance(address token) external view returns (uint);\n\n    function totalSupply() external view returns (uint);\n\n    function isPublicSwap() external view returns (bool);\n\n    function getDenormalizedWeight(address token) external view returns (uint);\n\n    function getTotalDenormalizedWeight() external view returns (uint);\n\n    function EXIT_FEE() external view returns (uint);\n\n    function getCurrentTokens() external view returns (address[] memory tokens);\n\n    function setController(address owner) external;\n}\n\ninterface IBFactory {\n    function newLiquidityPool() external returns (IBPool);\n\n    function setBLabs(address b) external;\n\n    function collect(IBPool pool) external;\n\n    function isBPool(address b) external view returns (bool);\n\n    function getBLabs() external view returns (address);\n\n    function getVault() external view returns (address);\n\n    function getUserVault() external view returns (address);\n\n    function getVaultAddress() external view returns (address);\n\n    function getOracleAddress() external view returns (address);\n\n    function isTokenWhitelistedForVerify(uint sort, address token) external view returns (bool);\n\n    function isTokenWhitelistedForVerify(address token) external view returns (bool);\n\n    function getModuleStatus(address etf, address module) external view returns (bool);\n\n    function isPaused() external view returns (bool);\n}\n\ninterface IVault {\n    function depositManagerToken(address[] calldata poolTokens, uint[] calldata tokensAmount) external;\n\n    function depositIssueRedeemPToken(\n        address[] calldata poolTokens,\n        uint[] calldata tokensAmount,\n        uint[] calldata tokensAmountP,\n        bool isPerfermance\n    ) external;\n\n    function managerClaim(address pool) external;\n\n    function getManagerClaimBool(address pool) external view returns (bool);\n}\n\ninterface IUserVault {\n    function recordTokenInfo(\n        address kol,\n        address user,\n        address[] calldata poolTokens,\n        uint[] calldata tokensAmount\n    ) external;\n}\n\ninterface Oracles {\n    function getPrice(address tokenAddress) external returns (uint price);\n\n    function getAllPrice(address[] calldata poolTokens, uint[] calldata tokensAmount) external returns (uint);\n}"
      },
      "contracts/libraries/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.12;\n\nimport {IERC20} from \"../interfaces/IERC20.sol\";\nimport {SafeMath} from \"./SafeMath.sol\";\nimport {Address} from \"./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 uint;\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint value\n    ) internal {\n        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint value\n    ) internal {\n        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint value\n    ) internal {\n        require((value == 0) || (token.allowance(address(this), spender) == 0), \"SafeERC20: approve from non-zero to non-zero allowance\");\n        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function callOptionalReturn(IERC20 token, bytes memory data) private {\n        require(address(token).isContract(), \"SafeERC20: call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = address(token).call(data);\n        require(success, \"SafeERC20: low-level call failed\");\n\n        if (returndata.length > 0) {\n            // 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"
      },
      "contracts/libraries/Address.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\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 {\n            codehash := extcodehash(account)\n        }\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, uint 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    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) 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(\n        address target,\n        bytes memory data,\n        uint value\n    ) 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(\n        address target,\n        bytes memory data,\n        uint value,\n        string memory errorMessage\n    ) 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(\n        address target,\n        bytes memory data,\n        uint weiValue,\n        string memory errorMessage\n    ) 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"
      },
      "contracts/base/Num.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.6.12;\n\nimport \"./Const.sol\";\n\n// Core contract; can't be changed. So disable solhint (reminder for v2)\n\n/* solhint-disable private-vars-leading-underscore */\n\ncontract Num is Const {\n    function btoi(uint a) internal pure returns (uint) {\n        return a / BONE;\n    }\n\n    function bfloor(uint a) internal pure returns (uint) {\n        return btoi(a) * BONE;\n    }\n\n    function badd(uint a, uint b) internal pure returns (uint) {\n        uint c = a + b;\n        require(c >= a, \"ERR_ADD_OVERFLOW\");\n        return c;\n    }\n\n    function bsub(uint a, uint b) internal pure returns (uint) {\n        (uint c, bool flag) = bsubSign(a, b);\n        require(!flag, \"ERR_SUB_UNDERFLOW\");\n        return c;\n    }\n\n    function bsubSign(uint a, uint b) internal pure returns (uint, bool) {\n        if (a >= b) {\n            return (a - b, false);\n        } else {\n            return (b - a, true);\n        }\n    }\n\n    function bmul(uint a, uint b) internal pure returns (uint) {\n        uint c0 = a * b;\n        require(a == 0 || c0 / a == b, \"ERR_MUL_OVERFLOW\");\n        uint c1 = c0 + (BONE / 2);\n        require(c1 >= c0, \"ERR_MUL_OVERFLOW\");\n        uint c2 = c1 / BONE;\n        return c2;\n    }\n\n    function bdiv(uint a, uint b) internal pure returns (uint) {\n        require(b != 0, \"ERR_DIV_ZERO\");\n        uint c0 = a * BONE;\n        require(a == 0 || c0 / a == BONE, \"ERR_DIV_INTERNAL\"); // bmul overflow\n        uint c1 = c0 + (b / 2);\n        require(c1 >= c0, \"ERR_DIV_INTERNAL\"); //  badd require\n        uint c2 = c1 / b;\n        return c2;\n    }\n\n    // DSMath.wpow\n    function bpowi(uint a, uint n) internal pure returns (uint) {\n        uint z = n % 2 != 0 ? a : BONE;\n\n        for (n /= 2; n != 0; n /= 2) {\n            a = bmul(a, a);\n\n            if (n % 2 != 0) {\n                z = bmul(z, a);\n            }\n        }\n        return z;\n    }\n\n    // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\n    // Use `bpowi` for `b^e` and `bpowK` for k iterations\n    // of approximation of b^0.w\n    function bpow(uint base, uint exp) internal pure returns (uint) {\n        require(base >= MIN_BPOW_BASE, \"ERR_BPOW_BASE_TOO_LOW\");\n        require(base <= MAX_BPOW_BASE, \"ERR_BPOW_BASE_TOO_HIGH\");\n\n        uint whole = bfloor(exp);\n        uint remain = bsub(exp, whole);\n\n        uint wholePow = bpowi(base, btoi(whole));\n\n        if (remain == 0) {\n            return wholePow;\n        }\n\n        uint partialResult = bpowApprox(base, remain, BPOW_PRECISION);\n        return bmul(wholePow, partialResult);\n    }\n\n    function bpowApprox(\n        uint base,\n        uint exp,\n        uint precision\n    ) internal pure returns (uint) {\n        // term 0:\n        uint a = exp;\n        (uint x, bool xneg) = bsubSign(base, BONE);\n        uint term = BONE;\n        uint sum = term;\n        bool negative = false;\n\n        // term(k) = numer / denom\n        //         = (product(a - i - 1, i=1-->k) * x^k) / (k!)\n        // each iteration, multiply previous term by (a-(k-1)) * x / k\n        // continue until term is less than precision\n        for (uint i = 1; term >= precision; i++) {\n            uint bigK = i * BONE;\n            (uint c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\n            term = bmul(term, bmul(c, x));\n            term = bdiv(term, bigK);\n            if (term == 0) break;\n\n            if (xneg) negative = !negative;\n            if (cneg) negative = !negative;\n            if (negative) {\n                sum = bsub(sum, term);\n            } else {\n                sum = badd(sum, term);\n            }\n        }\n\n        return sum;\n    }\n}\n"
      },
      "contracts/interfaces/IERC20.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.6.12;\n\n// Interface declarations\n\n/* solhint-disable func-order */\n\ninterface IERC20 {\n    // Emitted when the allowance of a spender for an owner is set by a call to approve.\n    // Value is the new allowance\n    event Approval(address indexed owner, address indexed spender, uint value);\n\n    // Emitted when value tokens are moved from one account (from) to another (to).\n    // Note that value may be zero\n    event Transfer(address indexed from, address indexed to, uint value);\n\n    // Returns the amount of tokens in existence\n    function totalSupply() external view returns (uint);\n\n    // Returns the amount of tokens owned by account\n    function balanceOf(address account) external view returns (uint);\n\n    // Returns the decimals of tokens\n    function decimals() external view returns (uint8);\n\n    function symbol() external view returns (string memory);\n\n    // Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner\n    // through transferFrom. This is zero by default\n    // This value changes when approve or transferFrom are called\n    function allowance(address owner, address spender) external view returns (uint);\n\n    // Sets amount as the allowance of spender over the caller’s tokens\n    // Returns a boolean value indicating whether the operation succeeded\n    // Emits an Approval event.\n    function approve(address spender, uint amount) external returns (bool);\n\n    // Moves amount tokens from the caller’s account to recipient\n    // Returns a boolean value indicating whether the operation succeeded\n    // Emits a Transfer event.\n    function transfer(address recipient, uint amount) external returns (bool);\n\n    // Moves amount tokens from sender to recipient using the allowance mechanism\n    // Amount is then deducted from the caller’s allowance\n    // Returns a boolean value indicating whether the operation succeeded\n    // Emits a Transfer event\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint amount\n    ) external returns (bool);\n}\n"
      },
      "contracts/base/Const.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.6.12;\n\nimport \"./Color.sol\";\n\ncontract Const is BBronze {\n    uint public constant BONE = 10**18;\n\n    uint public constant MIN_BOUND_TOKENS = 1;\n    uint public constant MAX_BOUND_TOKENS = 16;\n\n    uint public constant MIN_FEE = BONE / 10**6;\n    uint public constant MAX_FEE = BONE / 10;\n    uint public constant EXIT_FEE = 0;\n\n    uint public constant MIN_WEIGHT = BONE;\n    uint public constant MAX_WEIGHT = BONE * 50;\n    uint public constant MAX_TOTAL_WEIGHT = BONE * 50;\n    uint public constant MIN_BALANCE = 0;\n\n    uint public constant INIT_POOL_SUPPLY = BONE * 100;\n\n    uint public constant MIN_BPOW_BASE = 1 wei;\n    uint public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\n    uint public constant BPOW_PRECISION = BONE / 10**10;\n\n    uint public constant MAX_IN_RATIO = BONE / 2;\n    uint public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\n}\n"
      },
      "contracts/base/Color.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.6.12;\n\n// abstract contract BColor {\n//     function getColor()\n//         external view virtual\n//         returns (bytes32);\n// }\n\ncontract BBronze {\n    function getColor() external pure returns (bytes32) {\n        return bytes32(\"BRONZE\");\n    }\n}\n"
      },
      "contracts/libraries/SafeMath.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\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     * - Addition cannot overflow.\n     */\n    function add(uint a, uint b) internal pure returns (uint) {\n        uint 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     * - Subtraction cannot overflow.\n     */\n    function sub(uint a, uint b) internal pure returns (uint) {\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     * - Subtraction cannot overflow.\n     */\n    function sub(\n        uint a,\n        uint b,\n        string memory errorMessage\n    ) internal pure returns (uint) {\n        require(b <= a, errorMessage);\n        uint 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     * - Multiplication cannot overflow.\n     */\n    function mul(uint a, uint b) internal pure returns (uint) {\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        uint 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     * - The divisor cannot be zero.\n     */\n    function div(uint a, uint b) internal pure returns (uint) {\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     * - The divisor cannot be zero.\n     */\n    function div(\n        uint a,\n        uint b,\n        string memory errorMessage\n    ) internal pure returns (uint) {\n        // Solidity only automatically asserts when dividing by 0\n        require(b > 0, errorMessage);\n        uint 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     * - The divisor cannot be zero.\n     */\n    function mod(uint a, uint b) internal pure returns (uint) {\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     * - The divisor cannot be zero.\n     */\n    function mod(\n        uint a,\n        uint b,\n        string memory errorMessage\n    ) internal pure returns (uint) {\n        require(b != 0, errorMessage);\n        return a % b;\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 20
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}