@@ -20,6 +20,10 @@ library StreamExchangeHelper {
2020
2121 using SafeERC20 for ERC20 ;
2222
23+ // TODO: Emit these events where appropriate
24+ event Distribution (uint256 totalAmount , uint256 feeCollected , address token );
25+
26+
2327 function _getCurrentValue (
2428 StreamExchangeStorage.StreamExchange storage self ,
2529 uint256 _requestId
@@ -88,56 +92,75 @@ library StreamExchangeHelper {
8892 // Confirm the app has enough to distribute
8993 require (self.outputToken.balanceOf (address (this )) >= actualAmount, "!enough " );
9094
91- newCtx = _idaDistribute (self, self.outputIndexId, uint128 (actualAmount), self.outputToken, newCtx);
95+ newCtx = _idaDistribute (self, self.outputIndexId, uint128 (distAmount), self.outputToken, newCtx);
96+ emit Distribution (distAmount, feeCollected, address (self.outputToken));
9297
9398 // Distribute a subsidy if possible
9499 if (self.subsidyToken.balanceOf (address (this )) >= subsidyAmount) {
95100 newCtx = _idaDistribute (self, self.subsidyIndexId, uint128 (subsidyAmount), self.subsidyToken, newCtx);
101+ emit Distribution (subsidyAmount, 0 , address (self.subsidyToken));
96102 }
97103
98104 self.lastDistributionAt = block .timestamp ;
99105
100106 // Take the fee
101107 ISuperToken (self.outputToken).transfer (self.owner, feeCollected);
102108
109+ require (ISuperToken (self.inputToken).balanceOf (address (this )) == 0 , "!sellAllInput " );
110+
111+
103112 return newCtx;
104113
105114 }
106115
107116 function _swap (
108117 StreamExchangeStorage.StreamExchange storage self ,
109- uint256 amount ,
118+ uint256 amount , // Assumes this is outputToken.balanceOf(address(this))
110119 uint256 exchangeRate ,
111120 uint256 deadline
112121 ) public returns (uint ) {
113122
114- uint256 minOutput = amount * 1e18 / exchangeRate / 1e12 ;
115-
116- self.inputToken.downgrade (amount);
117- address inputToken = self.inputToken.getUnderlyingToken ();
118- address outputToken = self.outputToken.getUnderlyingToken ();
119- address [] memory path = new address [](2 );
120- path[0 ] = inputToken;
121- path[1 ] = outputToken;
122-
123- // approve the router to spend
124- ERC20 (inputToken).safeIncreaseAllowance (address (self.sushiRouter), amount);
125-
126- uint [] memory amounts = self.sushiRouter.swapExactTokensForTokens (
127- amount,
128- minOutput,
129- path,
130- address (this ),
131- deadline
132- );
133-
134- ERC20 (outputToken).safeIncreaseAllowance (address (self.outputToken), amounts[1 ]);
135- self.outputToken.upgrade (amounts[1 ]);
136-
137- // TODO: Take a small fee
138-
139- return amounts[1 ];
140- }
123+ address inputToken; // The underlying input token address
124+ address outputToken; // The underlying output token address
125+ address [] memory path; // The path to take
126+ uint256 minOutput; // The minimum amount of output tokens based on Tellor
127+ uint256 outputAmount; // The balance before the swap
128+
129+ console.log ("Amount to swap " , amount);
130+ // TODO: This needs to be "invertable"
131+ // minOutput = amount * 1e18 / exchangeRate / 1e12;
132+ minOutput = amount * exchangeRate / 1e6 ;
133+ console.log ("minOutput " , minOutput);
134+ minOutput = minOutput * (1e6 - self.rateTolerance) / 1e6 ;
135+ console.log ("minOutput " , minOutput);
136+
137+ self.inputToken.downgrade (amount);
138+ inputToken = self.inputToken.getUnderlyingToken ();
139+ outputToken = self.outputToken.getUnderlyingToken ();
140+ path = new address [](2 );
141+ path[0 ] = inputToken;
142+ path[1 ] = outputToken;
143+
144+ // Swap on Sushiswap
145+ ERC20 (inputToken).safeIncreaseAllowance (address (self.sushiRouter), amount);
146+ self.sushiRouter.swapExactTokensForTokens (
147+ amount,
148+ 0 , // Accept any amount but fail if we're too far from the oracle price
149+ path,
150+ address (this ),
151+ deadline
152+ );
153+ // Assumes `amount` was outputToken.balanceOf(address(this))
154+ outputAmount = ERC20 (outputToken).balanceOf (address (this ));
155+ console.log ("outputAmount " , outputAmount);
156+ require (outputAmount >= minOutput, "BAD_EXCHANGE_RATE: Try again later " );
157+
158+ // Convert the outputToken back to its supertoken version
159+ ERC20 (outputToken).safeIncreaseAllowance (address (self.outputToken), outputAmount);
160+ self.outputToken.upgrade (outputAmount);
161+
162+ return outputAmount;
163+ }
141164
142165
143166 function _initalizeLiquidityMining (StreamExchangeStorage.StreamExchange storage self ) internal {
0 commit comments