/ test / finance / OptionsExchange / TestWriteOptions.t.sol
TestWriteOptions.t.sol
  1  pragma solidity >=0.6.0;
  2  
  3  import "truffle/Assert.sol";
  4  import "../../../contracts/finance/OptionToken.sol";
  5  import "../../../contracts/utils/MoreMath.sol";
  6  import "../../common/actors/OptionsTrader.t.sol";
  7  import "../../common/utils/MoreAssert.t.sol";
  8  import "./Base.t.sol";
  9  
 10  contract TestWriteOptions is Base {
 11  
 12      function testWriteWithoutCollateral() public {
 13          
 14          (bool success,) = address(bob).call(
 15              abi.encodePacked(
 16                  bob.writeOption.selector,
 17                  abi.encode(CALL, ethInitialPrice, 10, pool)
 18              )
 19          );
 20          
 21          Assert.isFalse(success, "issue should fail");
 22      }
 23  
 24      function testWriteAndSequentialTransfers() public {
 25  
 26          int step = 40e18;
 27          uint vBase = 1e24;
 28          uint ct = MoreMath.sqrtAndMultiply(15, upperVol);
 29          
 30          depositTokens(address(bob), 5000 * vBase);
 31  
 32          address _tk = bob.writeOptions(10, CALL, ethInitialPrice - step, 15 days, pool);
 33  
 34          (bool success1,) = address(this).call(
 35              abi.encodePacked(
 36                  bob.writeOptions.selector,
 37                  abi.encode(10, CALL, ethInitialPrice - step, 15 days, pool)
 38              )
 39          );
 40          MoreAssert.equal(bob.calcCollateral(), 10 * ct, cBase, "collateral none transfered");
 41  
 42          //bob.transferOptions(address(alice), _tk, 1);
 43          MoreAssert.equal(bob.calcCollateral(), 10 * ct + 1 * uint(step), cBase, "collateral '1' transfered");
 44  
 45          //bob.transferOptions(address(alice), _tk, 2);
 46          MoreAssert.equal(bob.calcCollateral(), 10 * ct + 3 * uint(step), cBase, "collateral '3' transfered");
 47  
 48          //bob.transferOptions(address(alice), _tk, 3);
 49          MoreAssert.equal(bob.calcCollateral(), 10 * ct + 6 * uint(step), cBase, "collateral '6' transfered");
 50  
 51          OptionToken tk = OptionToken(_tk);
 52          
 53          Assert.equal(tk.writtenVolume(address(bob)), 10 * volumeBase, "bob written volume");
 54          Assert.equal(tk.balanceOf(address(bob)), 4 * volumeBase, "bob options");
 55          Assert.equal(tk.writtenVolume(address(alice)), 0, "alice written volume");
 56          Assert.equal(tk.balanceOf(address(alice)), 6 * volumeBase, "alice options");
 57          Assert.equal(tk.totalSupply(), 10 * volumeBase, "total supply");
 58  
 59          Assert.equal(getBookLength(), 2, "book length");
 60      }
 61  
 62      function testWriteAndDistribute() public {
 63  
 64          uint ct = exchange.calcCollateral(
 65              address(feed), 
 66              1100 * volumeBase, 
 67              CALL, 
 68              uint(ethInitialPrice), 
 69              time.getNow() + 30 days
 70          );
 71          depositTokens(address(bob), ct);
 72          address _tk = bob.writeOptions(1100, CALL, ethInitialPrice, 30 days, pool);
 73  
 74          Assert.equal(getBookLength(), 1, "book length t0");
 75  
 76          OptionsTrader h1 = createTrader();
 77          OptionsTrader h2 = createTrader();
 78          OptionsTrader h3 = createTrader();
 79          OptionsTrader h4 = createTrader();
 80  
 81          bob.transferOptions(address(h1), _tk, 100);
 82          bob.transferOptions(address(h2), _tk, 200);
 83          bob.transferOptions(address(h3), _tk, 300);
 84          bob.transferOptions(address(h4), _tk, 400);
 85  
 86          OptionToken tk = OptionToken(_tk);
 87  
 88          Assert.equal(tk.balanceOf(address(bob)), 100 * volumeBase, "bob options");
 89          Assert.equal(tk.balanceOf(address(h1)), 100 * volumeBase, "h1 options");
 90          Assert.equal(tk.balanceOf(address(h2)), 200 * volumeBase, "h2 options");
 91          Assert.equal(tk.balanceOf(address(h3)), 300 * volumeBase, "h3 options");
 92          Assert.equal(tk.balanceOf(address(h4)), 400 * volumeBase, "h4 options");
 93  
 94          Assert.equal(getBookLength(), 5, "book length t1");
 95  
 96          h1.transferOptions(address(h2), _tk, 100);
 97          h3.transferOptions(address(h2), _tk, 100);
 98          h4.transferOptions(address(h2), _tk, 100);
 99  
100          Assert.equal(tk.balanceOf(address(bob)), 100 * volumeBase, "bob options");
101          Assert.equal(tk.balanceOf(address(h1)), 0, "h1 options");
102          Assert.equal(tk.balanceOf(address(h2)), 500 * volumeBase, "h2 options");
103          Assert.equal(tk.balanceOf(address(h3)), 200 * volumeBase, "h3 options");
104          Assert.equal(tk.balanceOf(address(h4)), 300 * volumeBase, "h4 options");
105  
106          Assert.equal(tk.writtenVolume(address(bob)), 1100 * volumeBase, "bob written volume");
107          Assert.equal(getBookLength(), 4, "book length t2");
108      }
109  
110      function testWriteAndBurn() public {
111  
112          int step = 40e18;
113          uint vBase = 1e24;
114          uint ct = MoreMath.sqrtAndMultiply(15, upperVol);
115          
116          depositTokens(address(bob), 5000 * vBase);
117  
118          address _tk = bob.writeOptions(10, CALL, ethInitialPrice - step, 15 days, pool);
119  
120          //bob.transferOptions(address(alice), _tk, 5);
121          MoreAssert.equal(bob.calcCollateral(), 10 * ct + 5 * uint(step), cBase, "collateral before burn");
122  
123          OptionToken tk = OptionToken(_tk);
124  
125          Assert.equal(tk.writtenVolume(address(bob)), 10 * volumeBase, "bob written volume");
126          Assert.equal(tk.balanceOf(address(bob)), 5 * volumeBase, "bob options");
127          Assert.equal(tk.balanceOf(address(alice)), 5 * volumeBase, "alice options");
128          Assert.equal(tk.totalSupply(), 10 * volumeBase, "total supply");
129  
130          bob.burnOptions(_tk, 5);
131  
132          MoreAssert.equal(bob.calcCollateral(), 5 * ct + 5 * uint(step), cBase, "collateral after burn");
133  
134          Assert.equal(tk.writtenVolume(address(bob)), 5 * volumeBase, "bob written volume");
135          Assert.equal(tk.balanceOf(address(bob)), 0, "bob options");
136          Assert.equal(tk.balanceOf(address(alice)), 5 * volumeBase, "alice options");
137          Assert.equal(tk.totalSupply(), 5 * volumeBase, "total supply");
138  
139          Assert.equal(getBookLength(), 2, "book length");
140      }
141  
142      function testWriteSameMultipleTimes() public {
143  
144          uint ct = exchange.calcCollateral(
145              address(feed), 
146              300 * volumeBase, 
147              CALL, 
148              uint(ethInitialPrice), 
149              time.getNow() + 30 days
150          );
151          depositTokens(address(bob), ct);
152  
153          OptionsTrader h1 = createTrader();
154  
155          address _tk1 = bob.writeOptions(100, CALL, ethInitialPrice, 30 days, pool);
156          OptionToken tk = OptionToken(_tk1);
157          Assert.equal(tk.writtenVolume(address(bob)), 100 * volumeBase, "bob written volume");
158          bob.transferOptions(address(h1), _tk1, 100);
159  
160          address _tk2 = bob.writeOptions(100, CALL, ethInitialPrice, 30 days, pool);
161          Assert.equal(tk.writtenVolume(address(bob)), 200 * volumeBase, "bob written volume");
162          bob.transferOptions(address(h1), _tk2, 100);
163  
164          address _tk3 = bob.writeOptions(100, CALL, ethInitialPrice, 30 days, pool);
165          Assert.equal(tk.writtenVolume(address(bob)), 300 * volumeBase, "bob written volume");
166          bob.transferOptions(address(h1), _tk3, 100);
167          
168          Assert.equal(_tk1, _tk2, "same _tk (2)");
169          Assert.equal(_tk1, _tk3, "same _tk (3)");
170  
171          Assert.equal(tk.balanceOf(address(bob)), 0, "bob options");
172          Assert.equal(tk.balanceOf(address(h1)), 300 * volumeBase, "h1 options");
173          Assert.equal(getBookLength(), 2, "book length");
174      }
175  }