diff --git a/.gas-snapshot b/.gas-snapshot index 1f0b8427..d785e3b3 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,185 +1,188 @@ -CertifyTest:testCertify(uint256,uint256,string,string,uint256,uint256,bytes,uint256,bool) (runs: 269, μ: 1103631, ~: 1103267) -CertifyTest:testCertifyRevertOnFutureReferenceBlock(uint256,uint256,string,string,uint256,bytes,uint256,uint256,bool) (runs: 269, μ: 1075432, ~: 1076056) -CertifyTest:testCertifyRevertOnZeroCertifyUntil(uint256,uint256,uint256,string,string,bytes,uint256,bool) (runs: 269, μ: 1068389, ~: 1073510) -CertifyTest:testCertifyWithForceUntilTrue(uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256,uint256) (runs: 269, μ: 1334617, ~: 1331868) -CertifyTest:testCertifyWithForceUntilTrueRevertDeposit(uint256,uint256,string,string,uint256,uint256,bytes,uint256,uint256,uint256,uint256) (runs: 269, μ: 1288561, ~: 1290687) -CertifyTest:testVaultGetsCertified(uint256,uint256,uint256,uint256,string,string,bytes,uint256,uint256,uint256,bool) (runs: 269, μ: 1270896, ~: 1269823) -ConfiscateReceiptTest:testConfiscateReceipt(uint256,uint256,uint256,uint256,string,bytes,uint256,uint256,uint256,bool) (runs: 269, μ: 1375780, ~: 1336212) -ConfiscateReceiptTest:testConfiscateReceiptOnZeroBalance(uint256,uint256,string,string,bytes,uint256) (runs: 269, μ: 1144053, ~: 1141633) -ConfiscateSharesTest:testConfiscateShares(uint256,uint256,uint256,uint256,string,string,bytes,uint256,uint256,uint256,bool) (runs: 269, μ: 1319813, ~: 1318455) -ConfiscateSharesTest:testConfiscateSharesOnZeroBalance(uint256,uint256,string,string,bytes,uint256,uint256) (runs: 269, μ: 1237667, ~: 1239986) -ERC20PriceOracleReceiptVaultConstructionTest:testCheckConstructionEvent(uint256,string,string) (runs: 270, μ: 515158, ~: 517706) -ERC20PriceOracleReceiptVaultConstructionTest:testCreatingSeveralVaults(uint256,uint256,string,string,string,string) (runs: 269, μ: 992984, ~: 997049) -ERC20PriceOracleReceiptVaultDepositTest:testDepositBasic(uint256,string,uint256,uint256) (runs: 270, μ: 617528, ~: 576817) -ERC20PriceOracleReceiptVaultDepositTest:testDepositFlareFork(uint256) (runs: 10, μ: 499527, ~: 499477) -ERC20PriceOracleReceiptVaultDepositTest:testDepositSomeoneElse(uint256,uint256,string,uint256,uint256) (runs: 269, μ: 629370, ~: 585288) -ERC20PriceOracleReceiptVaultDepositTest:testDepositWithIncorrectPrice(uint256,string,string,bytes,uint256,uint256) (runs: 270, μ: 514095, ~: 508200) -ERC20PriceOracleReceiptVaultDepositTest:testDepositWithZeroAssets(uint256,string,string,bytes,uint256) (runs: 270, μ: 512021, ~: 506706) -ERC20PriceOracleReceiptVaultDepositTest:testDepositWithZeroReceiver(string,string,bytes,uint256,uint256) (runs: 270, μ: 506885, ~: 507319) -ERC20PriceOracleReceiptVaultDepositTest:testPreviewDepositReturnedShares(string,string,uint256,uint256) (runs: 270, μ: 505420, ~: 506760) -ERC20PriceOracleReceiptVaultMintTest:testMintBasic(uint256,string,uint256,uint256) (runs: 270, μ: 612914, ~: 572231) -ERC20PriceOracleReceiptVaultMintTest:testMintFlareFork(uint256) (runs: 10, μ: 522090, ~: 521828) -ERC20PriceOracleReceiptVaultMintTest:testMintSomeoneElse(uint256,uint256,string,uint256,uint256) (runs: 269, μ: 624755, ~: 580691) -ERC20PriceOracleReceiptVaultMintTest:testMintWithMinPrice(uint256,string,string,uint256,uint256,uint256) (runs: 260, μ: 510350, ~: 508512) -ERC20PriceOracleReceiptVaultMintTest:testMintWithZeroShares(uint256,string,uint256) (runs: 270, μ: 505592, ~: 483299) -ERC20PriceOracleReceiptVaultMintTest:testPreviewMintReturnedAssets(string,string,uint256,uint256) (runs: 270, μ: 505735, ~: 507070) -ERC20PriceOracleReceiptVaultRedeemTest:testPreviewRedeem(uint256,string,uint256,uint256) (runs: 270, μ: 501262, ~: 462083) -ERC20PriceOracleReceiptVaultRedeemTest:testRedeemBasic(uint256,string,uint256,uint256,uint256) (runs: 270, μ: 641058, ~: 597490) -ERC20PriceOracleReceiptVaultRedeemTest:testRedeemFlareFork(uint256) (runs: 10, μ: 549817, ~: 549555) -ERC20PriceOracleReceiptVaultRedeemTest:testRedeemMoreThanBalance(uint256,string,uint256,uint256,uint256) (runs: 270, μ: 628613, ~: 628062) -ERC20PriceOracleReceiptVaultRedeemTest:testRedeemRevertsOnZeroOwner(uint256,string,uint256,uint256,uint256) (runs: 270, μ: 620818, ~: 577246) -ERC20PriceOracleReceiptVaultRedeemTest:testRedeemRevertsOnZeroReceiver(uint256,string,uint256,uint256,uint256) (runs: 270, μ: 623214, ~: 579642) -ERC20PriceOracleReceiptVaultRedeemTest:testRedeemRevertsOnZeroShares(uint256,string,uint256,uint256) (runs: 270, μ: 616745, ~: 576048) -ERC20PriceOracleReceiptVaultRedeemTest:testRedeemWithERC20Approval(uint256,uint256,uint256,uint256,uint256) (runs: 264, μ: 675113, ~: 675587) -ERC20PriceOracleReceiptVaultWithdrawTest:testMultiplePricesAndHistoricalRedemptionsAndMint(uint256,uint256,uint256,uint256,uint256) (runs: 269, μ: 801992, ~: 802219) -ERC20PriceOracleReceiptVaultWithdrawTest:testPreviewWithdraw(uint256,string,uint256,uint256) (runs: 270, μ: 503037, ~: 462362) -ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawAliceBurnBob(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 267, μ: 802044, ~: 805709) -ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawBasic(uint256,string,uint256,uint256) (runs: 270, μ: 630497, ~: 594893) -ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawFlareFork(uint256) (runs: 10, μ: 549959, ~: 549697) -ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawMoreThanAssets(uint256,string,uint256,uint256,uint256) (runs: 270, μ: 627646, ~: 626492) -ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawRevertsOnZeroAssets(uint256,string,uint256,uint256) (runs: 270, μ: 616819, ~: 576122) -ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawRevertsOnZeroOwner(uint256,string,uint256,uint256) (runs: 270, μ: 615786, ~: 575090) -ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawRevertsOnZeroReceiver(uint256,string,uint256,uint256) (runs: 270, μ: 618140, ~: 577443) -ERC20PriceOracleReceiptVaultreceiptVaultTest:testConvertToAssets(uint256,string,uint256,uint256) (runs: 270, μ: 499590, ~: 459167) -ERC20PriceOracleReceiptVaultreceiptVaultTest:testConvertToAssetsDifferentCaller(uint256,uint256,string,uint256,uint256) (runs: 269, μ: 506005, ~: 461939) -ERC20PriceOracleReceiptVaultreceiptVaultTest:testConvertToShares(uint256,string,uint256,uint256) (runs: 270, μ: 502589, ~: 462757) -ERC20PriceOracleReceiptVaultreceiptVaultTest:testConvertToSharesDifferentCaller(uint256,uint256,string,uint256,uint256) (runs: 269, μ: 512315, ~: 468365) -ERC20PriceOracleReceiptVaultreceiptVaultTest:testMaxDeposit(uint256,string) (runs: 270, μ: 499630, ~: 497825) -ERC20PriceOracleReceiptVaultreceiptVaultTest:testMaxShares(uint256,string) (runs: 270, μ: 499618, ~: 497813) -ERC20PriceOracleReceiptVaultreceiptVaultTest:testReceiptVaultInformation(uint256,string,bytes) (runs: 270, μ: 508268, ~: 548436) -ERC20PriceOracleReceiptVaultreceiptVaultTest:testTotalAssets(uint256,string,uint256) (runs: 270, μ: 502847, ~: 480627) -ERC20PriceOracleReceiptVaultreceiptVaultTest:testVaultAsset(uint256,string) (runs: 270, μ: 499553, ~: 497748) -ERC20StandardTest:testERC20AllowanceAndApprove(uint256,uint256,uint256) (runs: 269, μ: 483021, ~: 483018) -ERC20StandardTest:testERC20DecreaseAllowance(uint256,uint256,uint256,uint256) (runs: 260, μ: 488349, ~: 488493) -ERC20StandardTest:testERC20IncreaseAllowance(uint256,uint256,uint256,uint256) (runs: 260, μ: 488470, ~: 488614) -ERC20StandardTest:testERC20NameSymbolDecimals(uint256,string,string) (runs: 270, μ: 501948, ~: 504485) -ERC20StandardTest:testERC20TotalSupplyAndBalanceOf(uint256,string,uint256,uint256) (runs: 270, μ: 598945, ~: 558370) -ERC20StandardTest:testERC20Transfer(uint256,uint256,uint256,uint256) (runs: 268, μ: 567885, ~: 567675) -ERC20StandardTest:testERC20TransferFrom(uint256,uint256,uint256,uint256,uint256) (runs: 268, μ: 618244, ~: 617840) +CertifyTest:testCertify(uint256,uint256,string,string,uint256,uint256,bytes,uint256,bool) (runs: 270, μ: 972232, ~: 971724) +CertifyTest:testCertifyRevertOnFutureReferenceBlock(uint256,uint256,string,string,uint256,bytes,uint256,uint256,bool) (runs: 270, μ: 944059, ~: 944513) +CertifyTest:testCertifyRevertOnZeroCertifyUntil(uint256,uint256,uint256,string,string,bytes,uint256,bool) (runs: 270, μ: 936873, ~: 941967) +CertifyTest:testCertifyWithForceUntilTrue(uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256,uint256) (runs: 270, μ: 1202990, ~: 1200399) +CertifyTest:testCertifyWithForceUntilTrueRevertDeposit(uint256,uint256,string,string,uint256,uint256,bytes,uint256,uint256,uint256,uint256) (runs: 270, μ: 1157180, ~: 1159132) +CertifyTest:testVaultGetsCertified(uint256,uint256,uint256,uint256,string,string,bytes,uint256,uint256,uint256,bool) (runs: 270, μ: 1139422, ~: 1138315) +ConfiscateReceiptTest:testConfiscateReceipt(uint256,uint256,uint256,uint256,string,bytes,uint256,uint256,uint256,bool) (runs: 270, μ: 1244475, ~: 1204888) +ConfiscateReceiptTest:testConfiscateReceiptOnZeroBalance(uint256,uint256,string,string,bytes,uint256) (runs: 270, μ: 1012669, ~: 1010090) +ConfiscateSharesTest:testConfiscateShares(uint256,uint256,uint256,uint256,string,string,bytes,uint256,uint256,uint256,bool) (runs: 270, μ: 1188348, ~: 1186947) +ConfiscateSharesTest:testConfiscateSharesOnZeroBalance(uint256,uint256,string,string,bytes,uint256,uint256) (runs: 270, μ: 1106324, ~: 1108480) +ERC20PriceOracleReceiptVaultConstructionTest:testCheckConstructionEvent(uint256,string,string) (runs: 271, μ: 383457, ~: 386163) +ERC20PriceOracleReceiptVaultConstructionTest:testCreatingSeveralVaults(uint256,uint256,string,string,string,string) (runs: 270, μ: 730081, ~: 733963) +ERC20PriceOracleReceiptVaultDepositTest:testDepositBasic(uint256,string,uint256,uint256) (runs: 271, μ: 485856, ~: 445311) +ERC20PriceOracleReceiptVaultDepositTest:testDepositFlareFork(uint256) (runs: 11, μ: 499559, ~: 499759) +ERC20PriceOracleReceiptVaultDepositTest:testDepositSomeoneElse(uint256,uint256,string,uint256,uint256) (runs: 270, μ: 498034, ~: 453782) +ERC20PriceOracleReceiptVaultDepositTest:testDepositWithIncorrectPrice(uint256,string,string,bytes,uint256,uint256) (runs: 271, μ: 382357, ~: 376657) +ERC20PriceOracleReceiptVaultDepositTest:testDepositWithZeroAssets(uint256,string,string,bytes,uint256) (runs: 271, μ: 380294, ~: 375163) +ERC20PriceOracleReceiptVaultDepositTest:testDepositWithZeroReceiver(string,string,bytes,uint256,uint256) (runs: 271, μ: 375356, ~: 375859) +ERC20PriceOracleReceiptVaultDepositTest:testPreviewDepositReturnedShares(string,string,uint256,uint256) (runs: 271, μ: 373887, ~: 375217) +ERC20PriceOracleReceiptVaultMintTest:testMintBasic(uint256,string,uint256,uint256) (runs: 271, μ: 481264, ~: 440725) +ERC20PriceOracleReceiptVaultMintTest:testMintFlareFork(uint256) (runs: 11, μ: 520152, ~: 522391) +ERC20PriceOracleReceiptVaultMintTest:testMintSomeoneElse(uint256,uint256,string,uint256,uint256) (runs: 270, μ: 493433, ~: 449185) +ERC20PriceOracleReceiptVaultMintTest:testMintWithMinPrice(uint256,string,string,uint256,uint256,uint256) (runs: 260, μ: 378915, ~: 377089) +ERC20PriceOracleReceiptVaultMintTest:testMintWithZeroShares(uint256,string,uint256) (runs: 271, μ: 373884, ~: 329523) +ERC20PriceOracleReceiptVaultMintTest:testPreviewMintReturnedAssets(string,string,uint256,uint256) (runs: 271, μ: 374209, ~: 375443) +ERC20PriceOracleReceiptVaultRedeemTest:testPreviewRedeem(uint256,string,uint256,uint256) (runs: 270, μ: 370227, ~: 330540) +ERC20PriceOracleReceiptVaultRedeemTest:testRedeemBasic(uint256,string,uint256,uint256,uint256) (runs: 270, μ: 509930, ~: 466021) +ERC20PriceOracleReceiptVaultRedeemTest:testRedeemFlareFork(uint256) (runs: 11, μ: 549856, ~: 549555) +ERC20PriceOracleReceiptVaultRedeemTest:testRedeemMoreThanBalance(uint256,string,uint256,uint256,uint256) (runs: 271, μ: 496901, ~: 496212) +ERC20PriceOracleReceiptVaultRedeemTest:testRedeemRevertsOnZeroOwner(uint256,string,uint256,uint256,uint256) (runs: 270, μ: 489653, ~: 445740) +ERC20PriceOracleReceiptVaultRedeemTest:testRedeemRevertsOnZeroReceiver(uint256,string,uint256,uint256,uint256) (runs: 270, μ: 492049, ~: 448136) +ERC20PriceOracleReceiptVaultRedeemTest:testRedeemRevertsOnZeroShares(uint256,string,uint256,uint256) (runs: 271, μ: 485088, ~: 444542) +ERC20PriceOracleReceiptVaultRedeemTest:testRedeemWithERC20Approval(uint256,uint256,uint256,uint256,uint256) (runs: 265, μ: 543623, ~: 544118) +ERC20PriceOracleReceiptVaultWithdrawTest:testMultiplePricesAndHistoricalRedemptionsAndMint(uint256,uint256,uint256,uint256,uint256) (runs: 270, μ: 670843, ~: 671083) +ERC20PriceOracleReceiptVaultWithdrawTest:testPreviewWithdraw(uint256,string,uint256,uint256) (runs: 271, μ: 371349, ~: 330819) +ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawAliceBurnBob(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 268, μ: 671027, ~: 674462) +ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawBasic(uint256,string,uint256,uint256) (runs: 271, μ: 498684, ~: 463424) +ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawFlareFork(uint256) (runs: 11, μ: 550060, ~: 550260) +ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawMoreThanAssets(uint256,string,uint256,uint256,uint256) (runs: 271, μ: 495977, ~: 494984) +ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawRevertsOnZeroAssets(uint256,string,uint256,uint256) (runs: 271, μ: 485170, ~: 444616) +ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawRevertsOnZeroOwner(uint256,string,uint256,uint256) (runs: 271, μ: 484137, ~: 443584) +ERC20PriceOracleReceiptVaultWithdrawTest:testWithdrawRevertsOnZeroReceiver(uint256,string,uint256,uint256) (runs: 271, μ: 486491, ~: 445937) +ERC20PriceOracleReceiptVaultreceiptVaultTest:testConvertToAssets(uint256,string,uint256,uint256) (runs: 271, μ: 367888, ~: 327624) +ERC20PriceOracleReceiptVaultreceiptVaultTest:testConvertToAssetsDifferentCaller(uint256,uint256,string,uint256,uint256) (runs: 270, μ: 374629, ~: 330396) +ERC20PriceOracleReceiptVaultreceiptVaultTest:testConvertToShares(uint256,string,uint256,uint256) (runs: 271, μ: 370908, ~: 331214) +ERC20PriceOracleReceiptVaultreceiptVaultTest:testConvertToSharesDifferentCaller(uint256,uint256,string,uint256,uint256) (runs: 270, μ: 380945, ~: 336822) +ERC20PriceOracleReceiptVaultreceiptVaultTest:testMaxDeposit(uint256,string) (runs: 271, μ: 367916, ~: 366282) +ERC20PriceOracleReceiptVaultreceiptVaultTest:testMaxShares(uint256,string) (runs: 271, μ: 367904, ~: 366270) +ERC20PriceOracleReceiptVaultreceiptVaultTest:testReceiptVaultInformation(uint256,string,bytes) (runs: 271, μ: 376541, ~: 416893) +ERC20PriceOracleReceiptVaultreceiptVaultTest:testTotalAssets(uint256,string,uint256) (runs: 271, μ: 371140, ~: 326991) +ERC20PriceOracleReceiptVaultreceiptVaultTest:testVaultAsset(uint256,string) (runs: 271, μ: 367839, ~: 366205) +ERC20StandardTest:testERC20AllowanceAndApprove(uint256,uint256,uint256) (runs: 270, μ: 351478, ~: 351475) +ERC20StandardTest:testERC20DecreaseAllowance(uint256,uint256,uint256,uint256) (runs: 260, μ: 356810, ~: 357012) +ERC20StandardTest:testERC20IncreaseAllowance(uint256,uint256,uint256,uint256) (runs: 260, μ: 356931, ~: 357133) +ERC20StandardTest:testERC20NameSymbolDecimals(uint256,string,string) (runs: 271, μ: 370248, ~: 372942) +ERC20StandardTest:testERC20TotalSupplyAndBalanceOf(uint256,string,uint256,uint256) (runs: 271, μ: 467284, ~: 426864) +ERC20StandardTest:testERC20Transfer(uint256,uint256,uint256,uint256) (runs: 269, μ: 436379, ~: 436169) +ERC20StandardTest:testERC20TransferFrom(uint256,uint256,uint256,uint256,uint256) (runs: 268, μ: 486763, ~: 486334) FtsoV2LTSFeedOracleTest:testFtsoV2LTSFeedOracle() (gas: 506535) -FtsoV2LTSFeedOracleTest:testFtsoV2LTSFeedOraclePaid(uint128) (runs: 14, μ: 745478, ~: 745478) +FtsoV2LTSFeedOracleTest:testFtsoV2LTSFeedOraclePaid(uint128) (runs: 15, μ: 745478, ~: 745478) FtsoV2LTSFeedOracleTest:testFtsoV2LTSFeedOracleStale() (gas: 504698) -MulticallTest:testDepositMulticall(uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 267, μ: 1258180, ~: 1219421) -MulticallTest:testMintMulticall(uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 267, μ: 1258301, ~: 1219542) -MulticallTest:testRedeemMulticall(uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 267, μ: 1246352, ~: 1207905) -MulticallTest:testWithdrawMulticall(uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 267, μ: 1246370, ~: 1207923) -OffChainAssetReceiptVaultTest:testConstruction(uint256,string,string) (runs: 270, μ: 1098351, ~: 1100900) -OffChainAssetReceiptVaultTest:testCreatingSeveralVaults(uint256,uint256,string,string,string,string) (runs: 269, μ: 2074116, ~: 2078181) -OffChainAssetReceiptVaultTest:testNonZeroAsset(uint256,address,string,string) (runs: 268, μ: 468896, ~: 469089) -OffChainAssetReceiptVaultTest:testVaultIsReceiptManager(uint256,string,string) (runs: 270, μ: 1091957, ~: 1094478) -OffChainAssetReceiptVaultTest:testZeroAdmin(string,string) (runs: 270, μ: 443993, ~: 448086) -OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransfer(uint256,uint256,string,string,uint256,uint256,bytes,uint256,bool) (runs: 269, μ: 1118433, ~: 1118284) -OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransferForConfiscatorTo(uint256,uint256,string,string) (runs: 269, μ: 1076286, ~: 1079213) -OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransferForHandlerFrom(uint256,uint256,string,string) (runs: 269, μ: 1071752, ~: 1074679) -OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransferForHandlerTo(uint256,uint256,string,string) (runs: 269, μ: 1073907, ~: 1076834) -OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransferRevert(uint256,uint256,uint256,string,string) (runs: 269, μ: 1063770, ~: 1059340) -OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransferRevertExpiredCertification(uint256,uint256,string,string,uint256,uint256,uint256,bytes) (runs: 269, μ: 1112335, ~: 1114686) -OffchainAssetReceiptVaultDepositTest:testDeposit(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1211657, ~: 1208752) -OffchainAssetReceiptVaultDepositTest:testDepositToSomeoneElseExpiredCertification(uint256,string,string,uint256,uint256,uint256,bytes,uint256,uint256,uint256) (runs: 270, μ: 1177174, ~: 1173904) -OffchainAssetReceiptVaultDepositTest:testDepositToSomeoneElseNotCertified(uint256,string,string,uint256,uint256,uint256,bytes,uint256) (runs: 270, μ: 1122505, ~: 1118154) -OffchainAssetReceiptVaultDepositTest:testDepositToSomeoneElseWithDepositorRole(uint256,string,string,uint256,uint256,uint256,bytes) (runs: 270, μ: 1238775, ~: 1237569) -OffchainAssetReceiptVaultDepositTest:testDepositWithoutDepositorRole(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1055053, ~: 1051872) -OffchainAssetReceiptVaultDepositTest:testDepositWithoutDepositorRoleForAdmin(uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1054081, ~: 1051210) -OffchainAssetReceiptVaultDepositTest:testMinShareRatio(uint256,uint256,string,string,uint256,uint256,bytes) (runs: 269, μ: 1080083, ~: 1077727) -OffchainAssetReceiptVaultDepositTest:testMinShareRatio(uint256,uint256,string,string,uint256,uint256,bytes) (runs: 269, μ: 1080107, ~: 1077673) -OffchainAssetReceiptVaultDepositTest:testMint(uint256,uint256,string,string,uint256,bytes,uint256) (runs: 269, μ: 1209311, ~: 1208267) -OffchainAssetReceiptVaultDepositTest:testMintToSomeoneElseExpiredCertification(uint256,string,string,uint256,uint256,uint256,bytes,uint256,uint256,uint256) (runs: 270, μ: 1177277, ~: 1173978) -OffchainAssetReceiptVaultDepositTest:testMintToSomeoneElseNotCertified(uint256,string,string,uint256,uint256,uint256,bytes,uint256) (runs: 270, μ: 1122570, ~: 1118205) -OffchainAssetReceiptVaultDepositTest:testMintToSomeoneElseWithDepositorRole(uint256,string,string,uint256,uint256,uint256,bytes) (runs: 270, μ: 1238811, ~: 1237776) -OffchainAssetReceiptVaultDepositTest:testMintWithoutDepositorRole(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1055039, ~: 1051859) -OffchainAssetReceiptVaultDepositTest:testMintWithoutDepositorRoleForAdmin(uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1054145, ~: 1051264) -OffchainAssetReceiptVaultDepositTest:testMultipleDeposit(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1261419, ~: 1259879) -OffchainAssetReceiptVaultDepositTest:testMultipleMints(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1261577, ~: 1260020) -OffchainAssetReceiptVaultDepositTest:testPreviewDepositReturnedShares(uint256,uint256,string,string,uint256) (runs: 269, μ: 1070916, ~: 1073521) -OffchainAssetReceiptVaultDepositTest:testPreviewMintReturnedAssets(uint256,uint256,string,string,uint256) (runs: 269, μ: 1071000, ~: 1073607) -OffchainAssetReceiptVaultDepositTest:testPreviewMintRevertWithoutRole(uint256,uint256,string,string,uint256) (runs: 269, μ: 1046996, ~: 1049637) -OffchainAssetReceiptVaultDepositTest:testReceiptInformationEvent(uint256,string,string,uint256,uint256,uint256,bytes) (runs: 270, μ: 1242202, ~: 1240950) -OffchainAssetReceiptVaultDepositTest:testZeroAssetsAmount(uint256,uint256,string,string,bytes,uint256) (runs: 269, μ: 1079564, ~: 1077063) -OffchainAssetReceiptVaultDepositTest:testZeroAssetsAmount(uint256,uint256,string,string,bytes,uint256) (runs: 269, μ: 1079637, ~: 1077131) -OffchainAssetReceiptVaultDepositTest:testZeroReceiver(uint256,uint256,string,string,uint256,uint256,bytes) (runs: 269, μ: 1080632, ~: 1078522) -OffchainAssetReceiptVaultDepositTest:testZeroReceiver(uint256,uint256,string,string,uint256,uint256,bytes) (runs: 269, μ: 1080716, ~: 1078595) -OffchainAssetReceiptVaultHandlerTest:testReceiptTransferHandler(uint256,uint256,string,uint256,uint256,uint256,bool,uint256) (runs: 269, μ: 1347825, ~: 1347147) -OffchainAssetReceiptVaultHandlerTest:testReceiptTransferHandlerOwner(uint256,uint256,uint256,string,uint256,uint256,uint256,bool,uint256) (runs: 268, μ: 1353067, ~: 1351713) -OffchainAssetReceiptVaultHandlerTest:testReceiptTransferHandlerReceiver(uint256,uint256,uint256,string,uint256,uint256,uint256,bool,uint256) (runs: 268, μ: 1360704, ~: 1359350) -PriceOracleV2Test:testPriceOracleV2(uint256,uint256) (runs: 270, μ: 167102, ~: 167692) -PriceOracleV2Test:testPriceOracleV2Refund(uint256) (runs: 270, μ: 201761, ~: 202130) -ReceiptMetadataTest:testReceiptName() (gas: 621450) -ReceiptMetadataTest:testReceiptSymbol() (gas: 621483) -ReceiptMetadataTest:testReceiptURI(uint256) (runs: 270, μ: 635040, ~: 635040) -ReceiptTest:testBalanceOf(uint256,uint256,uint256,bytes) (runs: 270, μ: 686510, ~: 686207) -ReceiptTest:testBalanceOfBatch(uint256,uint256,uint256,uint256,uint256,uint256,bytes) (runs: 269, μ: 729945, ~: 729371) -ReceiptTest:testInitialize() (gas: 620102) -ReceiptTest:testManagerBurn(uint256,uint256,uint256,bytes) (runs: 270, μ: 684909, ~: 684084) -ReceiptTest:testManagerBurnNotEnoughBalance(uint256,uint256,uint256,bytes,uint256) (runs: 270, μ: 698929, ~: 698665) -ReceiptTest:testManagerBurnRevertAlice(uint256,uint256,uint256,bytes) (runs: 270, μ: 626427, ~: 626367) -ReceiptTest:testManagerMint(uint256,uint256,uint256,bytes) (runs: 270, μ: 686544, ~: 686241) -ReceiptTest:testManagerMintRevertAlice(uint256,uint256,uint256,bytes) (runs: 270, μ: 626469, ~: 626409) -ReceiptTest:testManagerTransferFromMoreThanBalance(uint256,uint256,uint256,uint256,bytes,uint256) (runs: 269, μ: 717254, ~: 717259) -ReceiptTest:testManagerTransferFromSelf(uint256,uint256,uint256,uint256,bytes) (runs: 270, μ: 623692, ~: 623626) -ReceiptTest:testSafeBatchTransferFrom(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 268, μ: 760771, ~: 760767) -ReceiptTest:testSafeTransferFrom(uint256,uint256,uint256,uint256) (runs: 269, μ: 725848, ~: 725847) -ReceiptTest:testSetApprovalForAllAndIsApprovedForAll(uint256,uint256) (runs: 269, μ: 248098, ~: 248098) -ReceiptTest:testTransferManagerTransferFrom(uint256,uint256,uint256,uint256,bytes) (runs: 269, μ: 726885, ~: 726430) -ReceiptTest:testUnauthorizedTransferManagerTransferFrom(uint256,uint256,uint256,uint256,bytes) (runs: 269, μ: 696333, ~: 695878) -RedeemTest:testOffchainAssetWithdrawWithERC20Approval(uint256,uint256,uint256,uint256,uint256) (runs: 264, μ: 1378218, ~: 1379034) -RedeemTest:testPreviewRedeem(uint256,uint256,uint256,string,string,uint256) (runs: 269, μ: 1076245, ~: 1073785) -RedeemTest:testPreviewRedeemReturnsZero(uint256,uint256,string,string,uint256) (runs: 270, μ: 1044412, ~: 1046734) -RedeemTest:testRedeem(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1202784, ~: 1200137) -RedeemTest:testRedeemInvalidId(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1240489, ~: 1237434) -RedeemTest:testRedeemOfSomeoneElse(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,bool) (runs: 269, μ: 1302222, ~: 1301028) -RedeemTest:testRedeemOthersAssetsReverts(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,bool) (runs: 269, μ: 1321270, ~: 1320122) -RedeemTest:testRedeemOverSeveralIds(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 266, μ: 1419249, ~: 1439610) -RedeemTest:testRedeemRevertsWithoutRole(uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1213594, ~: 1210598) -RedeemTest:testRedeemSomePartOfAssetsDeposited(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1259649, ~: 1259561) -RedeemTest:testRedeemToSomeoneElse(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1202783, ~: 1200136) -RedeemTest:testRedeemZeroAssetsAmount(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1240236, ~: 1237234) -RedeemTest:testRedeemZeroOwner(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1243358, ~: 1240343) -RedeemTest:testRedeemZeroReceiver(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1240316, ~: 1237260) -RedeemTest:testWithdrawMoreThanBalance(uint256,uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 262, μ: 1244382, ~: 1244474) -RedepositTest:testReDeposit(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256) (runs: 269, μ: 1292187, ~: 1287875) -RedepositTest:testReDepositOverSeveralIds(uint256,uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256) (runs: 269, μ: 1485310, ~: 1484238) -RedepositTest:testReDepositRevertsWithZeroAssets(uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256) (runs: 269, μ: 1263415, ~: 1262816) -RedepositTest:testReDepositToNonExistentReceipt(uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256,uint256) (runs: 269, μ: 1275494, ~: 1273760) -RedepositTest:testReDepositToSomeoneElse(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1268618, ~: 1266055) -RedepositTest:testReDepositToSomeoneElseReverts(uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256,uint256) (runs: 269, μ: 1283200, ~: 1281418) -RedepositTest:testReDepositToSomeoneElseWhileCertified(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256) (runs: 269, μ: 1300341, ~: 1296046) -RedepositTest:testReDepositrevertsPastTopID(uint256,uint256,uint256,uint256,uint256,bytes,string,uint256,uint256,uint256,uint256) (runs: 269, μ: 1307113, ~: 1269122) -RolesTest:testCertifyWithoutRole(uint256,string,string,uint256,bytes) (runs: 270, μ: 1086351, ~: 1086714) -RolesTest:testConfiscateWithoutRole(uint256,string,string,bytes) (runs: 270, μ: 1089339, ~: 1088009) -RolesTest:testDepositWithoutDepositorRole(uint256,uint256,string,string,uint256,bytes) (runs: 269, μ: 1050397, ~: 1052511) -RolesTest:testGrantAdminRoles(uint256,string,string) (runs: 270, μ: 1058233, ~: 1060716) -RolesTest:testSetERC1155TierWithoutRole(uint256,string,string,bytes,uint8,uint256[]) (runs: 270, μ: 1673409, ~: 1673261) -RolesTest:testSetERC20TierWithoutRole(uint256,string,string,bytes,uint8,uint256[]) (runs: 270, μ: 1673476, ~: 1673328) -RolesTest:testSnapshotWithoutRole(uint256,string,string,bytes) (runs: 270, μ: 1087549, ~: 1086220) +MulticallTest:testDepositMulticall(uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 268, μ: 1126880, ~: 1087952) +MulticallTest:testMintMulticall(uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 268, μ: 1127001, ~: 1088073) +MulticallTest:testRedeemMulticall(uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 268, μ: 1115072, ~: 1076510) +MulticallTest:testWithdrawMulticall(uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 268, μ: 1115090, ~: 1076528) +OffChainAssetReceiptVaultTest:testConstruction(uint256,string,string) (runs: 271, μ: 966650, ~: 969357) +OffChainAssetReceiptVaultTest:testCreatingSeveralVaults(uint256,uint256,string,string,string,string) (runs: 270, μ: 1811213, ~: 1815095) +OffChainAssetReceiptVaultTest:testNonZeroAsset(uint256,address,string,string) (runs: 271, μ: 337191, ~: 337546) +OffChainAssetReceiptVaultTest:testVaultIsReceiptManager(uint256,string,string) (runs: 271, μ: 960257, ~: 962935) +OffChainAssetReceiptVaultTest:testZeroAdmin(string,string) (runs: 271, μ: 312465, ~: 316543) +OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransfer(uint256,uint256,string,string,uint256,uint256,bytes,uint256,bool) (runs: 270, μ: 987034, ~: 986741) +OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransferForConfiscatorTo(uint256,uint256,string,string) (runs: 270, μ: 944921, ~: 947670) +OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransferForHandlerFrom(uint256,uint256,string,string) (runs: 270, μ: 940387, ~: 943136) +OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransferForHandlerTo(uint256,uint256,string,string) (runs: 270, μ: 942542, ~: 945291) +OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransferRevert(uint256,uint256,uint256,string,string) (runs: 270, μ: 932208, ~: 927797) +OffchainAssetReceipetVaultAuthorizedReceiptTransferTest:testAuthorizeReceiptTransferRevertExpiredCertification(uint256,uint256,string,string,uint256,uint256,uint256,bytes) (runs: 270, μ: 980987, ~: 983293) +OffchainAssetReceiptVaultDepositTest:testDeposit(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1080153, ~: 1077246) +OffchainAssetReceiptVaultDepositTest:testDepositToSomeoneElseExpiredCertification(uint256,string,string,uint256,uint256,uint256,bytes,uint256,uint256,uint256) (runs: 271, μ: 1045450, ~: 1042361) +OffchainAssetReceiptVaultDepositTest:testDepositToSomeoneElseNotCertified(uint256,string,string,uint256,uint256,uint256,bytes,uint256) (runs: 271, μ: 990790, ~: 986596) +OffchainAssetReceiptVaultDepositTest:testDepositToSomeoneElseWithDepositorRole(uint256,string,string,uint256,uint256,uint256,bytes) (runs: 271, μ: 1107093, ~: 1106063) +OffchainAssetReceiptVaultDepositTest:testDepositWithoutDepositorRole(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 923508, ~: 920696) +OffchainAssetReceiptVaultDepositTest:testDepositWithoutDepositorRoleForAdmin(uint256,uint256,uint256,bytes,string,string) (runs: 271, μ: 922360, ~: 919667) +OffchainAssetReceiptVaultDepositTest:testMinShareRatio(uint256,uint256,string,string,uint256,uint256,bytes) (runs: 270, μ: 948684, ~: 946385) +OffchainAssetReceiptVaultDepositTest:testMinShareRatio(uint256,uint256,string,string,uint256,uint256,bytes) (runs: 270, μ: 948723, ~: 946362) +OffchainAssetReceiptVaultDepositTest:testMint(uint256,uint256,string,string,uint256,bytes,uint256) (runs: 270, μ: 1077992, ~: 1076759) +OffchainAssetReceiptVaultDepositTest:testMintToSomeoneElseExpiredCertification(uint256,string,string,uint256,uint256,uint256,bytes,uint256,uint256,uint256) (runs: 271, μ: 1045523, ~: 1042435) +OffchainAssetReceiptVaultDepositTest:testMintToSomeoneElseNotCertified(uint256,string,string,uint256,uint256,uint256,bytes,uint256) (runs: 271, μ: 990831, ~: 986647) +OffchainAssetReceiptVaultDepositTest:testMintToSomeoneElseWithDepositorRole(uint256,string,string,uint256,uint256,uint256,bytes) (runs: 271, μ: 1107138, ~: 1106111) +OffchainAssetReceiptVaultDepositTest:testMintWithoutDepositorRole(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 923474, ~: 920316) +OffchainAssetReceiptVaultDepositTest:testMintWithoutDepositorRoleForAdmin(uint256,uint256,uint256,bytes,string,string) (runs: 271, μ: 922416, ~: 919721) +OffchainAssetReceiptVaultDepositTest:testMultipleDeposit(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1129941, ~: 1128410) +OffchainAssetReceiptVaultDepositTest:testMultipleMints(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1130086, ~: 1128544) +OffchainAssetReceiptVaultDepositTest:testPreviewDepositReturnedShares(uint256,uint256,string,string,uint256) (runs: 270, μ: 939554, ~: 941978) +OffchainAssetReceiptVaultDepositTest:testPreviewMintReturnedAssets(uint256,uint256,string,string,uint256) (runs: 270, μ: 939637, ~: 942064) +OffchainAssetReceiptVaultDepositTest:testPreviewMintRevertWithoutRole(uint256,uint256,string,string,uint256) (runs: 270, μ: 915630, ~: 918094) +OffchainAssetReceiptVaultDepositTest:testReceiptInformationEvent(uint256,string,string,uint256,uint256,uint256,bytes) (runs: 271, μ: 1110531, ~: 1109285) +OffchainAssetReceiptVaultDepositTest:testZeroAssetsAmount(uint256,uint256,string,string,bytes,uint256) (runs: 270, μ: 948189, ~: 945712) +OffchainAssetReceiptVaultDepositTest:testZeroAssetsAmount(uint256,uint256,string,string,bytes,uint256) (runs: 270, μ: 948254, ~: 945780) +OffchainAssetReceiptVaultDepositTest:testZeroReceiver(uint256,uint256,string,string,uint256,uint256,bytes) (runs: 270, μ: 949253, ~: 946979) +OffchainAssetReceiptVaultDepositTest:testZeroReceiver(uint256,uint256,string,string,uint256,uint256,bytes) (runs: 270, μ: 949321, ~: 947052) +OffchainAssetReceiptVaultHandlerTest:testReceiptTransferHandler(uint256,uint256,string,uint256,uint256,uint256,bool,uint256) (runs: 270, μ: 1216529, ~: 1216020) +OffchainAssetReceiptVaultHandlerTest:testReceiptTransferHandlerOwner(uint256,uint256,uint256,string,uint256,uint256,uint256,bool,uint256) (runs: 269, μ: 1221816, ~: 1220929) +OffchainAssetReceiptVaultHandlerTest:testReceiptTransferHandlerReceiver(uint256,uint256,uint256,string,uint256,uint256,uint256,bool,uint256) (runs: 269, μ: 1229453, ~: 1228566) +PriceOracleV2Test:testPriceOracleV2(uint256,uint256) (runs: 271, μ: 167104, ~: 167692) +PriceOracleV2Test:testPriceOracleV2Refund(uint256) (runs: 271, μ: 201762, ~: 202130) +ReceiptMetadataTest:testOverriddenMetadata(uint256,string,string,string,string,string) (runs: 270, μ: 3212297, ~: 3213196) +ReceiptMetadataTest:testOverriddenMetadataWithImage(uint256,string,string,string,string,string,string) (runs: 269, μ: 3294214, ~: 3286498) +ReceiptMetadataTest:testReceiptName() (gas: 657598) +ReceiptMetadataTest:testReceiptSymbol() (gas: 657597) +ReceiptMetadataTest:testReceiptURI(uint256) (runs: 270, μ: 716276, ~: 716686) +ReceiptMetadataTest:testReceiptURIZeroError() (gas: 656124) +ReceiptTest:testBalanceOf(uint256,uint256,uint256,bytes) (runs: 271, μ: 720720, ~: 720415) +ReceiptTest:testBalanceOfBatch(uint256,uint256,uint256,uint256,uint256,uint256,bytes) (runs: 270, μ: 764273, ~: 763697) +ReceiptTest:testInitialize() (gas: 654168) +ReceiptTest:testManagerBurn(uint256,uint256,uint256,bytes) (runs: 271, μ: 719243, ~: 718411) +ReceiptTest:testManagerBurnNotEnoughBalance(uint256,uint256,uint256,bytes,uint256) (runs: 271, μ: 733254, ~: 732992) +ReceiptTest:testManagerBurnRevertAlice(uint256,uint256,uint256,bytes) (runs: 271, μ: 660533, ~: 660472) +ReceiptTest:testManagerMint(uint256,uint256,uint256,bytes) (runs: 271, μ: 720754, ~: 720449) +ReceiptTest:testManagerMintRevertAlice(uint256,uint256,uint256,bytes) (runs: 271, μ: 660575, ~: 660514) +ReceiptTest:testManagerTransferFromMoreThanBalance(uint256,uint256,uint256,uint256,bytes,uint256) (runs: 270, μ: 751589, ~: 751563) +ReceiptTest:testManagerTransferFromSelf(uint256,uint256,uint256,uint256,bytes) (runs: 271, μ: 657796, ~: 657730) +ReceiptTest:testSafeBatchTransferFrom(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 269, μ: 795179, ~: 795175) +ReceiptTest:testSafeTransferFrom(uint256,uint256,uint256,uint256) (runs: 270, μ: 760189, ~: 760188) +ReceiptTest:testSetApprovalForAllAndIsApprovedForAll(uint256,uint256) (runs: 270, μ: 116555, ~: 116555) +ReceiptTest:testTransferManagerTransferFrom(uint256,uint256,uint256,uint256,bytes) (runs: 270, μ: 761190, ~: 760734) +ReceiptTest:testUnauthorizedTransferManagerTransferFrom(uint256,uint256,uint256,uint256,bytes) (runs: 270, μ: 730638, ~: 730182) +RedeemTest:testOffchainAssetWithdrawWithERC20Approval(uint256,uint256,uint256,uint256,uint256) (runs: 265, μ: 1246730, ~: 1247565) +RedeemTest:testPreviewRedeem(uint256,uint256,uint256,string,string,uint256) (runs: 270, μ: 944693, ~: 942242) +RedeemTest:testPreviewRedeemReturnsZero(uint256,uint256,string,string,uint256) (runs: 271, μ: 913040, ~: 915191) +RedeemTest:testRedeem(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1071325, ~: 1068668) +RedeemTest:testRedeemInvalidId(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1108991, ~: 1105928) +RedeemTest:testRedeemOfSomeoneElse(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,bool) (runs: 270, μ: 1170693, ~: 1169522) +RedeemTest:testRedeemOthersAssetsReverts(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,bool) (runs: 270, μ: 1189745, ~: 1188616) +RedeemTest:testRedeemOverSeveralIds(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 267, μ: 1288077, ~: 1308492) +RedeemTest:testRedeemRevertsWithoutRole(uint256,uint256,uint256,bytes,string,string) (runs: 271, μ: 1081918, ~: 1079092) +RedeemTest:testRedeemSomePartOfAssetsDeposited(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1127972, ~: 1128386) +RedeemTest:testRedeemToSomeoneElse(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1071324, ~: 1068667) +RedeemTest:testRedeemZeroAssetsAmount(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1108735, ~: 1105728) +RedeemTest:testRedeemZeroOwner(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1111858, ~: 1108837) +RedeemTest:testRedeemZeroReceiver(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1108818, ~: 1105754) +RedeemTest:testWithdrawMoreThanBalance(uint256,uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 264, μ: 1112019, ~: 1112968) +RedepositTest:testReDeposit(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256) (runs: 270, μ: 1160711, ~: 1156729) +RedepositTest:testReDepositOverSeveralIds(uint256,uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256) (runs: 270, μ: 1353946, ~: 1352872) +RedepositTest:testReDepositRevertsWithZeroAssets(uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256) (runs: 270, μ: 1131753, ~: 1131248) +RedepositTest:testReDepositToNonExistentReceipt(uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256,uint256) (runs: 270, μ: 1144085, ~: 1142254) +RedepositTest:testReDepositToSomeoneElse(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1137141, ~: 1134586) +RedepositTest:testReDepositToSomeoneElseReverts(uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256,uint256) (runs: 270, μ: 1151559, ~: 1149912) +RedepositTest:testReDepositToSomeoneElseWhileCertified(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,uint256) (runs: 270, μ: 1168863, ~: 1164903) +RedepositTest:testReDepositrevertsPastTopID(uint256,uint256,uint256,uint256,uint256,bytes,string,uint256,uint256,uint256,uint256) (runs: 270, μ: 1175824, ~: 1137712) +RolesTest:testCertifyWithoutRole(uint256,string,string,uint256,bytes) (runs: 271, μ: 954647, ~: 955171) +RolesTest:testConfiscateWithoutRole(uint256,string,string,bytes) (runs: 271, μ: 957626, ~: 956466) +RolesTest:testDepositWithoutDepositorRole(uint256,uint256,string,string,uint256,bytes) (runs: 270, μ: 919034, ~: 920968) +RolesTest:testGrantAdminRoles(uint256,string,string) (runs: 271, μ: 926531, ~: 929173) +RolesTest:testSetERC1155TierWithoutRole(uint256,string,string,bytes,uint8,uint256[]) (runs: 271, μ: 1541680, ~: 1541550) +RolesTest:testSetERC20TierWithoutRole(uint256,string,string,bytes,uint8,uint256[]) (runs: 271, μ: 1541747, ~: 1541617) +RolesTest:testSnapshotWithoutRole(uint256,string,string,bytes) (runs: 271, μ: 955836, ~: 954677) SceptreStakedFlrOracleTest:testSceptreStakedFlrOracle() (gas: 184222) -SceptreStakedFlrOracleTest:testSceptreStakedFlrOracleRefund(uint128,uint128) (runs: 270, μ: 194277, ~: 193742) -SnapshotTest:testMultipleSnapshot(uint256,bytes,string,string) (runs: 270, μ: 1110928, ~: 1111413) -SnapshotTest:testSnapshot(uint256,bytes,string,string) (runs: 270, μ: 1100047, ~: 1100978) -TiersTest:testAuthorizeReceiptTransferOnRandomTier(uint256,uint256,string,bytes,uint8,uint256[],uint256,uint256,uint256,address,bool) (runs: 269, μ: 4098763, ~: 4086383) -TiersTest:testERC1155TierControlsTokenMovement(uint256,uint256,string,bytes,uint8,uint256[],address,uint256,uint256,bool,uint256) (runs: 269, μ: 4391514, ~: 4455335) -TiersTest:testERC20TierControlsTokenMovement(uint256,uint256,string,bytes,uint8,uint256[],address,uint256,uint256,bool,uint256) (runs: 269, μ: 4327762, ~: 4391381) -TiersTest:testReceiptTransfer(uint256,uint256,string,uint8,uint256[],uint256,uint256,address,bool) (runs: 269, μ: 4192398, ~: 4047043) -TiersTest:testSetERC1155Tier(uint256,uint256,string,string,bytes,uint8,uint256[],address) (runs: 269, μ: 3986159, ~: 3993604) -TiersTest:testSetERC20Tier(uint256,uint256,string,string,bytes,uint8,uint256[],address) (runs: 269, μ: 3964229, ~: 3971526) -TiersTest:testTransferOnUnauthorizedSenderTier(uint256,uint256,string,bytes,uint8,uint256[],uint256,uint256,address,bool) (runs: 269, μ: 4194596, ~: 4188245) -TwoPriceOracleTest:testNotOracle(address,address) (runs: 270, μ: 3895131, ~: 41855) -TwoPriceOracleTest:testOracleConstructs(address,uint256,address,uint256) (runs: 270, μ: 355816, ~: 355946) -TwoPriceOracleTest:testSameBaseQuote(address) (runs: 270, μ: 37396, ~: 37396) -TwoPriceOracleTest:testZeroAddressBase(address) (runs: 270, μ: 41409, ~: 41405) +SceptreStakedFlrOracleTest:testSceptreStakedFlrOracleRefund(uint128,uint128) (runs: 271, μ: 194275, ~: 193742) +SnapshotTest:testMultipleSnapshot(uint256,bytes,string,string) (runs: 271, μ: 979303, ~: 979870) +SnapshotTest:testSnapshot(uint256,bytes,string,string) (runs: 271, μ: 968424, ~: 969435) +TiersTest:testAuthorizeReceiptTransferOnRandomTier(uint256,uint256,string,bytes,uint8,uint256[],uint256,uint256,uint256,address,bool) (runs: 270, μ: 3952636, ~: 3949614) +TiersTest:testERC1155TierControlsTokenMovement(uint256,uint256,string,bytes,uint8,uint256[],address,uint256,uint256,bool,uint256) (runs: 270, μ: 4254995, ~: 4316781) +TiersTest:testERC20TierControlsTokenMovement(uint256,uint256,string,bytes,uint8,uint256[],address,uint256,uint256,bool,uint256) (runs: 270, μ: 4191202, ~: 4252990) +TiersTest:testReceiptTransfer(uint256,uint256,string,uint8,uint256[],uint256,uint256,address,bool) (runs: 270, μ: 4062915, ~: 3926594) +TiersTest:testSetERC1155Tier(uint256,uint256,string,string,bytes,uint8,uint256[],address) (runs: 270, μ: 3845675, ~: 3849426) +TiersTest:testSetERC20Tier(uint256,uint256,string,string,bytes,uint8,uint256[],address) (runs: 270, μ: 3823892, ~: 3827348) +TiersTest:testTransferOnUnauthorizedSenderTier(uint256,uint256,string,bytes,uint8,uint256[],uint256,uint256,address,bool) (runs: 270, μ: 4070681, ~: 4062197) +TwoPriceOracleTest:testNotOracle(address,address) (runs: 271, μ: 3880913, ~: 41855) +TwoPriceOracleTest:testOracleConstructs(address,uint256,address,uint256) (runs: 271, μ: 355819, ~: 355946) +TwoPriceOracleTest:testSameBaseQuote(address) (runs: 271, μ: 37396, ~: 37396) +TwoPriceOracleTest:testZeroAddressBase(address) (runs: 271, μ: 41409, ~: 41405) TwoPriceOracleTest:testZeroAddressBoth() (gas: 36420) -TwoPriceOracleTest:testZeroAddressQuote(address) (runs: 270, μ: 41407, ~: 41407) -WithdrawTest:testOffchainAssetWithdrawAliceBurnBob(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 269, μ: 1475944, ~: 1476126) -WithdrawTest:testPreviewWithdraw(uint256,uint256,uint256,string,string) (runs: 269, μ: 1076911, ~: 1072098) -WithdrawTest:testPreviewWithdrawReturnsZero(uint256,uint256,string,string,uint256) (runs: 270, μ: 1044116, ~: 1046758) -WithdrawTest:testWithdraw(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1202783, ~: 1200135) -WithdrawTest:testWithdrawInvalidId(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1240531, ~: 1237475) -WithdrawTest:testWithdrawMoreThanBalance(uint256,uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 263, μ: 1244932, ~: 1244468) -WithdrawTest:testWithdrawOfSomeoneElse(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,bool) (runs: 269, μ: 1302661, ~: 1301534) -WithdrawTest:testWithdrawOthersAssetsReverts(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,bool) (runs: 269, μ: 1322151, ~: 1321024) -WithdrawTest:testWithdrawOverSeveralIds(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 267, μ: 1419053, ~: 1438571) -WithdrawTest:testWithdrawRevertsWithoutRole(uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1214160, ~: 1210932) -WithdrawTest:testWithdrawSomePartOfAssetsDeposited(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1259640, ~: 1259829) -WithdrawTest:testWithdrawToSomeoneElse(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1202804, ~: 1200156) -WithdrawTest:testWithdrawZeroAssetsAmount(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1238983, ~: 1237993) -WithdrawTest:testWithdrawZeroOwner(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1243018, ~: 1242028) -WithdrawTest:testWithdrawZeroReceiver(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 269, μ: 1239049, ~: 1237995) \ No newline at end of file +TwoPriceOracleTest:testZeroAddressQuote(address) (runs: 271, μ: 41407, ~: 41407) +WithdrawTest:testOffchainAssetWithdrawAliceBurnBob(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 270, μ: 1344701, ~: 1344904) +WithdrawTest:testPreviewWithdraw(uint256,uint256,uint256,string,string) (runs: 270, μ: 945349, ~: 940555) +WithdrawTest:testPreviewWithdrawReturnsZero(uint256,uint256,string,string,uint256) (runs: 271, μ: 912748, ~: 915215) +WithdrawTest:testWithdraw(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1071305, ~: 1068666) +WithdrawTest:testWithdrawInvalidId(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1109014, ~: 1105969) +WithdrawTest:testWithdrawMoreThanBalance(uint256,uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 265, μ: 1113005, ~: 1112962) +WithdrawTest:testWithdrawOfSomeoneElse(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,bool) (runs: 270, μ: 1171137, ~: 1170028) +WithdrawTest:testWithdrawOthersAssetsReverts(uint256,uint256,uint256,uint256,bytes,string,string,uint256,uint256,bool) (runs: 270, μ: 1190627, ~: 1189518) +WithdrawTest:testWithdrawOverSeveralIds(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes,string) (runs: 268, μ: 1287939, ~: 1307513) +WithdrawTest:testWithdrawRevertsWithoutRole(uint256,uint256,uint256,bytes,string,string) (runs: 271, μ: 1082466, ~: 1079426) +WithdrawTest:testWithdrawSomePartOfAssetsDeposited(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1128158, ~: 1128360) +WithdrawTest:testWithdrawToSomeoneElse(uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1071326, ~: 1068687) +WithdrawTest:testWithdrawZeroAssetsAmount(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1107457, ~: 1106484) +WithdrawTest:testWithdrawZeroOwner(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1111492, ~: 1110519) +WithdrawTest:testWithdrawZeroReceiver(uint256,uint256,uint256,uint256,uint256,bytes,string,string) (runs: 270, μ: 1107518, ~: 1106486) \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index f7d62900..3e553307 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "lib/solady"] path = lib/solady url = https://github.com/Vectorized/solady +[submodule "lib/rain.string"] + path = lib/rain.string + url = https://github.com/rainlanguage/rain.string diff --git a/lib/rain.string b/lib/rain.string new file mode 160000 index 00000000..452e4b85 --- /dev/null +++ b/lib/rain.string @@ -0,0 +1 @@ +Subproject commit 452e4b85f04c08ea8ab9b4b7b7a8ce49e9b24aa9 diff --git a/src/concrete/receipt/ERC20PriceOracleReceipt.sol b/src/concrete/receipt/ERC20PriceOracleReceipt.sol new file mode 100644 index 00000000..fa745241 --- /dev/null +++ b/src/concrete/receipt/ERC20PriceOracleReceipt.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: LicenseRef-DCL-1.0 +// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd +pragma solidity =0.8.25; + +import {Receipt, DATA_URI_BASE64_PREFIX, Base64} from "./Receipt.sol"; +import {LibFixedPointDecimalFormat} from "rain.math.fixedpoint/lib/format/LibFixedPointDecimalFormat.sol"; +import {ZeroReceiptId} from "../../error/ErrReceipt.sol"; +import { + LibFixedPointDecimalArithmeticOpenZeppelin, + Math +} from "rain.math.fixedpoint/lib/LibFixedPointDecimalArithmeticOpenZeppelin.sol"; +import {FIXED_POINT_ONE} from "rain.math.fixedpoint/lib/FixedPointDecimalConstants.sol"; + +/// @dev The default symbol for the reference asset. +string constant DEFAULT_REFERENCE_ASSET_SYMBOL = "USD"; + +/// @dev The default URL for redeeming receipts. +string constant DEFAULT_REDEEM_URL = ""; + +/// @dev The default brand name for the receipt. +string constant DEFAULT_BRAND_NAME = ""; + +/// @dev The default SVG URI for the receipt. +string constant DEFAULT_SVG_URI = ""; + +contract ERC20PriceOracleReceipt is Receipt { + /// @inheritdoc Receipt + function uri(uint256 id) public view virtual override returns (string memory) { + if (id == 0) { + revert ZeroReceiptId(); + } + string memory redeemURL = _redeemURL(); + string memory redeemURLPhrase = bytes(redeemURL).length > 0 ? string.concat(" Redeem at ", redeemURL, ".") : ""; + + string memory brandName = _brandName(); + string memory brandNamePhrase = bytes(brandName).length > 0 ? string.concat(brandName, " ") : ""; + + string memory receiptSVGURI = _receiptSVGURI(); + string memory receiptSVGURIPhrase = + bytes(receiptSVGURI).length > 0 ? string.concat("\"image\":\"", receiptSVGURI, "\",") : ""; + + bytes memory json = bytes( + string.concat( + "{\"decimals\":18,\"description\":\"1 of these receipts can be burned alongside 1 ", + _vaultShareSymbol(), + " to redeem ", + LibFixedPointDecimalFormat.fixedPointToDecimalString( + LibFixedPointDecimalArithmeticOpenZeppelin.fixedPointDiv(FIXED_POINT_ONE, id, Math.Rounding.Down) + ), + " of ", + _vaultAssetSymbol(), + ".", + redeemURLPhrase, + "\",", + receiptSVGURIPhrase, + "\"name\":\"Receipt for ", + brandNamePhrase, + "lock at ", + LibFixedPointDecimalFormat.fixedPointToDecimalString(id), + " ", + _referenceAssetSymbol(), + " per ", + _vaultAssetSymbol(), + ".\"}" + ) + ); + + return string.concat(DATA_URI_BASE64_PREFIX, Base64.encode(json)); + } + + /// Provides the SVG URI for the receipt. Can be overridden to provide a + /// custom SVG URI. Default is an empty string, which will not include an + /// image in the metadata json. + function _receiptSVGURI() internal view virtual returns (string memory) { + return DEFAULT_SVG_URI; + } + + /// Provides the symbol of the reference asset that mint amounts are valued + /// in. Can be overridden to provide a custom reference asset symbol. Default + /// is "USD". + function _referenceAssetSymbol() internal view virtual returns (string memory) { + return DEFAULT_REFERENCE_ASSET_SYMBOL; + } + + /// Provides the URL for redeeming receipts. Can be overridden to provide a + /// custom redeem URL. Default is an empty string, which will not include a + /// redeem URL in the metadata json. + function _redeemURL() internal view virtual returns (string memory) { + return DEFAULT_REDEEM_URL; + } + + /// Provides the brand name for the receipt. Can be overridden to provide a + /// custom brand name. Default is an empty string, which will not include a + /// brand name in the metadata json. + function _brandName() internal view virtual returns (string memory) { + return DEFAULT_BRAND_NAME; + } +} diff --git a/src/concrete/receipt/Receipt.sol b/src/concrete/receipt/Receipt.sol index 3cea6d03..c3983cc4 100644 --- a/src/concrete/receipt/Receipt.sol +++ b/src/concrete/receipt/Receipt.sol @@ -6,25 +6,23 @@ import {ICloneableV2, ICLONEABLE_V2_SUCCESS} from "rain.factory/interface/IClone import {IReceiptManagerV1} from "../../interface/IReceiptManagerV1.sol"; import {IReceiptV2} from "../../interface/IReceiptV2.sol"; +import {IReceiptVaultV1} from "../../interface/IReceiptVaultV1.sol"; import {OnlyManager} from "../../error/ErrReceipt.sol"; import {ERC1155Upgradeable as ERC1155} from "openzeppelin-contracts-upgradeable/contracts/token/ERC1155/ERC1155Upgradeable.sol"; import {StringsUpgradeable as Strings} from "openzeppelin-contracts-upgradeable/contracts/utils/StringsUpgradeable.sol"; +import {IERC20MetadataUpgradeable as IERC20Metadata} from + "openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/IERC20MetadataUpgradeable.sol"; +import {Base64Upgradeable as Base64} from "openzeppelin-contracts-upgradeable/contracts/utils/Base64Upgradeable.sol"; /// @dev The prefix for data URIs as base64 encoded JSON. string constant DATA_URI_BASE64_PREFIX = "data:application/json;base64,"; -/// @dev The URI for the metadata of the `Receipt` contract. -/// Decodes to a simple generic receipt metadata object. -/// `{"name":"Receipt","decimals":18,"description":"A receipt for a ReceiptVault."}` -string constant RECEIPT_METADATA_DATA_URI = - "eyJuYW1lIjoiUmVjZWlwdCIsImRlY2ltYWxzIjoxOCwiZGVzY3JpcHRpb24iOiJBIHJlY2VpcHQgZm9yIGEgUmVjZWlwdFZhdWx0LiJ9"; +/// @dev The name of a `Receipt` is " Receipt". +string constant RECEIPT_NAME_SUFFIX = " Receipt"; -/// @dev The symbol for the `Receipt` contract. -string constant RECEIPT_SYMBOL = "RECEIPT"; - -/// @dev The name for the `Receipt` contract. -string constant RECEIPT_NAME = "Receipt"; +/// @dev The symbol of a `Receipt` is " RCPT". +string constant RECEIPT_SYMBOL_SUFFIX = " RCPT"; /// @title Receipt /// @notice The `IReceiptV2` for a `ReceiptVault`. Standard implementation allows @@ -54,7 +52,9 @@ contract Receipt is IReceiptV2, ERC1155, ICloneableV2 { /// implementation in `ReceiptFactory`. /// Compatible with `ICloneableV2`. function initialize(bytes memory data) external override initializer returns (bytes32) { - __ERC1155_init(string.concat(DATA_URI_BASE64_PREFIX, RECEIPT_METADATA_DATA_URI)); + // `uri` is overridden in this contract so we can just initialize + // `ERC1155` with an empty string. + __ERC1155_init(""); address receiptManager = abi.decode(data, (address)); sManager = IReceiptManagerV1(receiptManager); @@ -62,14 +62,46 @@ contract Receipt is IReceiptV2, ERC1155, ICloneableV2 { return ICLONEABLE_V2_SUCCESS; } + /// @inheritdoc ERC1155 + function uri(uint256) public view virtual override returns (string memory) { + bytes memory json = bytes( + string.concat( + "{\"decimals\":18,\"description\":\"1 of these receipts can be burned alongside 1 ", + _vaultShareSymbol(), + " to redeem ", + _vaultAssetSymbol(), + " from the vault.\",", + "\"name\":\"", + name(), + "\"}" + ) + ); + + return string.concat(DATA_URI_BASE64_PREFIX, Base64.encode(json)); + } + /// @inheritdoc IReceiptV2 - function name() external pure virtual returns (string memory) { - return RECEIPT_NAME; + function name() public view virtual returns (string memory) { + return string.concat(_vaultShareSymbol(), RECEIPT_NAME_SUFFIX); } /// @inheritdoc IReceiptV2 - function symbol() external pure virtual returns (string memory) { - return RECEIPT_SYMBOL; + function symbol() external view virtual returns (string memory) { + return string.concat(_vaultShareSymbol(), RECEIPT_SYMBOL_SUFFIX); + } + + /// Provides the symbol of the `ReceiptVault` ERC20 share token that manages + /// this `Receipt`. Can be overridden if the manager is not going to be + /// a `ReceiptVault`. + function _vaultShareSymbol() internal view virtual returns (string memory) { + return IERC20Metadata(payable(address(sManager))).symbol(); + } + + /// Provides the symbol of the ERC20 asset token that the `ReceiptVault` + /// managing this `Receipt` is accepting for mints. Can be overridden if the + /// manager is not going to be a `ReceiptVault`. + function _vaultAssetSymbol() internal view virtual returns (string memory) { + return IERC20Metadata(IReceiptVaultV1(payable(address(sManager))).asset()).symbol(); } /// @inheritdoc IReceiptV2 diff --git a/src/error/ErrReceipt.sol b/src/error/ErrReceipt.sol index d357be7c..fa697fd6 100644 --- a/src/error/ErrReceipt.sol +++ b/src/error/ErrReceipt.sol @@ -4,3 +4,6 @@ pragma solidity ^0.8.25; /// Thrown when the manager is not the caller. error OnlyManager(); + +/// Thrown when the receipt ID is zero. +error ZeroReceiptId(); diff --git a/test/abstract/ReceiptFactoryTest.sol b/test/abstract/ReceiptFactoryTest.sol index 11c7016d..4859a366 100644 --- a/test/abstract/ReceiptFactoryTest.sol +++ b/test/abstract/ReceiptFactoryTest.sol @@ -6,24 +6,67 @@ import {ICloneableFactoryV2} from "rain.factory/interface/ICloneableFactoryV2.so import {CloneFactory} from "rain.factory/concrete/CloneFactory.sol"; import {Test, Vm} from "forge-std/Test.sol"; import {Receipt as ReceiptContract} from "src/concrete/receipt/Receipt.sol"; +import {ERC20PriceOracleReceipt} from "src/concrete/receipt/ERC20PriceOracleReceipt.sol"; +import {DATA_URI_BASE64_PREFIX} from "src/concrete/receipt/Receipt.sol"; +import {Base64} from "solady/utils/Base64.sol"; contract ReceiptFactoryTest is Test { + struct Metadata { + uint8 decimals; + string description; + string name; + } + + struct MetadataWithImage { + uint8 decimals; + string description; + string image; + string name; + } + ICloneableFactoryV2 internal immutable iFactory; - ReceiptContract internal immutable receiptImplementation; + ReceiptContract internal immutable iReceiptImplementation; + ERC20PriceOracleReceipt internal immutable iERC20PriceOracleReceiptImplementation; constructor() { iFactory = new CloneFactory(); - receiptImplementation = new ReceiptContract(); + iReceiptImplementation = new ReceiptContract(); + iERC20PriceOracleReceiptImplementation = new ERC20PriceOracleReceipt(); + } + + function decodeMetadataURI(string memory uri) internal pure returns (Metadata memory) { + uint256 uriLength = bytes(uri).length; + assembly ("memory-safe") { + mstore(uri, 29) + } + assertEq(uri, DATA_URI_BASE64_PREFIX); + assembly ("memory-safe") { + uri := add(uri, 29) + mstore(uri, sub(uriLength, 29)) + } + + string memory uriDecoded = string(Base64.decode(uri)); + bytes memory uriJsonData = vm.parseJson(uriDecoded); + + Metadata memory metadataJson = abi.decode(uriJsonData, (Metadata)); + return metadataJson; } - /// Creates a new `ReceiptContract` clone with the specified manager. - /// @param manager The address to set as the manager of the new ReceiptContract - /// @return The address of the newly created `ReceiptContract` clone - function createReceipt(address manager) internal returns (ReceiptContract) { - // Clone ReceiptContract using the factory and initialize it with the - // manager. - address clone = iFactory.clone(address(receiptImplementation), abi.encode(manager)); - // Return the clone cast to ReceiptContract type - return ReceiptContract(clone); + function decodeMetadataURIWithImage(string memory uri) internal pure returns (MetadataWithImage memory) { + uint256 uriLength = bytes(uri).length; + assembly ("memory-safe") { + mstore(uri, 29) + } + assertEq(uri, DATA_URI_BASE64_PREFIX); + assembly ("memory-safe") { + uri := add(uri, 29) + mstore(uri, sub(uriLength, 29)) + } + + string memory uriDecoded = string(Base64.decode(uri)); + bytes memory uriJsonData = vm.parseJson(uriDecoded); + + MetadataWithImage memory metadataJson = abi.decode(uriJsonData, (MetadataWithImage)); + return metadataJson; } } diff --git a/test/concrete/TestReceiptManager.sol b/test/concrete/TestReceiptManager.sol index fef377e7..adf6ce66 100644 --- a/test/concrete/TestReceiptManager.sol +++ b/test/concrete/TestReceiptManager.sol @@ -10,16 +10,33 @@ import {IReceiptManagerV1} from "src/interface/IReceiptManagerV1.sol"; /// @param to The transfer attemped to this address. error UnauthorizedTransfer(address from, address to); +contract TestReceiptManagerAsset { + function symbol() external pure returns (string memory) { + return "TRMAsset"; + } + + function name() external pure returns (string memory) { + return "TestReceiptManagerAsset"; + } +} + /// @title TestReceiptManager /// @notice TEST contract that can be the manager of an `IReceiptV2` and forward /// function calls to the manager restricted functions on the receipt. Completely /// insecure, intended for use only by the test harness to drive tests. contract TestReceiptManager is IReceiptManagerV1 { + /// The address of the test asset. + address internal iAsset; + /// The address that is authorized to send transfers. address internal sFrom; /// The address that is authorized to receive transfers. address internal sTo; + constructor() { + iAsset = address(new TestReceiptManagerAsset()); + } + /// Anon can set the from address. /// @param from The new `from` address. function setFrom(address from) external { @@ -86,4 +103,16 @@ contract TestReceiptManager is IReceiptManagerV1 { ) external { receipt.managerTransferFrom(from, to, id, amount, data); } + + function name() external pure returns (string memory) { + return "TestReceiptManager"; + } + + function symbol() external pure returns (string memory) { + return "TRM"; + } + + function asset() external view returns (address) { + return iAsset; + } } diff --git a/test/src/concrete/receipt/ERC20PriceOracleReceipt.metadata.t.sol b/test/src/concrete/receipt/ERC20PriceOracleReceipt.metadata.t.sol new file mode 100644 index 00000000..81b6e28c --- /dev/null +++ b/test/src/concrete/receipt/ERC20PriceOracleReceipt.metadata.t.sol @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: LicenseRef-DCL-1.0 +// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd +pragma solidity =0.8.25; + +import {ReceiptFactoryTest} from "test/abstract/ReceiptFactoryTest.sol"; +import {TestReceiptManager} from "test/concrete/TestReceiptManager.sol"; +import {ERC20PriceOracleReceipt} from "src/concrete/receipt/ERC20PriceOracleReceipt.sol"; +import {LibFixedPointDecimalFormat} from "rain.math.fixedpoint/lib/format/LibFixedPointDecimalFormat.sol"; +import { + LibFixedPointDecimalArithmeticOpenZeppelin, + Math +} from "rain.math.fixedpoint/lib/LibFixedPointDecimalArithmeticOpenZeppelin.sol"; +import {FIXED_POINT_ONE} from "rain.math.fixedpoint/lib/FixedPointDecimalConstants.sol"; +import {ZeroReceiptId} from "src/error/ErrReceipt.sol"; +import {LibConformString} from "rain.string/lib/mut/LibConformString.sol"; +import {CMASK_QUOTATION_MARK, CMASK_PRINTABLE, CMASK_BACKSLASH} from "rain.string/lib/parse/LibParseCMask.sol"; + +/// This contract is used to test the metadata of the `Receipt` contract. +/// As all the overridden functions are internal, we need to create a new +/// contract that inherits from `Receipt` and exposes these functions; we can't +/// just mock `Receipt`. +contract MutableMetadataReceipt is ERC20PriceOracleReceipt { + string internal sVaultShareSymbol; + string internal sVaultAssetSymbol; + string internal sReceiptSVGURI; + string internal sReferenceAssetSymbol; + string internal sRedeemURL; + string internal sBrandName; + + function setVaultShareSymbol(string memory vaultShareSymbol) external { + sVaultShareSymbol = vaultShareSymbol; + } + + function setVaultAssetSymbol(string memory vaultAssetSymbol) external { + sVaultAssetSymbol = vaultAssetSymbol; + } + + function setReceiptSVGURI(string memory receiptSVGURI) external { + sReceiptSVGURI = receiptSVGURI; + } + + function setReferenceAssetSymbol(string memory referenceAssetSymbol) external { + sReferenceAssetSymbol = referenceAssetSymbol; + } + + function setRedeemURL(string memory redeemURL) external { + sRedeemURL = redeemURL; + } + + function setBrandName(string memory brandName) external { + sBrandName = brandName; + } + + function _vaultShareSymbol() internal view override returns (string memory) { + return sVaultShareSymbol; + } + + function _vaultAssetSymbol() internal view override returns (string memory) { + return sVaultAssetSymbol; + } + + function _receiptSVGURI() internal view override returns (string memory) { + return sReceiptSVGURI; + } + + function _referenceAssetSymbol() internal view override returns (string memory) { + return sReferenceAssetSymbol; + } + + function _redeemURL() internal view override returns (string memory) { + return sRedeemURL; + } + + function _brandName() internal view override returns (string memory) { + return sBrandName; + } +} + +contract ERC20PriceOracleReceiptMetadataTest is ReceiptFactoryTest { + function testReceiptURIZeroError() external { + // Deploy the Receipt contract + TestReceiptManager testManager = new TestReceiptManager(); + ERC20PriceOracleReceipt receipt = ERC20PriceOracleReceipt( + iFactory.clone(address(iERC20PriceOracleReceiptImplementation), abi.encode(address(testManager))) + ); + + vm.expectRevert(ZeroReceiptId.selector); + receipt.uri(0); + } + + function testReceiptURI(uint256 id) external { + vm.assume(id != 0); + + // Deploy the Receipt contract + TestReceiptManager testManager = new TestReceiptManager(); + ERC20PriceOracleReceipt receipt = ERC20PriceOracleReceipt( + iFactory.clone(address(iERC20PriceOracleReceiptImplementation), abi.encode(address(testManager))) + ); + + string memory uri = receipt.uri(id); + + Metadata memory metadataJson = decodeMetadataURI(uri); + + string memory idInvFormatted = LibFixedPointDecimalFormat.fixedPointToDecimalString( + LibFixedPointDecimalArithmeticOpenZeppelin.fixedPointDiv(FIXED_POINT_ONE, id, Math.Rounding.Down) + ); + assertEq( + metadataJson.description, + string.concat( + "1 of these receipts can be burned alongside 1 TRM to redeem ", idInvFormatted, " of TRMAsset." + ) + ); + + assertEq(metadataJson.decimals, 18); + assertEq( + metadataJson.name, + string.concat( + "Receipt for lock at ", LibFixedPointDecimalFormat.fixedPointToDecimalString(id), " USD per TRMAsset." + ) + ); + } + + function testReceiptName() external { + // Deploy the Receipt contract + TestReceiptManager testManager = new TestReceiptManager(); + ERC20PriceOracleReceipt receipt = ERC20PriceOracleReceipt( + iFactory.clone(address(iERC20PriceOracleReceiptImplementation), abi.encode(address(testManager))) + ); + + assertEq(receipt.name(), "TRM Receipt"); + } + + function testReceiptSymbol() external { + // Deploy the Receipt contract + TestReceiptManager testManager = new TestReceiptManager(); + ERC20PriceOracleReceipt receipt = ERC20PriceOracleReceipt( + iFactory.clone(address(iERC20PriceOracleReceiptImplementation), abi.encode(address(testManager))) + ); + + assertEq(receipt.symbol(), "TRM RCPT"); + } + + function testOverriddenMetadata( + uint256 id, + string memory vaultShareSymbol, + string memory vaultAssetSymbol, + string memory redeemURL, + string memory brandName, + string memory referenceAssetSymbol + ) external { + vm.assume(id != 0); + MutableMetadataReceipt receipt = new MutableMetadataReceipt(); + + { + uint256 mask = CMASK_PRINTABLE & ~(CMASK_QUOTATION_MARK | CMASK_BACKSLASH); + + LibConformString.conformStringToMask(vaultShareSymbol, mask, 0x100); + LibConformString.conformStringToMask(vaultAssetSymbol, mask, 0x100); + LibConformString.conformStringToMask(redeemURL, mask, 0x100); + LibConformString.conformStringToMask(brandName, mask, 0x100); + LibConformString.conformStringToMask(referenceAssetSymbol, mask, 0x100); + + receipt.setVaultShareSymbol(vaultShareSymbol); + receipt.setVaultAssetSymbol(vaultAssetSymbol); + receipt.setRedeemURL(redeemURL); + receipt.setBrandName(brandName); + receipt.setReferenceAssetSymbol(referenceAssetSymbol); + } + + string memory uri = receipt.uri(id); + Metadata memory metadata = decodeMetadataURI(uri); + + string memory idInvFormatted = LibFixedPointDecimalFormat.fixedPointToDecimalString( + LibFixedPointDecimalArithmeticOpenZeppelin.fixedPointDiv(FIXED_POINT_ONE, id, Math.Rounding.Down) + ); + + string memory redeemURLPhrase = bytes(redeemURL).length > 0 ? string.concat(" Redeem at ", redeemURL, ".") : ""; + string memory brandNamePhrase = bytes(brandName).length > 0 ? string.concat(brandName, " ") : ""; + + assertEq(metadata.decimals, 18); + assertEq( + metadata.description, + string.concat( + "1 of these receipts can be burned alongside 1 ", + vaultShareSymbol, + " to redeem ", + idInvFormatted, + " of ", + vaultAssetSymbol, + ".", + redeemURLPhrase + ) + ); + assertEq( + metadata.name, + string.concat( + "Receipt for ", + brandNamePhrase, + "lock at ", + LibFixedPointDecimalFormat.fixedPointToDecimalString(id), + " ", + referenceAssetSymbol, + " per ", + vaultAssetSymbol, + "." + ) + ); + } + + function testOverriddenMetadataWithImage( + uint256 id, + string memory vaultShareSymbol, + string memory vaultAssetSymbol, + string memory redeemURL, + string memory brandName, + string memory referenceAssetSymbol, + string memory receiptSVGURI + ) external { + vm.assume(bytes(receiptSVGURI).length > 0); + vm.assume(id != 0); + MutableMetadataReceipt receipt = new MutableMetadataReceipt(); + + { + uint256 mask = CMASK_PRINTABLE & ~(CMASK_QUOTATION_MARK | CMASK_BACKSLASH); + + LibConformString.conformStringToMask(vaultShareSymbol, mask, 0x100); + LibConformString.conformStringToMask(vaultAssetSymbol, mask, 0x100); + LibConformString.conformStringToMask(redeemURL, mask, 0x100); + LibConformString.conformStringToMask(brandName, mask, 0x100); + LibConformString.conformStringToMask(referenceAssetSymbol, mask, 0x100); + LibConformString.conformStringToMask(receiptSVGURI, mask, 0x100); + + receipt.setVaultShareSymbol(vaultShareSymbol); + receipt.setVaultAssetSymbol(vaultAssetSymbol); + receipt.setRedeemURL(redeemURL); + receipt.setBrandName(brandName); + receipt.setReferenceAssetSymbol(referenceAssetSymbol); + receipt.setReceiptSVGURI(receiptSVGURI); + } + + string memory uri = receipt.uri(id); + MetadataWithImage memory metadata = decodeMetadataURIWithImage(uri); + + string memory idInvFormatted = LibFixedPointDecimalFormat.fixedPointToDecimalString( + LibFixedPointDecimalArithmeticOpenZeppelin.fixedPointDiv(FIXED_POINT_ONE, id, Math.Rounding.Down) + ); + + assertEq(metadata.decimals, 18); + + { + string memory redeemURLPhrase = + bytes(redeemURL).length > 0 ? string.concat(" Redeem at ", redeemURL, ".") : ""; + assertEq( + metadata.description, + string.concat( + "1 of these receipts can be burned alongside 1 ", + vaultShareSymbol, + " to redeem ", + idInvFormatted, + " of ", + vaultAssetSymbol, + ".", + redeemURLPhrase + ) + ); + } + + { + string memory brandNamePhrase = bytes(brandName).length > 0 ? string.concat(brandName, " ") : ""; + assertEq( + metadata.name, + string.concat( + "Receipt for ", + brandNamePhrase, + "lock at ", + LibFixedPointDecimalFormat.fixedPointToDecimalString(id), + " ", + referenceAssetSymbol, + " per ", + vaultAssetSymbol, + "." + ) + ); + } + + assertEq(metadata.image, receiptSVGURI); + } +} diff --git a/test/src/concrete/receipt/Receipt.metadata.t.sol b/test/src/concrete/receipt/Receipt.metadata.t.sol index c9636da0..2360714e 100644 --- a/test/src/concrete/receipt/Receipt.metadata.t.sol +++ b/test/src/concrete/receipt/Receipt.metadata.t.sol @@ -5,62 +5,41 @@ pragma solidity =0.8.25; import {ReceiptFactoryTest} from "test/abstract/ReceiptFactoryTest.sol"; import {TestReceiptManager} from "test/concrete/TestReceiptManager.sol"; import {Receipt as ReceiptContract} from "src/concrete/receipt/Receipt.sol"; -import {Base64} from "solady/utils/Base64.sol"; -import { - Receipt, - RECEIPT_METADATA_DATA_URI, - DATA_URI_BASE64_PREFIX, - RECEIPT_NAME, - RECEIPT_SYMBOL -} from "src/concrete/receipt/Receipt.sol"; contract ReceiptMetadataTest is ReceiptFactoryTest { - struct Metadata { - uint8 decimals; - string description; - string name; - } - function testReceiptURI(uint256 id) external { // Deploy the Receipt contract TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); string memory uri = receipt.uri(id); - uint256 uriLength = bytes(uri).length; - assembly ("memory-safe") { - mstore(uri, 29) - } - assertEq(uri, DATA_URI_BASE64_PREFIX); - assembly ("memory-safe") { - uri := add(uri, 29) - mstore(uri, sub(uriLength, 29)) - } - assertEq(uri, RECEIPT_METADATA_DATA_URI); - - string memory uriDecoded = string(Base64.decode(uri)); - bytes memory uriJsonData = vm.parseJson(uriDecoded); + Metadata memory metadataJson = decodeMetadataURI(uri); - Metadata memory metadataJson = abi.decode(uriJsonData, (Metadata)); - assertEq(metadataJson.description, "A receipt for a ReceiptVault."); + assertEq( + metadataJson.description, + "1 of these receipts can be burned alongside 1 TRM to redeem TRMAsset from the vault." + ); assertEq(metadataJson.decimals, 18); - assertEq(metadataJson.name, RECEIPT_NAME); + assertEq(metadataJson.name, "TRM Receipt"); } function testReceiptName() external { // Deploy the Receipt contract TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); - assertEq(receipt.name(), RECEIPT_NAME); + assertEq(receipt.name(), "TRM Receipt"); } function testReceiptSymbol() external { // Deploy the Receipt contract TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); - assertEq(receipt.symbol(), RECEIPT_SYMBOL); + assertEq(receipt.symbol(), "TRM RCPT"); } } diff --git a/test/src/concrete/receipt/Receipt.t.sol b/test/src/concrete/receipt/Receipt.t.sol index b809adb4..aa0c75dc 100644 --- a/test/src/concrete/receipt/Receipt.t.sol +++ b/test/src/concrete/receipt/Receipt.t.sol @@ -14,7 +14,8 @@ contract ReceiptTest is ReceiptFactoryTest { function testInitialize() public { TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); assertEq(receipt.manager(), address(testManager)); } @@ -27,7 +28,8 @@ contract ReceiptTest is ReceiptFactoryTest { amount = bound(amount, 1, type(uint256).max); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -42,7 +44,8 @@ contract ReceiptTest is ReceiptFactoryTest { amount = bound(amount, 1, type(uint256).max); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -65,7 +68,8 @@ contract ReceiptTest is ReceiptFactoryTest { amount = bound(amount, 1, type(uint256).max); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -85,7 +89,8 @@ contract ReceiptTest is ReceiptFactoryTest { vm.assume(fuzzedReceiptInformation.length > 0); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -124,7 +129,8 @@ contract ReceiptTest is ReceiptFactoryTest { id = bound(id, 0, type(uint256).max); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -161,7 +167,8 @@ contract ReceiptTest is ReceiptFactoryTest { id = bound(id, 0, type(uint256).max); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -196,7 +203,8 @@ contract ReceiptTest is ReceiptFactoryTest { id = bound(id, 0, type(uint256).max); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -227,7 +235,8 @@ contract ReceiptTest is ReceiptFactoryTest { address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -252,7 +261,8 @@ contract ReceiptTest is ReceiptFactoryTest { id = bound(id, 0, type(uint256).max); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -281,7 +291,8 @@ contract ReceiptTest is ReceiptFactoryTest { amount = bound(amount, 1, type(uint256).max); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -317,7 +328,8 @@ contract ReceiptTest is ReceiptFactoryTest { vm.assume(amountOne != amountTwo); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -352,7 +364,8 @@ contract ReceiptTest is ReceiptFactoryTest { address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); vm.assume(alice != bob); - ReceiptContract receipt = createReceipt(alice); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(alice)))); vm.startPrank(alice); // Alice approves operator @@ -376,7 +389,8 @@ contract ReceiptTest is ReceiptFactoryTest { amount = bound(amount, 1, type(uint256).max); TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice); @@ -435,7 +449,8 @@ contract ReceiptTest is ReceiptFactoryTest { tokenIds[1] = tokenId2; // Create a new receipt TestReceiptManager testManager = new TestReceiptManager(); - ReceiptContract receipt = createReceipt(address(testManager)); + ReceiptContract receipt = + ReceiptContract(iFactory.clone(address(iReceiptImplementation), abi.encode(address(testManager)))); vm.startPrank(alice);