@@ -94,7 +94,7 @@ contract MultiwrapTest is BaseTest {
9494 erc1155.mint (address (tokenOwner), 0 , 100 );
9595
9696 // Token owner approves `Multiwrap` to transfer tokens.
97- tokenOwner.setAllowanceERC20 (address (erc20), address (multiwrap), 10 ether );
97+ tokenOwner.setAllowanceERC20 (address (erc20), address (multiwrap), type ( uint ).max );
9898 tokenOwner.setApprovalForAllERC721 (address (erc721), address (multiwrap), true );
9999 tokenOwner.setApprovalForAllERC1155 (address (erc1155), address (multiwrap), true );
100100
@@ -471,4 +471,87 @@ contract MultiwrapTest is BaseTest {
471471 vm.expectRevert (bytes (errorMsg));
472472 multiwrap.unwrap (expectedIdForWrappedToken, recipient);
473473 }
474+
475+ /**
476+ * Fuzz testing:
477+ * - Wrapping and unwrapping arbitrary kinds of tokens
478+ */
479+
480+ uint256 internal constant MAX_TOKENS = 1000 ;
481+
482+ function getTokensToWrap (uint256 x ) internal returns (ITokenBundle.Token[] memory tokensToWrap ) {
483+ uint256 len = x % MAX_TOKENS;
484+ tokensToWrap = new ITokenBundle.Token [](len);
485+
486+ for (uint256 i = 0 ; i < len; i += 1 ) {
487+
488+ uint256 random = uint (keccak256 (abi.encodePacked (len + i))) % MAX_TOKENS;
489+ uint256 selector = random % 3 ;
490+
491+ if (selector == 0 ) {
492+
493+ tokensToWrap[i] = ITokenBundle.Token ({
494+ assetContract: address (erc20),
495+ tokenType: ITokenBundle.TokenType.ERC20 ,
496+ tokenId: 0 ,
497+ totalAmount: random
498+ });
499+
500+ erc20.mint (address (tokenOwner), tokensToWrap[i].totalAmount);
501+
502+ } else if (selector == 1 ) {
503+
504+ uint256 tokenId = erc721.nextTokenIdToMint ();
505+
506+ tokensToWrap[i] = ITokenBundle.Token ({
507+ assetContract: address (erc721),
508+ tokenType: ITokenBundle.TokenType.ERC721 ,
509+ tokenId: tokenId,
510+ totalAmount: 1
511+ });
512+
513+ erc721.mint (address (tokenOwner), 1 );
514+
515+ } else if (selector == 2 ) {
516+
517+ tokensToWrap[i] = ITokenBundle.Token ({
518+ assetContract: address (erc1155),
519+ tokenType: ITokenBundle.TokenType.ERC1155 ,
520+ tokenId: random,
521+ totalAmount: random
522+ });
523+
524+ erc1155.mint (address (tokenOwner), tokensToWrap[i].tokenId, tokensToWrap[i].totalAmount);
525+ }
526+ }
527+ }
528+
529+ function test_fuzz_wrap (uint256 x ) public {
530+ ITokenBundle.Token[] memory tokensToWrap = getTokensToWrap (x);
531+
532+ uint256 expectedIdForWrappedToken = multiwrap.nextTokenIdToMint ();
533+ address recipient = address (0x123 );
534+
535+ vm.prank (address (tokenOwner));
536+ if (x == 0 ) {
537+ vm.expectRevert ("TokenBundle: no tokens to bind. " );
538+ multiwrap.wrap (tokensToWrap, uriForWrappedToken, recipient);
539+ } else {
540+
541+ multiwrap.wrap (tokensToWrap, uriForWrappedToken, recipient);
542+
543+ assertEq (expectedIdForWrappedToken + 1 , multiwrap.nextTokenIdToMint ());
544+
545+ ITokenBundle.Token[] memory contentsOfWrappedToken = multiwrap.getWrappedContents (expectedIdForWrappedToken);
546+ assertEq (contentsOfWrappedToken.length , tokensToWrap.length );
547+ for (uint256 i = 0 ; i < contentsOfWrappedToken.length ; i += 1 ) {
548+ assertEq (contentsOfWrappedToken[i].assetContract, tokensToWrap[i].assetContract);
549+ assertEq (uint256 (contentsOfWrappedToken[i].tokenType), uint256 (tokensToWrap[i].tokenType));
550+ assertEq (contentsOfWrappedToken[i].tokenId, tokensToWrap[i].tokenId);
551+ assertEq (contentsOfWrappedToken[i].totalAmount, tokensToWrap[i].totalAmount);
552+ }
553+
554+ assertEq (uriForWrappedToken, multiwrap.tokenURI (expectedIdForWrappedToken));
555+ }
556+ }
474557}
0 commit comments