@@ -8,6 +8,8 @@ import { Test } from "@std/Test.sol";
8
8
import { AjnaToken } from "../../src/token/AjnaToken.sol " ;
9
9
import { BurnWrappedAjna } from "../../src/token/BurnWrapper.sol " ;
10
10
11
+ import { SigUtils } from "../utils/SigUtils.sol " ;
12
+
11
13
contract BurnWrappedTokenTest is Test {
12
14
13
15
/*************/
@@ -16,6 +18,7 @@ contract BurnWrappedTokenTest is Test {
16
18
17
19
AjnaToken internal _token;
18
20
BurnWrappedAjna internal _wrappedToken;
21
+ SigUtils internal _sigUtils;
19
22
20
23
address internal _ajnaAddress = 0x9a96ec9B57Fb64FbC60B423d1f4da7691Bd35079 ; // mainnet ajna token address
21
24
address internal _tokenDeployer = 0x666cf594fB18622e1ddB91468309a7E194ccb799 ; // mainnet token deployer
@@ -35,6 +38,8 @@ contract BurnWrappedTokenTest is Test {
35
38
// reference mainnet deployment
36
39
_token = AjnaToken (_ajnaAddress);
37
40
_wrappedToken = new BurnWrappedAjna (IERC20 (address (_token)));
41
+
42
+ _sigUtils = new SigUtils (_wrappedToken.DOMAIN_SEPARATOR ());
38
43
}
39
44
40
45
function approveAndWrapTokens (address account_ , uint256 amount_ ) internal {
@@ -128,4 +133,157 @@ contract BurnWrappedTokenTest is Test {
128
133
_wrappedToken.withdrawTo (_tokenHolder, 25 * 1e18 );
129
134
}
130
135
136
+ function testApproveAndTransfer () external {
137
+ uint256 tokensToTransfer = 500 * 1e18 ;
138
+ address tokenReceiver = makeAddr ("tokenReceiver " );
139
+
140
+ // transfer some tokens to the test address
141
+ vm.startPrank (_tokenDeployer);
142
+ _token.approve (address (_tokenDeployer), tokensToTransfer);
143
+ _token.transferFrom (_tokenDeployer, _tokenHolder, tokensToTransfer);
144
+
145
+ // wrap tokens
146
+ approveAndWrapTokens (_tokenHolder, tokensToTransfer);
147
+
148
+ // approve some tokens to the receiver address
149
+ vm.startPrank (_tokenHolder);
150
+ _wrappedToken.approve (tokenReceiver, tokensToTransfer);
151
+
152
+ // check token allowance
153
+ assertEq (_wrappedToken.allowance (_tokenHolder, tokenReceiver), tokensToTransfer);
154
+
155
+ // transfer tokens
156
+ changePrank (tokenReceiver);
157
+ _wrappedToken.transferFrom (_tokenHolder, tokenReceiver, tokensToTransfer);
158
+
159
+ // ensure tokens are transferred
160
+ assertEq (_wrappedToken.balanceOf (tokenReceiver), tokensToTransfer);
161
+ }
162
+
163
+ function testIncreaseAndDecreaseAllowance () external {
164
+ uint256 tokensToTransfer = 500 * 1e18 ;
165
+ address tokenReceiver = makeAddr ("tokenReceiver " );
166
+
167
+ // transfer some tokens to the test address
168
+ vm.startPrank (_tokenDeployer);
169
+ _token.approve (address (_tokenDeployer), tokensToTransfer);
170
+ _token.transferFrom (_tokenDeployer, _tokenHolder, tokensToTransfer);
171
+
172
+ // wrap tokens
173
+ approveAndWrapTokens (_tokenHolder, tokensToTransfer);
174
+
175
+ // approve some tokens to the test address
176
+ vm.startPrank (_tokenHolder);
177
+ _wrappedToken.approve (tokenReceiver, tokensToTransfer);
178
+
179
+ // increase token allowance to 1000 tokens
180
+ _wrappedToken.increaseAllowance (tokenReceiver, 500 * 1e18 );
181
+
182
+ // check allowance is increased
183
+ assertEq (_wrappedToken.allowance (_tokenHolder, tokenReceiver), 1000 * 1e18 );
184
+
185
+ // decrease token allowance to 200 tokens
186
+ _wrappedToken.decreaseAllowance (tokenReceiver, 800 * 1e18 );
187
+
188
+ // check allowance is decreased
189
+ assertEq (_wrappedToken.allowance (_tokenHolder, tokenReceiver), 200 * 1e18 );
190
+ }
191
+
192
+ function testDomainSeparatorAndUnderlyingToken () external {
193
+ bytes32 expectedDomainSeparator = keccak256 (
194
+ abi.encode (
195
+ keccak256 ("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract) " ),
196
+ keccak256 (bytes ("Burn Wrapped AJNA " )),
197
+ keccak256 (bytes ("1 " )),
198
+ block .chainid ,
199
+ address (_wrappedToken)
200
+ )
201
+ );
202
+
203
+ assertEq (_wrappedToken.DOMAIN_SEPARATOR (), expectedDomainSeparator);
204
+
205
+ assertEq (address (_wrappedToken.underlying ()), address (_token));
206
+ }
207
+
208
+ function testTransferWithPermit () external {
209
+ uint256 tokensToTransfer = 500 * 1e18 ;
210
+
211
+ // define owner and spender addresses
212
+ (address owner , uint256 ownerPrivateKey ) = makeAddrAndKey ("owner " );
213
+ address spender = makeAddr ("spender " );
214
+ address newOwner = makeAddr ("newOwner " );
215
+
216
+ // set owner balance
217
+ deal (address (_wrappedToken), owner, tokensToTransfer);
218
+
219
+ // check owner and spender balances
220
+ assertEq (_wrappedToken.balanceOf (owner), tokensToTransfer);
221
+ assertEq (_wrappedToken.balanceOf (spender), 0 );
222
+ assertEq (_wrappedToken.balanceOf (newOwner), 0 );
223
+
224
+ // TEST transfer with ERC20 permit
225
+ vm.startPrank (owner);
226
+ SigUtils.Permit memory permit = SigUtils.Permit ({
227
+ owner: owner,
228
+ spender: spender,
229
+ value: tokensToTransfer,
230
+ nonce: 0 ,
231
+ deadline: block .timestamp + 1 days
232
+ });
233
+
234
+ bytes32 digest = _sigUtils.getTypedDataHash (permit);
235
+ (uint8 v , bytes32 r , bytes32 s ) = vm.sign (ownerPrivateKey, digest);
236
+ _wrappedToken.permit (owner, spender, tokensToTransfer, permit.deadline, v, r, s);
237
+
238
+ // check nonces is increased
239
+ assertEq (_wrappedToken.nonces (owner), 1 );
240
+
241
+ changePrank (spender);
242
+ _wrappedToken.transferFrom (owner, newOwner, tokensToTransfer);
243
+
244
+ // check owner and spender balances after transfer
245
+ assertEq (_wrappedToken.balanceOf (owner), 0 );
246
+ assertEq (_wrappedToken.balanceOf (spender), 0 );
247
+ assertEq (_wrappedToken.balanceOf (newOwner), tokensToTransfer);
248
+ assertEq (_wrappedToken.allowance (owner, spender), 0 );
249
+ }
250
+
251
+ function testBurn () external {
252
+ uint256 tokensToBurn = 500 * 1e18 ;
253
+
254
+ // transfer some tokens to the test address
255
+ vm.startPrank (_tokenDeployer);
256
+ _token.approve (address (_tokenDeployer), tokensToBurn);
257
+ _token.transferFrom (_tokenDeployer, _tokenHolder, tokensToBurn);
258
+
259
+ // wrap tokens
260
+ approveAndWrapTokens (_tokenHolder, tokensToBurn);
261
+
262
+ uint256 totalTokenSupply = _wrappedToken.totalSupply ();
263
+
264
+ uint256 snapshot = vm.snapshot ();
265
+
266
+ // burn tokens
267
+ _wrappedToken.burn (tokensToBurn);
268
+
269
+ // ensure tokens are burned
270
+ assertEq (_wrappedToken.balanceOf (_tokenHolder), 0 );
271
+ assertEq (_wrappedToken.totalSupply (), totalTokenSupply - tokensToBurn);
272
+
273
+ vm.revertTo (snapshot);
274
+
275
+ address tokenBurner = makeAddr ("tokenBurner " );
276
+
277
+ // approve tokens to token burner address
278
+ _wrappedToken.approve (tokenBurner, tokensToBurn);
279
+
280
+ // burn tokens
281
+ changePrank (tokenBurner);
282
+ _wrappedToken.burnFrom (_tokenHolder, tokensToBurn);
283
+
284
+ // ensure tokens are burned
285
+ assertEq (_wrappedToken.balanceOf (_tokenHolder), 0 );
286
+ assertEq (_wrappedToken.totalSupply (), totalTokenSupply - tokensToBurn);
287
+ }
288
+
131
289
}
0 commit comments