-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathEpendleVaultSidechain.sol
141 lines (107 loc) · 4.05 KB
/
EpendleVaultSidechain.sol
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@layerzerolabs/solidity-examples/contracts/token/oft/v2/interfaces/IOFTV2.sol";
import "./Interfaces/IEqbExternalToken.sol";
import "./Interfaces/IEPendleVaultSidechain.sol";
contract EPendleVaultSidechain is
IEPendleVaultSidechain,
AccessControlUpgradeable
{
using SafeERC20 for IERC20;
using EnumerableSet for EnumerableSet.AddressSet;
IEqbExternalToken public ePendle;
address public swapToken;
EnumerableSet.AddressSet private convertibleTokens;
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
event Converted(address indexed _user, address _token, uint256 _amount);
event Swapped(address indexed _user, uint256 _amount, address indexed _to);
event Sent(
address indexed _user,
uint16 _dstChainId,
bytes32 _to,
uint256 _amount
);
event AdminWithdrawn(address indexed _admin, uint256 _amount);
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
function initialize() public initializer {
__AccessControl_init();
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(ADMIN_ROLE, msg.sender);
}
function setParams(
address _ePendle,
address _swapToken
) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(_ePendle != address(0), "invalid _ePendle!");
require(_swapToken != address(0), "invalid _swapToken!");
ePendle = IEqbExternalToken(_ePendle);
swapToken = _swapToken;
}
modifier onlyConvertibleToken(address _token) {
require(convertibleTokens.contains(_token), "token not convertible!");
_;
}
function addConvertibleToken(address _token) external onlyRole(ADMIN_ROLE) {
require(_token != address(0), "invalid _token!");
require(!convertibleTokens.contains(_token), "already added!");
convertibleTokens.add(_token);
}
function removeConvertibleToken(
address _token
) external onlyRole(ADMIN_ROLE) {
require(_token != address(0), "invalid _token!");
require(convertibleTokens.contains(_token), "token not convertible!");
convertibleTokens.remove(_token);
}
function getConvertibleTokens() external view returns (address[] memory) {
return convertibleTokens.values();
}
function convert(
address _token,
uint256 _amount
) external override onlyConvertibleToken(_token) {
require(_amount > 0, "invalid _amount!");
IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);
ePendle.mint(msg.sender, _amount);
emit Converted(msg.sender, _token, _amount);
}
function swap(uint256 _amount, address _to) public {
require(_amount > 0, "invalid _amount!");
require(
IERC20(swapToken).balanceOf(address(this)) >= _amount,
"not enough token!"
);
ePendle.burn(msg.sender, _amount);
IERC20(swapToken).safeTransfer(_to, _amount);
emit Swapped(msg.sender, _amount, _to);
}
function swapAndSend(
uint16 _dstChainId,
bytes32 _to,
uint256 _amount,
ICommonOFT.LzCallParams calldata _callParams
) external payable {
swap(_amount, address(this));
IOFTV2(swapToken).sendFrom{value: msg.value}(
address(this),
_dstChainId,
_to,
_amount,
_callParams
);
emit Sent(msg.sender, _dstChainId, _to, _amount);
}
function adminWithdraw(
address _token
) external onlyRole(ADMIN_ROLE) onlyConvertibleToken(_token) {
uint256 tokenBal = IERC20(_token).balanceOf(address(this));
IERC20(_token).safeTransfer(msg.sender, tokenBal);
emit AdminWithdrawn(msg.sender, tokenBal);
}
}