TestCoveredLiquidation.t.sol
1 pragma solidity >=0.6.0; 2 pragma experimental ABIEncoderV2; 3 4 import "truffle/Assert.sol"; 5 import "../../../contracts/finance/OptionToken.sol"; 6 import "../../../contracts/utils/MoreMath.sol"; 7 import "./Base.t.sol"; 8 9 contract TestCoveredLiquidation is Base { 10 11 function testLiquidationBeforeAllowed() public { 12 underlying.reset(address(this)); 13 underlying.issue(address(this), 3 * underlyingBase); 14 address _tk = writeCovered(3, ethInitialPrice, 10 days, address(alice)); 15 16 OptionToken tk = OptionToken(_tk); 17 18 //tk.transfer(address(alice), 2 * volumeBase); 19 20 Assert.equal(1 * volumeBase, tk.balanceOf(address(this)), "writer tk balance"); 21 Assert.equal(2 * volumeBase, tk.balanceOf(address(alice)), "alice tk balance"); 22 23 (bool success,) = address(alice).call( 24 abi.encodePacked( 25 alice.liquidateOptions.selector, 26 abi.encode(_tk, address(alice)) 27 ) 28 ); 29 30 Assert.isFalse(success, "liquidate should fail"); 31 } 32 33 function testLiquidationAtMaturityOTM() public { 34 35 underlying.reset(address(this)); 36 underlying.issue(address(this), 2 * underlyingBase); 37 38 int step = 40e18; 39 40 address _tk = writeCovered(2, ethInitialPrice, 10 days, address(alice)); 41 42 OptionToken tk = OptionToken(_tk); 43 44 45 feed.setPrice(ethInitialPrice - step); 46 time.setTimeOffset(10 days); 47 48 uint b0 = underlying.balanceOf(address(this)); 49 Assert.equal(b0, 0, "underlying before liquidation"); 50 51 (bool success,) = address(this).call( 52 abi.encodePacked( 53 collateralManager.liquidateOptions.selector, 54 abi.encode(_tk, address(this)) 55 ) 56 ); 57 58 uint b1 = underlying.balanceOf(address(this)); 59 Assert.equal(b1, 2 * underlyingBase, "underlying after liquidation"); 60 61 Assert.equal(exchange.calcCollateral(address(this), true), 0, "writer final collateral"); 62 Assert.equal(alice.calcCollateral(), 0, "alice final collateral"); 63 64 Assert.equal(exchange.calcSurplus(address(this)), 0, "writer final surplus"); 65 Assert.equal(alice.calcSurplus(), 0, "alice final surplus"); 66 } 67 68 function testLiquidateMultipleITM() public { 69 70 underlying.reset(address(this)); 71 underlying.issue(address(this), 4 * underlyingBase); 72 73 settings.setSwapRouterInfo(router, address(erc20)); 74 settings.setSwapRouterTolerance(105e4, 1e6); 75 76 int step = 40e18; 77 78 address _tk100 = writeCovered(2, ethInitialPrice, 100 days, address(alice)); 79 address _tk200 = writeCovered(2, ethInitialPrice, 200 days, address(alice)); 80 81 OptionToken tk100 = OptionToken(_tk100); 82 OptionToken tk200 = OptionToken(_tk200); 83 84 85 feed.setPrice(ethInitialPrice + step); 86 87 time.setTimeOffset(100 days); 88 (bool success,) = address(this).call( 89 abi.encodePacked( 90 collateralManager.liquidateOptions.selector, 91 abi.encode(_tk100, address(this)) 92 ) 93 ); 94 95 time.setTimeOffset(200 days); 96 (bool success1,) = address(this).call( 97 abi.encodePacked( 98 collateralManager.liquidateOptions.selector, 99 abi.encode(_tk200, address(this)) 100 ) 101 ); 102 } 103 104 function writeCovered( 105 uint volume, 106 int strike, 107 uint timeToMaturity, 108 address trader 109 ) 110 public 111 returns (address _tk) 112 { 113 IERC20( 114 UnderlyingFeed(feed).getUnderlyingAddr() 115 ).approve(address(exchange), volume * volumeBase); 116 117 _tk = exchange.createSymbol( 118 address(feed), 119 IOptionsExchange.OptionType.CALL, 120 uint(strike), 121 time.getNow() + timeToMaturity 122 ); 123 124 addSymbol(uint(strike), time.getNow() + timeToMaturity); 125 126 IOptionsExchange.OpenExposureInputs memory oEi; 127 128 oEi.symbols = new string[](1); 129 oEi.volume = new uint[](1); 130 oEi.isShort = new bool[](1); 131 oEi.isCovered = new bool[](1); 132 oEi.poolAddrs = new address[](1); 133 oEi.paymentTokens = new address[](1); 134 135 136 oEi.symbols[0] = IOptionToken(_tk).symbol(); 137 oEi.volume[0] = volume * volumeBase; 138 oEi.isShort[0] = true; 139 oEi.poolAddrs[0] = pool;//poolAddr; 140 oEi.isCovered[0] = true; 141 //oEi.paymentTokens[0] = address(0); //exploiting default to save gas 142 143 (bool success,) = address(this).call( 144 abi.encodePacked( 145 exchange.openExposure.selector, 146 abi.encode(oEi, trader) 147 ) 148 ); 149 150 Assert.equal(success,true, "covered option written"); 151 } 152 }