/ contracts / pools / GovernableLinearLiquidityPool.sol
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  }