@@ -28,73 +28,142 @@ abstract contract TokenWrapper is ERC20PresetMinterPauser, ITokenWrapper {
2828 @param tokenAddress Address of ERC20 to transfer.
2929 @param amount Amount of tokens to transfer.
3030 */
31- function wrap (address tokenAddress , uint256 amount ) override public {
32- require (_isValidAddress (tokenAddress), "Invalid token address " );
33- require (_isValidAmount (amount), "Invalid token amount " );
34- // transfer liquidity to the token wrapper
35- IERC20 (tokenAddress).transferFrom (_msgSender (), address (this ), amount);
36- // mint the wrapped token for the sender
37- _mint (_msgSender (), amount);
31+ function wrap (
32+ address tokenAddress ,
33+ uint256 amount
34+ ) override payable public isValidWrapping (tokenAddress, amount) {
35+ if (tokenAddress == address (0 )) {
36+ // mint the native value sent to the contract
37+ _mint (_msgSender (), msg .value );
38+ } else {
39+ // transfer liquidity to the token wrapper
40+ IERC20 (tokenAddress).transferFrom (_msgSender (), address (this ), amount);
41+ // mint the wrapped token for the sender
42+ _mint (_msgSender (), amount);
43+ }
3844 }
3945
4046 /**
4147 @notice Used to unwrap/burn the wrapper token on behalf of a sender.
4248 @param tokenAddress Address of ERC20 to unwrap into.
4349 @param amount Amount of tokens to burn.
4450 */
45- function unwrap (address tokenAddress , uint256 amount ) override public {
46- require (_isValidAddress (tokenAddress), "Invalid token address " );
47- require (_isValidAmount (amount), "Invalid token amount " );
51+ function unwrap (
52+ address tokenAddress ,
53+ uint256 amount
54+ ) override public isValidUnwrapping (tokenAddress, amount) {
4855 // burn wrapped token from sender
4956 _burn (_msgSender (), amount);
50- // transfer liquidity from the token wrapper to the sender
51- IERC20 (tokenAddress).transfer (_msgSender (), amount);
57+ // unwrap liquidity and send to the sender
58+ if (tokenAddress == address (0 )) {
59+ // transfer native liquidity from the token wrapper to the sender
60+ payable (msg .sender ).transfer (amount);
61+ } else {
62+ // transfer ERC20 liquidity from the token wrapper to the sender
63+ IERC20 (tokenAddress).transfer (_msgSender (), amount);
64+ }
5265 }
5366
5467 /**
5568 @notice Used to wrap tokens on behalf of a sender
69+ @param sender Address of sender where assets are sent from.
5670 @param tokenAddress Address of ERC20 to transfer.
5771 @param amount Amount of tokens to transfer.
5872 */
59- function wrapFor (address sender , address tokenAddress , uint256 amount ) override public {
60- require (hasRole (MINTER_ROLE, msg .sender ), "ERC20PresetMinterPauser: must have minter role " );
61- require (_isValidAddress (tokenAddress), "Invalid token address " );
62- require (_isValidAmount (amount), "Invalid token amount " );
63- // transfer liquidity to the token wrapper
64- IERC20 (tokenAddress).transferFrom (sender, address (this ), amount);
65- // mint the wrapped token for the sender
66- mint (sender, amount);
73+ function wrapFor (
74+ address sender ,
75+ address tokenAddress ,
76+ uint256 amount
77+ ) override payable public isMinter () isValidWrapping (tokenAddress, amount) {
78+ if (tokenAddress == address (0 )) {
79+ mint (sender, msg .value );
80+ } else {
81+ // transfer liquidity to the token wrapper
82+ IERC20 (tokenAddress).transferFrom (sender, address (this ), amount);
83+ // mint the wrapped token for the sender
84+ mint (sender, amount);
85+ }
6786 }
87+
6888 /**
69- @notice Used to wrap tokens and mint the wrapped tokens to a potentially different recipient
89+ @notice Used to wrap tokens on behalf of a sender and mint to a potentially different address
90+ @param sender Address of sender where assets are sent from.
91+ @param tokenAddress Address of ERC20 to transfer.
92+ @param amount Amount of tokens to transfer.
93+ @param recipient Recipient of the wrapped tokens.
7094 */
71- function wrapForAndSendTo (address sender , address tokenAddress , uint256 amount , address recipient ) override public {
72- require (hasRole (MINTER_ROLE, msg .sender ), "ERC20PresetMinterPauser: must have minter role " );
73- require (_isValidAddress (tokenAddress), "Invalid token address " );
74- require (_isValidAmount (amount), "Invalid token amount " );
75- // transfer liquidity to the token wrapper
76- IERC20 (tokenAddress).transferFrom (sender, address (this ), amount);
77- // mint the wrapped token for the sender
78- mint (recipient, amount);
95+ function wrapForAndSendTo (
96+ address sender ,
97+ address tokenAddress ,
98+ uint256 amount ,
99+ address recipient
100+ ) override payable public isMinter () isValidWrapping (tokenAddress, amount) {
101+ if (tokenAddress == address (0 )) {
102+ mint (recipient, msg .value );
103+ } else {
104+ // transfer liquidity to the token wrapper
105+ IERC20 (tokenAddress).transferFrom (sender, address (this ), amount);
106+ // mint the wrapped token for the recipient
107+ mint (recipient, amount);
108+ }
79109 }
110+
80111 /**
81112 @notice Used to unwrap/burn the wrapper token.
82113 @param tokenAddress Address of ERC20 to unwrap into.
83114 @param amount Amount of tokens to burn.
84115 */
85- function unwrapFor (address sender , address tokenAddress , uint256 amount ) override public {
86- require (hasRole (MINTER_ROLE, msg .sender ), "ERC20PresetMinterPauser: must have minter role " );
87- require (_isValidAddress (tokenAddress), "Invalid token address " );
88- require (_isValidAmount (amount), "Invalid token amount " );
116+ function unwrapFor (
117+ address sender ,
118+ address tokenAddress ,
119+ uint256 amount
120+ ) override public isMinter () isValidUnwrapping (tokenAddress, amount) {
89121 // burn wrapped token from sender
90122 _burn (sender, amount);
91- // transfer liquidity from the token wrapper to the sender
92- IERC20 (tokenAddress).transfer (sender, amount);
123+ if (tokenAddress == address (0 )) {
124+ payable (sender).transfer (amount);
125+ } else {
126+ // transfer liquidity from the token wrapper to the sender
127+ IERC20 (tokenAddress).transfer (sender, amount);
128+ }
93129 }
94130
95131 /** @dev this function is defined in a child contract */
96132 function _isValidAddress (address tokenAddress ) internal virtual returns (bool );
97133
134+ /** @dev this function is defined in a child contract */
135+ function _isNativeValid () internal virtual returns (bool );
136+
98137 /** @dev this function is defined in a child contract */
99138 function _isValidAmount (uint256 amount ) internal virtual returns (bool );
139+
140+ modifier isMinter () {
141+ require (hasRole (MINTER_ROLE, msg .sender ), "ERC20PresetMinterPauser: must have minter role " );
142+ _;
143+ }
144+
145+ modifier isValidWrapping (address tokenAddress , uint256 amount ) {
146+ if (tokenAddress == address (0 )) {
147+ require (amount == 0 , "Invalid amount provided for native wrapping " );
148+ require (_isNativeValid (), "Native wrapping is not allowed for this token wrapper " );
149+ } else {
150+ require (msg .value == 0 , "Invalid value sent for wrapping " );
151+ require (_isValidAddress (tokenAddress), "Invalid token address " );
152+ }
153+
154+ require (_isValidAmount (amount), "Invalid token amount " );
155+ _;
156+ }
157+
158+ modifier isValidUnwrapping (address tokenAddress , uint256 amount ) {
159+ if (tokenAddress == address (0 )) {
160+ require (address (this ).balance >= amount, "Insufficient native balance " );
161+ require (_isNativeValid (), "Native unwrapping is not allowed for this token wrapper " );
162+ } else {
163+ require (IERC20 (tokenAddress).balanceOf (address (this )) >= amount, "Insufficient ERC20 balance " );
164+ require (_isValidAddress (tokenAddress), "Invalid token address " );
165+ }
166+
167+ _;
168+ }
100169}
0 commit comments