/ test / common / actors / OptionsTrader.t.sol
OptionsTrader.t.sol
  1  pragma solidity >=0.6.0;
  2  pragma experimental ABIEncoderV2;
  3  
  4  import "../../../contracts/finance/OptionsExchange.sol";
  5  import "../../../contracts/governance/ProtocolSettings.sol";
  6  import "../../../contracts/finance/credit/CreditProvider.sol";
  7  import "../../../contracts/interfaces/TimeProvider.sol";
  8  import "../../../contracts/interfaces/UnderlyingFeed.sol";
  9  import "../../../contracts/interfaces/ICollateralManager.sol";
 10  import "../../../contracts/interfaces/IOptionsExchange.sol";
 11  import "../../../contracts/interfaces/IOptionToken.sol";
 12  import "../../../contracts/interfaces/IGovernableLiquidityPool.sol";
 13  
 14  contract OptionsTrader {
 15      
 16      OptionsExchange private exchange;
 17      CreditProvider private creditProvider;
 18      TimeProvider private time;
 19      ProtocolSettings private settings;
 20      ICollateralManager private collateralManager;
 21      IGovernableLiquidityPool private pool;
 22  
 23      address private addr;
 24      address private feed;
 25      uint private volumeBase = 1e18;
 26      
 27      constructor(address _exchange, address _pool, address _protocol_settings, address _credit_provider, address _collateral_manager, address _time, address _feed) public {
 28  
 29          exchange = OptionsExchange(_exchange);
 30          creditProvider = CreditProvider(_credit_provider);
 31          collateralManager = ICollateralManager(_collateral_manager);
 32          settings = ProtocolSettings(_protocol_settings);
 33          pool = IGovernableLiquidityPool(_pool);
 34          time = TimeProvider(_time);
 35          addr = address(this);
 36          feed = _feed;
 37  
 38      }
 39      
 40      function balance() public view returns (uint) {
 41          
 42          return exchange.balanceOf(addr);
 43      }
 44      
 45      function approve(address spender, uint value) public {
 46          
 47          exchange.approve(spender, value);
 48      }
 49      
 50      function withdrawTokens() public {
 51          address[] memory tokens = settings.getAllowedTokens();        
 52          uint[] memory amount = new uint[](1); 
 53          amount[0] = calcSurplus();
 54  
 55          address[] memory tokenArray = new address[](1); 
 56          tokenArray[0] = tokens[0];
 57          //exchange.withdrawTokens(tokenArray, amount);
 58  
 59          (bool success2,) = address(this).call(
 60              abi.encodePacked(
 61                  exchange.withdrawTokens.selector,
 62                  abi.encode(tokens, amount)
 63              )
 64          );
 65      }
 66      
 67      function withdrawTokens(uint amount) public {
 68          address[] memory tokens = settings.getAllowedTokens();
 69          uint[] memory amountArray = new uint[](1); 
 70          amountArray[0] = amount;
 71  
 72          address[] memory tokenArray = new address[](1); 
 73          tokenArray[0] = tokens[0];
 74          (bool success2,) = address(this).call(
 75              abi.encodePacked(
 76                  exchange.withdrawTokens.selector,
 77                  abi.encode(tokenArray, amountArray)
 78              )
 79          );
 80  
 81  
 82      }
 83  
 84      function writeOption(
 85          IOptionsExchange.OptionType optType,
 86          int strike, 
 87          uint timeTomaturity,
 88          address pool
 89      )
 90          public
 91          returns (address _tk)
 92      {
 93          _tk = writeOptions(1, optType, strike, timeTomaturity, pool);
 94      }
 95  
 96      function writeOptions(
 97          uint volume,
 98          IOptionsExchange.OptionType optType,
 99          int strike, 
100          uint timeToMaturity,
101          address pool
102      )
103          public
104          returns (address _tk)
105      {
106  
107          IOptionsExchange.OpenExposureInputs memory oEi;
108  
109          oEi.symbols = new string[](1);
110          oEi.volume = new uint[](1);
111          oEi.isShort = new bool[](1);
112          oEi.isCovered = new bool[](1);
113          oEi.poolAddrs = new address[](1);
114          oEi.paymentTokens = new address[](1);
115  
116  
117          oEi.symbols[0] = IOptionToken(_tk).symbol();
118          oEi.volume[0] = volume * volumeBase;
119          oEi.isShort[0] = true;
120          oEi.poolAddrs[0] = pool;//poolAddr;
121          //oEi.isCovered[0] = false; //expoliting default to save gas
122          //oEi.paymentTokens[0] = address(0); //exploiting default to save gas
123  
124  
125          (bool success,) = address(this).call(
126              abi.encodePacked(
127                  exchange.openExposure.selector,
128                  abi.encode(oEi, address(this))
129              )
130          );
131      }
132  
133      function liquidateOptions(address _tk) public {
134          
135          collateralManager.liquidateOptions(_tk, address(this));
136      }
137  
138      function transferOptions(address to, address _tk, uint volume) public {
139  
140          IOptionToken(_tk).transfer(to, volume * volumeBase);
141      }
142  
143      function burnOptions(address _tk, uint volume) public {
144  
145          IOptionToken(_tk).burn(volume * volumeBase);
146      }
147      
148      function calcCollateral() public view returns (uint) {
149          
150          return exchange.calcCollateral(addr, true);
151      }
152      
153      function calcSurplus() public view returns (uint) {
154          
155          return exchange.calcSurplus(addr);
156      }
157      
158      function calcDebt() public view returns (uint) {
159          
160          return creditProvider.calcDebt(addr);
161      }
162  
163      function queryBuy(string memory symbol)
164          public
165          view
166          returns (uint price, uint volume)
167      {
168          price = uint(exchange.calcIntrinsicValue(
169              exchange.resolveToken(symbol)
170          ));
171          volume = 0;
172      }
173  
174      function querySell(string memory symbol)
175          public
176          view
177          returns (uint price, uint volume)
178      {    
179          price = uint(exchange.calcIntrinsicValue(
180              exchange.resolveToken(symbol)
181          ));
182          volume = 0;
183      }
184  }