GovernableLinearLiquidityPool.sol
1 pragma solidity >=0.6.0; 2 pragma experimental ABIEncoderV2; 3 4 import "./GovernableLiquidityPoolV2.sol"; 5 6 contract GovernableLinearLiquidityPool is GovernableLiquidityPoolV2 { 7 constructor(string memory _nm, string memory _sb, address _deployAddr, bool _onlyMintToOwner, address _owner) 8 GovernableLiquidityPoolV2(_nm, _sb, _deployAddr, _onlyMintToOwner, _owner) public {} 9 10 function name() override external view returns (string memory) { 11 return string(abi.encodePacked(_name_prefix, _name)); 12 } 13 14 function symbol() override external view returns (string memory) { 15 16 return string(abi.encodePacked(_symbol_prefix, _symbol)); 17 } 18 19 function writeOptions( 20 address _tk, 21 PricingParameters memory param, 22 uint volume, 23 address to 24 ) 25 internal 26 override 27 { 28 { 29 address poolAddr = address(this); 30 require(IOptionToken(_tk).writtenVolume(poolAddr).add(volume) <= param.bsStockSpread[0].toUint120(), "2 high vol"); 31 32 IOptionsExchange.OpenExposureInputs memory oEi; 33 34 oEi.symbols = new string[](1); 35 oEi.volume = new uint[](1); 36 oEi.isShort = new bool[](1); 37 oEi.isCovered = new bool[](1); 38 oEi.poolAddrs = new address[](1); 39 oEi.paymentTokens = new address[](1); 40 41 42 oEi.symbols[0] = IOptionToken(_tk).symbol(); 43 oEi.volume[0] = volume; 44 oEi.isShort[0] = true; 45 oEi.poolAddrs[0] = poolAddr; 46 //oEi.isCovered[0] = false; //expoliting default to save gas 47 //oEi.paymentTokens[0] = address(0); //exploiting default to save gas 48 49 50 exchange.openExposure( 51 oEi, 52 to 53 ); 54 } 55 56 require(calcFreeTradableBalance() > 0, "bal low"); 57 58 } 59 60 /* 61 TODO: 62 - FACTOR IN IF USER WANTS TO FILL THE TOTAL VOLUME THAT IT WILL MEAN THAT IT WILL BE THE MID MARKET PRICE? 63 */ 64 65 function calcOptPrice(PricingParameters memory p, Operation op, uint poolPosBuy, uint poolPosSell) 66 internal 67 override 68 view 69 returns (uint price) 70 { 71 uint skew = calcSkewSpread(p, op, poolPosBuy, poolPosSell); 72 uint spread = (op == Operation.BUY) ? p.bsStockSpread[2].add(fractionBase).sub(skew) : fractionBase.sub(p.bsStockSpread[2]).add(skew); 73 price = interpolator.interpolate( 74 getUdlPrice(p.udlFeed), 75 p.t0, 76 p.t1, 77 p.x, 78 p.y, 79 spread 80 ); 81 } 82 83 function calcSkewSpread(PricingParameters memory p, Operation op, uint poolPosBuy, uint poolPosSell) private pure returns (uint skew) { 84 uint skewBuy = (p.bsStockSpread[0] > 0) ? poolPosBuy.mul(p.bsStockSpread[2]).div(p.bsStockSpread[0]) : 0; //buy expo / max buy expo * spread 85 uint skewSell = (p.bsStockSpread[1] > 0) ? poolPosSell.mul(p.bsStockSpread[2]).div(p.bsStockSpread[1]) : 0; //sell expo / max sell expo * spread 86 87 skew = (op == Operation.BUY) ? ( 88 (skewBuy > skewSell) ? 0 : skewSell //when pricing when someone wants to buy, if buy volume greater than sell volume, no discount, else discount back to mid 89 ) : ( 90 (skewBuy > skewSell) ? skewBuy : 0 //when pricing when someone wants to sell, if buy volume greater than sell volume, discount back to mid, else no discount 91 ); 92 } 93 94 function calcVolume( 95 string memory optSymbol, 96 PricingParameters memory p, 97 uint price, 98 Operation op, 99 uint poolPos 100 ) 101 internal 102 override 103 view 104 returns (uint volume) 105 { 106 uint r = fractionBase.sub(reserveRatio); 107 108 uint coll = exchange.calcCollateral( 109 p.udlFeed, 110 volumeBase, 111 p.optType, 112 p.strike, 113 p.maturity 114 ); 115 116 if (op == Operation.BUY) { 117 volume = coll <= price ? uint(-1) : 118 calcFreeTradableBalance().mul(volumeBase).div( 119 //calcFreeBalance().mul(volumeBase).div( 120 coll.sub(price.mul(r).div(fractionBase)) 121 ).add(poolPos); 122 123 //balance in pool / (collateral per 1 option - premium recived per option) 124 125 } else { 126 127 uint bal = calcFreeTradableBalance(); 128 129 uint poolColl = exchange.collateral(address(this)); 130 131 uint writtenColl = IOptionToken( 132 exchange.resolveToken(optSymbol) 133 ).writtenVolume(address(this)).mul(coll); 134 135 poolColl = poolColl > writtenColl ? poolColl.sub(writtenColl) : 0; 136 137 uint iv = uint(exchange.calcIntrinsicValue( 138 p.udlFeed, 139 p.optType, 140 p.strike, 141 p.maturity 142 )); 143 144 volume = price <= iv ? uint(-1) : 145 bal.sub(poolColl.mul(fractionBase).div(r)).mul(volumeBase).div( 146 price.sub(iv) 147 ).add(poolPos); 148 149 uint balMulDiv = bal.mul(volumeBase).div(price); 150 151 volume = MoreMath.min( 152 MoreMath.max( 153 volume, 154 balMulDiv 155 ), 156 balMulDiv 157 ); 158 } 159 } 160 }