-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathLimitSwap.sol
More file actions
90 lines (82 loc) · 3.5 KB
/
LimitSwap.sol
File metadata and controls
90 lines (82 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {console} from "forge-std/Test.sol";
import {IERC20} from "../interfaces/IERC20.sol";
import {IExchangeRouter} from "../interfaces/IExchangeRouter.sol";
import {IReader} from "../interfaces/IReader.sol";
import {Order} from "../types/Order.sol";
import {IBaseOrderUtils} from "../types/IBaseOrderUtils.sol";
import "../Constants.sol";
contract LimitSwap {
IERC20 constant weth = IERC20(WETH);
IERC20 constant usdc = IERC20(USDC);
IExchangeRouter constant exchangeRouter = IExchangeRouter(EXCHANGE_ROUTER);
// Task 1 - Receive execution fee refund from GMX
receive() external payable {}
// Task 2 - Create a limit order to swap USDC to WETH
function createLimitOrder(
uint256 usdcAmount,
uint256 maxEthPrice
) external payable returns (bytes32 key) {
uint256 executionFee = 0.1 * 1e18;
usdc.transferFrom(msg.sender, address(this), usdcAmount);
// Task 2.1 - Send execution fee to the order vault
exchangeRouter.sendWnt{value: executionFee}({
receiver: ORDER_VAULT,
amount: executionFee
});
// Task 2.2 - Send USDC to the order vault
usdc.approve(ROUTER, usdcAmount);
exchangeRouter.sendTokens({
token: USDC,
receiver: ORDER_VAULT,
amount: usdcAmount
});
// Task 2.3 - Create an order to swap USDC to WETH
// hint - set the initialCollateralToken to USDC
// swap path can be any GM token that has WETH and USDC
// calculates the appripriate minOutputAmount based on the price limit maxEthPrice
// maxEthPrice has 8 decimals
// USDC has 6 decimals
// Assume 1 USDC = 1 USD
// WETH has 18 decimals
// returns the order key (ID) for future reference
// orderType = 1 (LimitSwap)
address[] memory swapPath = new address[](1);
swapPath[0] = GM_TOKEN_ETH_WETH_USDC;
// usdc amount = 1e6 * 1e20 / 1e18 = 1e18 (WETH)
uint256 minOutputAmount = (usdcAmount * 1e20) / maxEthPrice;
return
exchangeRouter.createOrder(
IBaseOrderUtils.CreateOrderParams({
addresses: IBaseOrderUtils.CreateOrderParamsAddresses({
receiver: address(this),
cancellationReceiver: address(0),
callbackContract: address(0),
uiFeeReceiver: address(0),
market: address(0),
initialCollateralToken: USDC,
swapPath: swapPath
}),
numbers: IBaseOrderUtils.CreateOrderParamsNumbers({
sizeDeltaUsd: 0,
initialCollateralDeltaAmount: 0,
triggerPrice: 0,
acceptablePrice: 0,
executionFee: executionFee,
callbackGasLimit: 0,
minOutputAmount: minOutputAmount,
validFromTime: 0
}),
orderType: Order.OrderType.LimitSwap,
decreasePositionSwapType: Order
.DecreasePositionSwapType
.NoSwap,
isLong: false,
shouldUnwrapNativeToken: false,
autoCancel: false,
referralCode: bytes32(uint256(0))
})
);
}
}