@@ -10,6 +10,7 @@ import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
10
10
11
11
import "./interfaces/ISignalBuyContract.sol " ;
12
12
import "./interfaces/IWeth.sol " ;
13
+ import { Asset } from "./utils/Asset.sol " ;
13
14
import "./utils/BaseLibEIP712.sol " ;
14
15
import "./utils/LibConstant.sol " ;
15
16
import "./utils/LibSignalBuyContractOrderStorage.sol " ;
@@ -23,6 +24,7 @@ import "./utils/SignatureValidator.sol";
23
24
contract SignalBuyContract is ISignalBuyContract , BaseLibEIP712 , SignatureValidator , ReentrancyGuard , Ownable {
24
25
using SafeMath for uint256 ;
25
26
using SafeERC20 for IERC20 ;
27
+ using Asset for address ;
26
28
27
29
IWETH public immutable weth;
28
30
uint256 public immutable factorActivateDelay;
@@ -145,7 +147,7 @@ contract SignalBuyContract is ISignalBuyContract, BaseLibEIP712, SignatureValida
145
147
bytes calldata _orderUserSig ,
146
148
TraderParams calldata _params ,
147
149
CoordinatorParams calldata _crdParams
148
- ) external override nonReentrant returns (uint256 , uint256 ) {
150
+ ) external payable override nonReentrant returns (uint256 , uint256 ) {
149
151
bytes32 orderHash = getEIP712Hash (SignalBuyContractLibEIP712._getOrderStructHash (_order));
150
152
151
153
_validateOrder (_order, orderHash, _orderUserSig);
@@ -267,18 +269,53 @@ contract SignalBuyContract is ISignalBuyContract, BaseLibEIP712, SignatureValida
267
269
uint256 tokenlonFee = _mulFactor (_settlement.dealerTokenAmount, tokenlonFeeFactor);
268
270
// 2. Fee for SignalBuy, including gas fee and strategy fee
269
271
uint256 dealerFee = _mulFactor (_settlement.dealerTokenAmount, _settlement.gasFeeFactor + _settlement.dealerStrategyFeeFactor);
270
- uint256 dealerTokenForUser = _settlement.dealerTokenAmount.sub (tokenlonFee).sub (dealerFee);
272
+ uint256 dealerTokenForUserAndTokenlon = _settlement.dealerTokenAmount.sub (dealerFee);
273
+ uint256 dealerTokenForUser = dealerTokenForUserAndTokenlon.sub (tokenlonFee);
271
274
require (dealerTokenForUser >= _settlement.minDealerTokenAmount, "SignalBuyContract: dealer token amount not enough " );
272
275
273
276
// trader -> user
274
- _settlement.dealerToken.safeTransferFrom (_settlement.trader, _settlement.user, dealerTokenForUser);
277
+ address _weth = address (weth); // cache
278
+ if (address (_settlement.dealerToken).isETH ()) {
279
+ if (msg .value > 0 ) {
280
+ // User wants ETH and dealer pays in ETH
281
+ require (msg .value == dealerTokenForUserAndTokenlon, "SignalBuyContract: mismatch dealer token (ETH) amount " );
282
+ } else {
283
+ // User wants ETH but dealer pays in WETH
284
+ IERC20 (_weth).safeTransferFrom (_settlement.trader, address (this ), dealerTokenForUserAndTokenlon);
285
+ weth.withdraw (dealerTokenForUserAndTokenlon);
286
+ }
287
+ // Send ETH to user
288
+ LibConstant.ETH_ADDRESS.transferTo (payable (_settlement.user), dealerTokenForUser);
289
+ } else if (address (_settlement.dealerToken) == _weth) {
290
+ if (msg .value > 0 ) {
291
+ // User wants WETH but dealer pays in ETH
292
+ require (msg .value == dealerTokenForUserAndTokenlon, "SignalBuyContract: mismatch dealer token (ETH) amount " );
293
+ weth.deposit { value: dealerTokenForUserAndTokenlon }();
294
+ weth.transfer (_settlement.user, dealerTokenForUser);
295
+ } else {
296
+ // User wants WETH and dealer pays in WETH
297
+ IERC20 (_weth).safeTransferFrom (_settlement.trader, _settlement.user, dealerTokenForUser);
298
+ }
299
+ } else {
300
+ _settlement.dealerToken.safeTransferFrom (_settlement.trader, _settlement.user, dealerTokenForUser);
301
+ }
275
302
276
303
// user -> recipient
277
304
_settlement.userToken.safeTransferFrom (_settlement.user, _settlement.recipient, _settlement.userTokenAmount);
278
305
279
306
// Collect user fee (charged in dealer token)
280
307
if (tokenlonFee > 0 ) {
281
- _settlement.dealerToken.safeTransferFrom (_settlement.trader, _feeCollector, tokenlonFee);
308
+ if (address (_settlement.dealerToken).isETH ()) {
309
+ LibConstant.ETH_ADDRESS.transferTo (payable (_feeCollector), tokenlonFee);
310
+ } else if (address (_settlement.dealerToken) == _weth) {
311
+ if (msg .value > 0 ) {
312
+ weth.transfer (_feeCollector, tokenlonFee);
313
+ } else {
314
+ weth.transferFrom (_settlement.trader, _feeCollector, tokenlonFee);
315
+ }
316
+ } else {
317
+ _settlement.dealerToken.safeTransferFrom (_settlement.trader, _feeCollector, tokenlonFee);
318
+ }
282
319
}
283
320
284
321
// bypass stack too deep error
0 commit comments