/ contracts / pools / LinearLiquidityPool.sol
LinearLiquidityPool.sol
  1  pragma experimental ABIEncoderV2;
  2  pragma solidity >=0.6.0;
  3  
  4  import "./LinearInterpolator.sol";
  5  import "./LiquidityPool.sol";
  6  
  7  contract LinearLiquidityPool is LiquidityPool {
  8      
  9      LinearInterpolator private interpolator;
 10  
 11      string private constant _name = "Linear Liquidity Pool Redeemable Token";
 12      string private constant _symbol = "LLPTK";
 13  
 14      constructor() LiquidityPool(_name) public {
 15          
 16      }
 17  
 18      function initialize(Deployer deployer) override internal {
 19  
 20          super.initialize(deployer);
 21          interpolator = LinearInterpolator(deployer.getContractAddress("LinearInterpolator"));
 22      }
 23  
 24      function name() override external view returns (string memory) {
 25          return _name;
 26      }
 27  
 28      function symbol() override external view returns (string memory) {
 29          return _symbol;
 30      }
 31  
 32      function writeOptions(
 33          IOptionToken tk,
 34          PricingParameters memory param,
 35          uint volume,
 36          address to
 37      )
 38          internal
 39          override
 40      {
 41          require(tk.writtenVolume(address(this)).add(volume) <= param.buyStock, "excessive volume");
 42  
 43          IOptionsExchange.OpenExposureInputs memory oEi;
 44          
 45          oEi.symbols[0] = tk.symbol();
 46          oEi.volume[0] = volume;
 47          oEi.isShort[0] = true;
 48          oEi.isCovered[0] = false;
 49          oEi.poolAddrs[0] = address(this);
 50          oEi.paymentTokens[0] = address(0);
 51  
 52          exchange.openExposure(
 53              oEi,
 54              to
 55          );
 56          
 57          require(calcFreeBalance() > 0, "pool balance too low");
 58      }
 59  
 60      function calcOptPrice(PricingParameters memory p, Operation op)
 61          internal
 62          override
 63          view
 64          returns (uint)
 65      {
 66          return interpolator.interpolate(
 67              getUdlPrice(p.udlFeed),
 68              p.t0,
 69              p.t1,
 70              p.x,
 71              p.y,
 72              op == Operation.BUY ? spread.add(fractionBase) : fractionBase.sub(spread)
 73          );
 74      }
 75  
 76      function calcVolume(
 77          string memory optSymbol,
 78          PricingParameters memory p,
 79          uint price,
 80          Operation op
 81      )
 82          internal
 83          override
 84          view
 85          returns (uint volume)
 86      {
 87          uint r = fractionBase.sub(reserveRatio);
 88  
 89          uint coll = exchange.calcCollateral(
 90              p.udlFeed,
 91              volumeBase,
 92              p.optType,
 93              p.strike,
 94              p.maturity
 95          );
 96  
 97          if (op == Operation.BUY) {
 98  
 99              volume = coll <= price ? uint(-1) :
100                  calcFreeBalance().mul(volumeBase).div(
101                      coll.sub(price.mul(r).div(fractionBase))
102                  );
103  
104          } else {
105  
106              uint bal = exchange.balanceOf(address(this));
107  
108              uint poolColl = exchange.collateral(address(this));
109  
110              uint writtenColl = IOptionToken(
111                  exchange.resolveToken(optSymbol)
112              ).writtenVolume(address(this)).mul(coll);
113  
114              poolColl = poolColl > writtenColl ? poolColl.sub(writtenColl) : 0;
115              
116              uint iv = uint(exchange.calcIntrinsicValue(
117                  p.udlFeed,
118                  p.optType,
119                  p.strike,
120                  p.maturity
121              ));
122  
123              volume = price <= iv ? uint(-1) :
124                  bal.sub(poolColl.mul(fractionBase).div(r)).mul(volumeBase).div(
125                      price.sub(iv)
126                  );
127  
128              volume = MoreMath.max(
129                  volume, 
130                  bal.mul(volumeBase).div(price)
131              );
132  
133              volume = MoreMath.min(
134                  volume, 
135                  bal.mul(volumeBase).div(price)
136              );
137          }
138      }
139  }