/ test / finance / OptionsExchange / Base.t.sol
Base.t.sol
  1  pragma solidity >=0.6.0;
  2  
  3  import "truffle/Assert.sol";
  4  
  5  //import "truffle/DeployedAddresses.sol";
  6  
  7  import "../../../contracts/deployment/Deployer.sol";
  8  import "../../../contracts/finance/credit/CreditProvider.sol";
  9  import "../../../contracts/finance/OptionsExchange.sol";
 10  import "../../../contracts/finance/collateral/CollateralManager.sol";
 11  import "../../../contracts/finance/credit/CreditToken.sol";
 12  import "../../../contracts/finance/UnderlyingVault.sol";
 13  import "../../../contracts/finance/Incentivized.sol";
 14  import "../../../contracts/finance/OptionTokenFactory.sol";
 15  import "../../../contracts/finance/PendingExposureRouter.sol";
 16  import "../../../contracts/finance/YieldTracker.sol";
 17  
 18  import "../../../contracts/feeds/DEXFeedFactory.sol";
 19  import "../../../contracts/pools/LinearLiquidityPoolFactory.sol";
 20  import "../../../contracts/pools/LinearAnySlopeInterpolator.sol";
 21  
 22  import "../../../contracts/finance/credit/UnderlyingCreditProviderFactory.sol";
 23  import "../../../contracts/finance/credit/UnderlyingCreditTokenFactory.sol";
 24  import "../../../contracts/governance/ProtocolSettings.sol";
 25  import "../../../contracts/governance/ProposalsManager.sol";
 26  import "../../../contracts/governance/GovToken.sol";
 27  
 28  import "../../../contracts/finance/OptionToken.sol";
 29  import "../../../contracts/interfaces/IOptionsExchange.sol";
 30  
 31  import "../../common/actors/OptionsTrader.t.sol";
 32  import "../../common/mock/ERC20Mock.t.sol";
 33  import "../../common/mock/EthFeedMock.t.sol";
 34  import "../../common/mock/TimeProviderMock.t.sol";
 35  import "../../common/mock/UniswapV2RouterMock.t.sol";
 36  import "../../common/samples/SimplePoolManagementProposal.t.sol";
 37  
 38  contract Base {
 39      
 40      int ethInitialPrice = 550e18;
 41      uint lowerVol;
 42      uint upperVol;
 43      
 44      uint err = 1; // rounding error
 45      uint cBase = 1e8; // comparison base
 46      uint volumeBase = 1e18;
 47      uint timeBase = 1 hours;
 48      uint underlyingBase;
 49  
 50      address[] traders;
 51      address router;
 52      address pool;
 53      address symbolAddr;
 54      string symbol;
 55  
 56      EthFeedMock feed;
 57      ERC20Mock erc20;
 58      ERC20Mock underlying;
 59      TimeProviderMock time;
 60  
 61      ProtocolSettings settings;
 62      CreditProvider creditProvider;
 63      CreditToken creditToken;
 64      OptionsExchange exchange;
 65      CollateralManager collateralManager;
 66      
 67      OptionsTrader bob;
 68      OptionsTrader alice;
 69  
 70      uint120[] x;
 71      uint120[] y;
 72      uint256[3] bsStockSpread;
 73      
 74      IOptionsExchange.OptionType CALL = IOptionsExchange.OptionType.CALL;
 75      IOptionsExchange.OptionType PUT = IOptionsExchange.OptionType.PUT;
 76  
 77      Deployer deployer;
 78  
 79      
 80      //function beforeEachDeploy() public {
 81      function setUp() public {
 82  
 83          deployer = new Deployer(address(this));
 84          deployer.setContractAddress("ProtocolSettings", address(new ProtocolSettings(true)));
 85          deployer.setContractAddress("TimeProvider", address(new TimeProviderMock()));
 86          deployer.setContractAddress("CreditProvider", address(new CreditProvider()));
 87          deployer.addAlias("CreditIssuer", "CreditProvider");
 88          deployer.setContractAddress("CreditToken", address(new CreditToken()));
 89          
 90          deployer.setContractAddress("ProposalsManager", address(new ProposalsManager()));
 91          deployer.setContractAddress("GovToken", address(new GovToken(address(0))));
 92          deployer.setContractAddress("CollateralManager", address(new CollateralManager()));
 93          deployer.setContractAddress("OptionsExchange", address(new OptionsExchange()));
 94          deployer.setContractAddress("OptionTokenFactory", address(new OptionTokenFactory()));
 95          deployer.setContractAddress("UnderlyingVault", address(new UnderlyingVault()));
 96          deployer.setContractAddress("Incentivized", address(new Incentivized()));
 97          deployer.setContractAddress("UnderlyingCreditProviderFactory", address(new UnderlyingCreditProviderFactory()));
 98          deployer.setContractAddress("UnderlyingCreditTokenFactory", address(new UnderlyingCreditTokenFactory()));
 99          deployer.setContractAddress("LinearLiquidityPoolFactory", address(new LinearLiquidityPoolFactory()));
100          deployer.setContractAddress("YieldTracker", address(new YieldTracker()));
101          deployer.setContractAddress("DEXFeedFactory", address(new DEXFeedFactory()));
102          deployer.setContractAddress("Interpolator", address(new LinearAnySlopeInterpolator()));
103          deployer.setContractAddress("PendingExposureRouter", address(new PendingExposureRouter()));
104  
105  
106          deployer.setContractAddress("UnderlyingToken", address(new ERC20Mock(18)), false);
107          deployer.setContractAddress("UnderlyingFeed", address(new EthFeedMock()));
108          deployer.setContractAddress("SwapRouter", address(new UniswapV2RouterMock()));
109          deployer.setContractAddress("StablecoinA", address(new ERC20Mock(18)), false);
110          deployer.deploy(address(this));
111  
112          time = TimeProviderMock(deployer.getContractAddress("TimeProvider"));
113          feed = EthFeedMock(deployer.getContractAddress("UnderlyingFeed"));
114          settings = ProtocolSettings(deployer.getContractAddress("ProtocolSettings"));
115          creditProvider = CreditProvider(deployer.getContractAddress("CreditProvider"));
116          creditToken = CreditToken(deployer.getContractAddress("CreditToken"));
117          exchange = OptionsExchange(deployer.getContractAddress("OptionsExchange"));
118          erc20 = ERC20Mock(deployer.getContractAddress("StablecoinA"));
119          router = deployer.getContractAddress("SwapRouter");
120          pool = exchange.createPool("DEFAULT", "TEST", false, address(0));
121          collateralManager = CollateralManager(deployer.getContractAddress("CollateralManager"));
122          erc20.reset();
123  
124          settings.setAllowedToken(address(erc20), 1, 1);
125          settings.setUdlFeed(address(feed), 1);
126          underlying = ERC20Mock(feed.getUnderlyingAddr());
127          underlyingBase = 10 ** uint(underlying.decimals());
128          underlying.reset();
129  
130          bob = createTrader();
131          alice = createTrader();
132          
133          uint vol = feed.getDailyVolatility(182 days);
134          lowerVol = feed.calcLowerVolatility(vol);
135          upperVol = feed.calcUpperVolatility(vol);
136  
137  
138          erc20.issue(address(this), 1000e18);
139          erc20.approve(pool, 1000e18);
140          IGovernableLiquidityPool(pool).depositTokens(address(this), address(erc20), 1000e18);
141          
142          //initialize proposal manager with set parameters propsoal data
143          SimplePoolManagementProposal pp = new SimplePoolManagementProposal();
144          pp.setExecutionBytes(
145              abi.encodeWithSelector(
146                  bytes4(keccak256("setParameters(uint256,uint256,uint256,uint256,address,uint256)")),
147                  0,
148                  0,
149                  time.getNow() + 365 days,
150                  10,
151                  address(0),
152                  1000e18
153              )
154          );
155          //registered proposal
156          (uint pid, address proposalWrapperAddr) = IProposalManager(
157              deployer.getContractAddress("ProposalsManager")
158          ).registerProposal(
159              address(pp),
160              pool,
161              IProposalManager.Quorum.QUADRATIC,
162              IProposalManager.VoteType.POOL_SETTINGS,
163              time.getNow() + 1 hours
164          );
165  
166          
167          //vote on proposal
168          IProposalWrapper(proposalWrapperAddr).castVote(true);
169          //close proposal
170          IProposalWrapper(proposalWrapperAddr).close();
171          IGovernableLiquidityPool(pool).withdraw(1000e18);
172  
173          feed.setPrice(ethInitialPrice);
174          time.setTimeOffset(0);
175  
176      }
177  
178      function createTrader() internal returns (OptionsTrader) {
179  
180          OptionsTrader td = new OptionsTrader(address(exchange), pool, address(settings), address(collateralManager), address(creditProvider), address(time), address(feed));
181          traders.push(address(td));
182          return td;
183      }
184  
185      function depositTokens(address to, uint value) internal {
186          
187          erc20.issue(address(this), value);
188          erc20.approve(address(exchange), value);
189          exchange.depositTokens(to, address(erc20), value);
190      }
191  
192      function getBookLength() internal view returns (uint total) {
193      /*
194          returns (
195              string memory symbols,
196              address[] memory tokens,
197              uint[] memory holding,
198              uint[] memory written,
199              uint[] memory uncovered,
200              int[] memory iv,
201              address[] memory underlying
202          )
203      */
204          total = 0;
205          for (uint i = 0; i < traders.length; i++) {
206              (,,uint[] memory holding,,,,) = exchange.getBook(traders[i]);
207              total += holding.length;
208          }
209      }
210  
211      function addSymbol(uint strike, uint maturity) internal {
212  
213          x = [400e18, 450e18, 500e18, 550e18, 600e18, 650e18, 700e18];
214          y = [
215              30e18,  40e18,  50e18,  50e18, 110e18, 170e18, 230e18,
216              25e18,  35e18,  45e18,  45e18, 105e18, 165e18, 225e18
217          ];
218  
219          bsStockSpread = [
220              100 * volumeBase, // buy stock
221              200 * volumeBase,  // sell stock
222              5e7 //5%
223          ];        
224  
225          erc20.issue(address(this), 1000e18);
226          erc20.approve(pool, 1000e18);
227          IGovernableLiquidityPool(pool).depositTokens(address(this), address(erc20), 1000e18);
228  
229  
230          //initialize proposal manager with addSymbol propsoal data
231          SimplePoolManagementProposal pp = new SimplePoolManagementProposal();
232          pp.setExecutionBytes(
233              abi.encodeWithSelector(
234                  //bytes4(
235                  //    keccak256("addSymbol(address,uint256,uint256,IOptionsExchange.OptionType,uint256,uint256,uint120[],uint120[],uint256[3])")
236                  //),
237                  IGovernableLiquidityPool(pool).addSymbol.selector,
238                  address(feed),
239                  strike,
240                  maturity,
241                  CALL,
242                  time.getNow(),
243                  time.getNow() + 1 days,
244                  x,
245                  y,
246                  bsStockSpread
247              )
248          );
249  
250          //registered proposal
251          (uint pid, address proposalWrapperAddr) = IProposalManager(
252              deployer.getContractAddress("ProposalsManager")
253          ).registerProposal(
254              address(pp),
255              pool,
256              IProposalManager.Quorum.QUADRATIC,
257              IProposalManager.VoteType.POOL_SETTINGS,
258              time.getNow() + 1 hours
259          );        
260          //vote on proposal
261          IProposalWrapper(proposalWrapperAddr).castVote(true);
262          //close proposal
263          IProposalWrapper(proposalWrapperAddr).close();
264      }
265  
266      function liquidateAndRedeem(address _tk) internal {
267  
268          collateralManager.liquidateExpired(_tk, traders);
269          OptionToken(_tk).redeem(traders);
270      }
271  }