diff --git a/.gas-snapshot b/.gas-snapshot index 80ae19bb..62a38513 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,218 +1,218 @@ -AuthTest:testCallFunctionAsOwner() (gas: 29871) -AuthTest:testCallFunctionWithPermissiveAuthority() (gas: 124249) -AuthTest:testFailCallFunctionAsNonOwner() (gas: 15491) -AuthTest:testFailCallFunctionAsOwnerWithOutOfOrderAuthority() (gas: 136021) -AuthTest:testFailCallFunctionWithRestrictiveAuthority() (gas: 129201) -AuthTest:testFailSetAuthorityAsNonOwner() (gas: 18260) -AuthTest:testFailSetAuthorityWithRestrictiveAuthority() (gas: 129078) -AuthTest:testFailSetOwnerAsNonOwner() (gas: 15609) -AuthTest:testFailSetOwnerAsOwnerWithOutOfOrderAuthority() (gas: 136161) -AuthTest:testFailSetOwnerWithRestrictiveAuthority() (gas: 129242) -AuthTest:testSetAuthorityAsOwner() (gas: 32302) -AuthTest:testSetAuthorityAsOwnerWithOutOfOrderAuthority() (gas: 226396) -AuthTest:testSetAuthorityWithPermissiveAuthority() (gas: 125963) -AuthTest:testSetOwnerAsOwner() (gas: 15298) -AuthTest:testSetOwnerWithPermissiveAuthority() (gas: 127884) -Bytes32AddressLibTest:testFillLast12Bytes() (gas: 223) -Bytes32AddressLibTest:testFromLast20Bytes() (gas: 191) -CREATE3Test:testDeployERC20() (gas: 852410) -CREATE3Test:testFailDoubleDeployDifferentBytecode() (gas: 9079256848778914164) -CREATE3Test:testFailDoubleDeploySameBytecode() (gas: 9079256848778906218) -DSTestPlusTest:testBound() (gas: 16777) -DSTestPlusTest:testFailBoundMinBiggerThanMax() (gas: 309) -DSTestPlusTest:testRelApproxEqBothZeroesPasses() (gas: 413) -ERC1155Test:testApproveAll() (gas: 31009) -ERC1155Test:testBatchBalanceOf() (gas: 157631) -ERC1155Test:testBatchBurn() (gas: 151074) -ERC1155Test:testBatchMintToEOA() (gas: 137337) -ERC1155Test:testBatchMintToERC1155Recipient() (gas: 942650) -ERC1155Test:testBurn() (gas: 38598) -ERC1155Test:testFailBalanceOfBatchWithArrayMismatch() (gas: 7933) -ERC1155Test:testFailBatchBurnInsufficientBalance() (gas: 136156) -ERC1155Test:testFailBatchBurnWithArrayLengthMismatch() (gas: 135542) -ERC1155Test:testFailBatchMintToNonERC1155Recipient() (gas: 167292) -ERC1155Test:testFailBatchMintToRevertingERC1155Recipient() (gas: 358811) -ERC1155Test:testFailBatchMintToWrongReturnDataERC1155Recipient() (gas: 310743) -ERC1155Test:testFailBatchMintToZero() (gas: 131737) -ERC1155Test:testFailBatchMintWithArrayMismatch() (gas: 9600) -ERC1155Test:testFailBurnInsufficientBalance() (gas: 34852) -ERC1155Test:testFailMintToNonERC155Recipient() (gas: 68191) -ERC1155Test:testFailMintToRevertingERC155Recipient() (gas: 259435) -ERC1155Test:testFailMintToWrongReturnDataERC155Recipient() (gas: 259389) -ERC1155Test:testFailMintToZero() (gas: 33705) -ERC1155Test:testFailSafeBatchTransferFromToNonERC1155Recipient() (gas: 321377) +AuthTest:testCallFunctionAsNonOwner() (gas: 13588) +AuthTest:testCallFunctionAsOwner() (gas: 29849) +AuthTest:testCallFunctionAsOwnerWithOutOfOrderAuthority() (gas: 138899) +AuthTest:testCallFunctionWithPermissiveAuthority() (gas: 124293) +AuthTest:testCallFunctionWithRestrictiveAuthority() (gas: 127226) +AuthTest:testSetAuthorityAsNonOwner() (gas: 16296) +AuthTest:testSetAuthorityAsOwner() (gas: 32258) +AuthTest:testSetAuthorityAsOwnerWithOutOfOrderAuthority() (gas: 226441) +AuthTest:testSetAuthorityWithPermissiveAuthority() (gas: 125941) +AuthTest:testSetAuthorityWithRestrictiveAuthority() (gas: 127272) +AuthTest:testSetOwnerAsNonOwner() (gas: 13627) +AuthTest:testSetOwnerAsOwner() (gas: 15343) +AuthTest:testSetOwnerAsOwnerWithOutOfOrderAuthority() (gas: 139018) +AuthTest:testSetOwnerWithPermissiveAuthority() (gas: 127885) +AuthTest:testSetOwnerWithRestrictiveAuthority() (gas: 127353) +Bytes32AddressLibTest:testFillLast12Bytes() (gas: 245) +Bytes32AddressLibTest:testFromLast20Bytes() (gas: 259) +CREATE3Test:testDeployERC20() (gas: 852592) +CREATE3Test:testDoubleDeployDifferentBytecode() (gas: 9079256848778914267) +CREATE3Test:testDoubleDeploySameBytecode() (gas: 9079256848778906616) +ERC1155Test:testApproveAll() (gas: 31008) +ERC1155Test:testBalanceOfBatchWithArrayMismatch() (gas: 11373) +ERC1155Test:testBatchBalanceOf() (gas: 157587) +ERC1155Test:testBatchBurn() (gas: 151051) +ERC1155Test:testBatchBurnInsufficientBalance() (gas: 139531) +ERC1155Test:testBatchBurnWithArrayLengthMismatch() (gas: 138487) +ERC1155Test:testBatchMintToEOA() (gas: 137315) +ERC1155Test:testBatchMintToERC1155Recipient() (gas: 942672) +ERC1155Test:testBatchMintToNonERC1155Recipient() (gas: 170122) +ERC1155Test:testBatchMintToWrongReturnDataERC1155Recipient() (gas: 313627) +ERC1155Test:testBatchMintToZero() (gas: 134596) +ERC1155Test:testBatchMintWithArrayMismatch() (gas: 12519) +ERC1155Test:testBurn() (gas: 38599) +ERC1155Test:testBurnInsufficientBalance() (gas: 38159) +ERC1155Test:testFailBatchMintToRevertingERC1155Recipient() (gas: 358832) +ERC1155Test:testFailMintToRevertingERC155Recipient() (gas: 259415) +ERC1155Test:testFailMintToWrongReturnDataERC155Recipient() (gas: 259413) ERC1155Test:testFailSafeBatchTransferFromToRevertingERC1155Recipient() (gas: 512956) -ERC1155Test:testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() (gas: 464847) -ERC1155Test:testFailSafeBatchTransferFromToZero() (gas: 286556) -ERC1155Test:testFailSafeBatchTransferFromWithArrayLengthMismatch() (gas: 162674) -ERC1155Test:testFailSafeBatchTransferInsufficientBalance() (gas: 163555) -ERC1155Test:testFailSafeTransferFromInsufficientBalance() (gas: 63245) -ERC1155Test:testFailSafeTransferFromSelfInsufficientBalance() (gas: 34297) -ERC1155Test:testFailSafeTransferFromToNonERC155Recipient() (gas: 96510) -ERC1155Test:testFailSafeTransferFromToRevertingERC1155Recipient() (gas: 287731) -ERC1155Test:testFailSafeTransferFromToWrongReturnDataERC1155Recipient() (gas: 239587) -ERC1155Test:testFailSafeTransferFromToZero() (gas: 62014) -ERC1155Test:testMintToEOA() (gas: 34765) -ERC1155Test:testMintToERC1155Recipient() (gas: 608328) -ERC1155Test:testSafeBatchTransferFromToEOA() (gas: 297822) -ERC1155Test:testSafeBatchTransferFromToERC1155Recipient() (gas: 1122274) -ERC1155Test:testSafeTransferFromSelf() (gas: 64177) -ERC1155Test:testSafeTransferFromToEOA() (gas: 93167) -ERC1155Test:testSafeTransferFromToERC1155Recipient() (gas: 686500) -ERC20Test:testApprove() (gas: 31058) -ERC20Test:testBurn() (gas: 56970) -ERC20Test:testFailPermitBadDeadline() (gas: 36924) -ERC20Test:testFailPermitBadNonce() (gas: 36874) -ERC20Test:testFailPermitPastDeadline() (gas: 8589) -ERC20Test:testFailPermitReplay() (gas: 66285) -ERC20Test:testFailTransferFromInsufficientAllowance() (gas: 80882) -ERC20Test:testFailTransferFromInsufficientBalance() (gas: 81358) -ERC20Test:testFailTransferInsufficientBalance() (gas: 52806) -ERC20Test:testInfiniteApproveTransferFrom() (gas: 89793) -ERC20Test:testMint() (gas: 53746) -ERC20Test:testPermit() (gas: 63193) -ERC20Test:testTransfer() (gas: 60272) -ERC20Test:testTransferFrom() (gas: 83777) -ERC4626Test:testFailDepositWithNoApproval() (gas: 13351) -ERC4626Test:testFailDepositWithNotEnoughApproval() (gas: 86987) -ERC4626Test:testFailDepositZero() (gas: 7774) -ERC4626Test:testFailMintWithNoApproval() (gas: 13296) -ERC4626Test:testFailRedeemWithNoShareAmount() (gas: 32339) -ERC4626Test:testFailRedeemWithNotEnoughShareAmount() (gas: 203632) -ERC4626Test:testFailRedeemZero() (gas: 7961) -ERC4626Test:testFailWithdrawWithNoUnderlyingAmount() (gas: 32292) -ERC4626Test:testFailWithdrawWithNotEnoughUnderlyingAmount() (gas: 203615) -ERC4626Test:testMintZero() (gas: 54598) -ERC4626Test:testMultipleMintDepositRedeemWithdraw() (gas: 411940) -ERC4626Test:testVaultInteractionsForSomeoneElse() (gas: 286247) -ERC4626Test:testWithdrawZero() (gas: 52465) -ERC721Test:testApprove() (gas: 78427) -ERC721Test:testApproveAll() (gas: 31063) -ERC721Test:testApproveBurn() (gas: 65550) -ERC721Test:testBurn() (gas: 46107) -ERC721Test:testFailApproveUnAuthorized() (gas: 55598) -ERC721Test:testFailApproveUnMinted() (gas: 10236) -ERC721Test:testFailBalanceOfZeroAddress() (gas: 5555) -ERC721Test:testFailBurnUnMinted() (gas: 7857) -ERC721Test:testFailDoubleBurn() (gas: 58943) -ERC721Test:testFailDoubleMint() (gas: 53286) -ERC721Test:testFailMintToZero() (gas: 5753) -ERC721Test:testFailOwnerOfUnminted() (gas: 7609) -ERC721Test:testFailSafeMintToERC721RecipientWithWrongReturnData() (gas: 159076) -ERC721Test:testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() (gas: 159831) -ERC721Test:testFailSafeMintToNonERC721Recipient() (gas: 89210) -ERC721Test:testFailSafeMintToNonERC721RecipientWithData() (gas: 89995) -ERC721Test:testFailSafeMintToRevertingERC721Recipient() (gas: 204743) -ERC721Test:testFailSafeMintToRevertingERC721RecipientWithData() (gas: 205517) -ERC721Test:testFailSafeTransferFromToERC721RecipientWithWrongReturnData() (gas: 187276) -ERC721Test:testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() (gas: 187728) -ERC721Test:testFailSafeTransferFromToNonERC721Recipient() (gas: 117413) -ERC721Test:testFailSafeTransferFromToNonERC721RecipientWithData() (gas: 117872) -ERC721Test:testFailSafeTransferFromToRevertingERC721Recipient() (gas: 233009) -ERC721Test:testFailSafeTransferFromToRevertingERC721RecipientWithData() (gas: 233396) -ERC721Test:testFailTransferFromNotOwner() (gas: 57872) -ERC721Test:testFailTransferFromToZero() (gas: 53381) -ERC721Test:testFailTransferFromUnOwned() (gas: 8000) -ERC721Test:testFailTransferFromWrongFrom() (gas: 53361) -ERC721Test:testMint() (gas: 54336) -ERC721Test:testSafeMintToEOA() (gas: 56993) -ERC721Test:testSafeMintToERC721Recipient() (gas: 381737) -ERC721Test:testSafeMintToERC721RecipientWithData() (gas: 402881) -ERC721Test:testSafeTransferFromToEOA() (gas: 95666) -ERC721Test:testSafeTransferFromToERC721Recipient() (gas: 440251) -ERC721Test:testSafeTransferFromToERC721RecipientWithData() (gas: 461049) +ERC1155Test:testFailSafeTransferFromToRevertingERC1155Recipient() (gas: 287687) +ERC1155Test:testMintToEOA() (gas: 34721) +ERC1155Test:testMintToERC1155Recipient() (gas: 608371) +ERC1155Test:testMintToNonERC155Recipient() (gas: 71080) +ERC1155Test:testMintToZero() (gas: 36586) +ERC1155Test:testSafeBatchTransferFromToEOA() (gas: 297800) +ERC1155Test:testSafeBatchTransferFromToERC1155Recipient() (gas: 1122296) +ERC1155Test:testSafeBatchTransferFromToNonERC1155Recipient() (gas: 321758) +ERC1155Test:testSafeBatchTransferFromToWrongReturnDataERC1155Recipient() (gas: 465236) +ERC1155Test:testSafeBatchTransferFromToZero() (gas: 286877) +ERC1155Test:testSafeBatchTransferFromWithArrayLengthMismatch() (gas: 163116) +ERC1155Test:testSafeBatchTransferInsufficientBalance() (gas: 164351) +ERC1155Test:testSafeTransferFromInsufficientBalance() (gas: 64092) +ERC1155Test:testSafeTransferFromSelf() (gas: 64133) +ERC1155Test:testSafeTransferFromSelfInsufficientBalance() (gas: 37621) +ERC1155Test:testSafeTransferFromToEOA() (gas: 93123) +ERC1155Test:testSafeTransferFromToERC1155Recipient() (gas: 686501) +ERC1155Test:testSafeTransferFromToNonERC155Recipient() (gas: 99323) +ERC1155Test:testSafeTransferFromToWrongReturnDataERC1155Recipient() (gas: 242471) +ERC1155Test:testSafeTransferFromToZero() (gas: 64891) +ERC20Test:testApprove() (gas: 35815) +ERC20Test:testBurn() (gas: 61723) +ERC20Test:testInfiniteApproveTransferFrom() (gas: 94268) +ERC20Test:testMint() (gas: 58500) +ERC20Test:testPermit() (gas: 65396) +ERC20Test:testPermitBadDeadline() (gas: 37308) +ERC20Test:testPermitBadNonce() (gas: 37204) +ERC20Test:testPermitPastDeadline() (gas: 11582) +ERC20Test:testPermitReplay() (gas: 66674) +ERC20Test:testTransfer() (gas: 64998) +ERC20Test:testTransferFrom() (gas: 85625) +ERC20Test:testTransferFromInsufficientAllowance() (gas: 81888) +ERC20Test:testTransferFromInsufficientBalance() (gas: 62507) +ERC20Test:testTransferInsufficientBalance() (gas: 56363) +ERC4626Test:testBadDepositWithNoApproval() (gas: 16359) +ERC4626Test:testBadDepositWithNotEnoughApproval() (gas: 90004) +ERC4626Test:testBadDepositZero() (gas: 10780) +ERC4626Test:testBadMintWithNoApproval() (gas: 16280) +ERC4626Test:testBadRedeemWithNoShareAmount() (gas: 35852) +ERC4626Test:testBadRedeemWithNotEnoughShareAmount() (gas: 167331) +ERC4626Test:testBadRedeemZero() (gas: 10987) +ERC4626Test:testBadWithdrawWithNoUnderlyingAmount() (gas: 35752) +ERC4626Test:testBadWithdrawWithNotEnoughUnderlyingAmount() (gas: 167250) +ERC4626Test:testMintZero() (gas: 54548) +ERC4626Test:testMultipleMintDepositRedeemWithdraw() (gas: 411196) +ERC4626Test:testVaultInteractionsForSomeoneElse() (gas: 286152) +ERC4626Test:testWithdrawZero() (gas: 52372) +ERC721Test:testApprove() (gas: 78449) +ERC721Test:testApproveAll() (gas: 31085) +ERC721Test:testApproveBurn() (gas: 65575) +ERC721Test:testApproveUnAuthorized() (gas: 58434) +ERC721Test:testApproveUnMinted() (gas: 13045) +ERC721Test:testBalanceOfZeroAddress() (gas: 8525) +ERC721Test:testBurn() (gas: 46096) +ERC721Test:testBurnUnMinted() (gas: 10719) +ERC721Test:testDoubleBurn() (gas: 45257) +ERC721Test:testDoubleMint() (gas: 56187) +ERC721Test:testFailSafeMintToRevertingERC721Recipient() (gas: 204733) +ERC721Test:testFailSafeMintToRevertingERC721RecipientWithData() (gas: 205557) +ERC721Test:testFailSafeTransferFromToRevertingERC721Recipient() (gas: 232968) +ERC721Test:testFailSafeTransferFromToRevertingERC721RecipientWithData() (gas: 233388) +ERC721Test:testMint() (gas: 54361) +ERC721Test:testMintToZero() (gas: 8636) +ERC721Test:testOwnerOfUnminted() (gas: 10685) +ERC721Test:testSafeMintToEOA() (gas: 56992) +ERC721Test:testSafeMintToERC721Recipient() (gas: 381780) +ERC721Test:testSafeMintToERC721RecipientWithData() (gas: 402859) +ERC721Test:testSafeMintToERC721RecipientWithWrongReturnData() (gas: 161906) +ERC721Test:testSafeMintToERC721RecipientWithWrongReturnDataWithData() (gas: 162689) +ERC721Test:testSafeMintToNonERC721Recipient() (gas: 92076) +ERC721Test:testSafeMintToNonERC721RecipientWithData() (gas: 92827) +ERC721Test:testSafeTransferFromToEOA() (gas: 95667) +ERC721Test:testSafeTransferFromToERC721Recipient() (gas: 440273) +ERC721Test:testSafeTransferFromToERC721RecipientWithData() (gas: 461048) +ERC721Test:testSafeTransferFromToERC721RecipientWithWrongReturnData() (gas: 170221) +ERC721Test:testSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() (gas: 170685) +ERC721Test:testSafeTransferFromToNonERC721Recipient() (gas: 100350) +ERC721Test:testSafeTransferFromToNonERC721RecipientWithData() (gas: 100846) ERC721Test:testTransferFrom() (gas: 86347) -ERC721Test:testTransferFromApproveAll() (gas: 92898) -ERC721Test:testTransferFromSelf() (gas: 64776) -FixedPointMathLibTest:testDivWadDown() (gas: 864) -FixedPointMathLibTest:testDivWadDownEdgeCases() (gas: 423) -FixedPointMathLibTest:testDivWadUp() (gas: 981) -FixedPointMathLibTest:testDivWadUpEdgeCases() (gas: 482) -FixedPointMathLibTest:testFailDivWadDownZeroDenominator() (gas: 362) -FixedPointMathLibTest:testFailDivWadUpZeroDenominator() (gas: 342) -FixedPointMathLibTest:testFailMulDivDownZeroDenominator() (gas: 316) -FixedPointMathLibTest:testFailMulDivUpZeroDenominator() (gas: 317) -FixedPointMathLibTest:testMulDivDown() (gas: 1861) -FixedPointMathLibTest:testMulDivDownEdgeCases() (gas: 751) -FixedPointMathLibTest:testMulDivUp() (gas: 2273) -FixedPointMathLibTest:testMulDivUpEdgeCases() (gas: 846) -FixedPointMathLibTest:testMulWadDown() (gas: 821) +ERC721Test:testTransferFromApproveAll() (gas: 92897) +ERC721Test:testTransferFromNotOwner() (gas: 60720) +ERC721Test:testTransferFromSelf() (gas: 64820) +ERC721Test:testTransferFromToZero() (gas: 56236) +ERC721Test:testTransferFromUnOwned() (gas: 10890) +ERC721Test:testTransferFromWrongFrom() (gas: 56251) +FixedPointMathLibTest:testDivWadDown() (gas: 853) +FixedPointMathLibTest:testDivWadDownEdgeCases() (gas: 435) +FixedPointMathLibTest:testDivWadDownZeroDenominator() (gas: 3181) +FixedPointMathLibTest:testDivWadUp() (gas: 949) +FixedPointMathLibTest:testDivWadUpEdgeCases() (gas: 516) +FixedPointMathLibTest:testDivWadUpZeroDenominator() (gas: 3202) +FixedPointMathLibTest:testMulDivDown() (gas: 1883) +FixedPointMathLibTest:testMulDivDownEdgeCases() (gas: 729) +FixedPointMathLibTest:testMulDivDownZeroDenominator() (gas: 3145) +FixedPointMathLibTest:testMulDivUp() (gas: 2250) +FixedPointMathLibTest:testMulDivUpEdgeCases() (gas: 868) +FixedPointMathLibTest:testMulDivUpZeroDenominator() (gas: 3189) +FixedPointMathLibTest:testMulWadDown() (gas: 844) FixedPointMathLibTest:testMulWadDownEdgeCases() (gas: 886) -FixedPointMathLibTest:testMulWadUp() (gas: 959) -FixedPointMathLibTest:testMulWadUpEdgeCases() (gas: 1002) -FixedPointMathLibTest:testRPow() (gas: 2142) -FixedPointMathLibTest:testSqrt() (gas: 2537) -MultiRolesAuthorityTest:testCanCallPublicCapability() (gas: 34292) -MultiRolesAuthorityTest:testCanCallWithAuthorizedRole() (gas: 80556) -MultiRolesAuthorityTest:testCanCallWithCustomAuthority() (gas: 422681) -MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesPublicCapability() (gas: 247674) -MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesUserWithRole() (gas: 256845) -MultiRolesAuthorityTest:testSetPublicCapabilities() (gas: 27762) -MultiRolesAuthorityTest:testSetRoleCapabilities() (gas: 28985) -MultiRolesAuthorityTest:testSetRoles() (gas: 29006) -MultiRolesAuthorityTest:testSetTargetCustomAuthority() (gas: 27976) -ReentrancyGuardTest:testFailUnprotectedCall() (gas: 45665) -ReentrancyGuardTest:testNoReentrancy() (gas: 7515) -ReentrancyGuardTest:testProtectedCall() (gas: 32949) -RolesAuthorityTest:testCanCallPublicCapability() (gas: 33336) -RolesAuthorityTest:testCanCallWithAuthorizedRole() (gas: 79601) -RolesAuthorityTest:testSetPublicCapabilities() (gas: 29183) -RolesAuthorityTest:testSetRoleCapabilities() (gas: 30258) -RolesAuthorityTest:testSetRoles() (gas: 28986) -SSTORE2Test:testFailReadInvalidPointer() (gas: 2905) -SSTORE2Test:testFailReadInvalidPointerCustomBounds() (gas: 3143) -SSTORE2Test:testFailReadInvalidPointerCustomStartBound() (gas: 2982) -SSTORE2Test:testFailWriteReadEmptyOutOfBounds() (gas: 34432) -SSTORE2Test:testFailWriteReadOutOfBounds() (gas: 34453) -SSTORE2Test:testFailWriteReadOutOfStartBound() (gas: 34346) +FixedPointMathLibTest:testMulWadUp() (gas: 981) +FixedPointMathLibTest:testMulWadUpEdgeCases() (gas: 959) +FixedPointMathLibTest:testRPow() (gas: 2187) +FixedPointMathLibTest:testSqrt() (gas: 2559) +MultiRolesAuthorityTest:testCanCallPublicCapability() (gas: 34380) +MultiRolesAuthorityTest:testCanCallWithAuthorizedRole() (gas: 80732) +MultiRolesAuthorityTest:testCanCallWithCustomAuthority() (gas: 422900) +MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesPublicCapability() (gas: 247921) +MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesUserWithRole() (gas: 257077) +MultiRolesAuthorityTest:testSetPublicCapabilities() (gas: 27832) +MultiRolesAuthorityTest:testSetRoleCapabilities() (gas: 29055) +MultiRolesAuthorityTest:testSetRoles() (gas: 29076) +MultiRolesAuthorityTest:testSetTargetCustomAuthority() (gas: 27994) +ReentrancyGuardTest:testNoReentrancy() (gas: 7561) +ReentrancyGuardTest:testProtectedCall() (gas: 35836) +ReentrancyGuardTest:testUnprotectedCall() (gas: 31194) +RolesAuthorityTest:testCanCallPublicCapability() (gas: 33406) +RolesAuthorityTest:testCanCallWithAuthorizedRole() (gas: 79759) +RolesAuthorityTest:testSetPublicCapabilities() (gas: 29252) +RolesAuthorityTest:testSetRoleCapabilities() (gas: 30364) +RolesAuthorityTest:testSetRoles() (gas: 29074) +SSTORE2Test:testReadInvalidPointer() (gas: 6302) +SSTORE2Test:testReadInvalidPointerCustomBounds() (gas: 6093) +SSTORE2Test:testReadInvalidPointerCustomStartBound() (gas: 6379) SSTORE2Test:testWriteRead() (gas: 53511) -SSTORE2Test:testWriteReadCustomBounds() (gas: 34853) -SSTORE2Test:testWriteReadCustomStartBound() (gas: 34768) -SSTORE2Test:testWriteReadEmptyBound() (gas: 34639) -SSTORE2Test:testWriteReadFullBoundedRead() (gas: 53708) -SSTORE2Test:testWriteReadFullStartBound() (gas: 34725) -SafeCastLibTest:testFailSafeCastTo128() (gas: 321) -SafeCastLibTest:testFailSafeCastTo160() (gas: 342) -SafeCastLibTest:testFailSafeCastTo192() (gas: 344) -SafeCastLibTest:testFailSafeCastTo224() (gas: 343) -SafeCastLibTest:testFailSafeCastTo248() (gas: 365) -SafeCastLibTest:testFailSafeCastTo32() (gas: 364) -SafeCastLibTest:testFailSafeCastTo64() (gas: 321) -SafeCastLibTest:testFailSafeCastTo8() (gas: 296) -SafeCastLibTest:testFailSafeCastTo96() (gas: 321) +SSTORE2Test:testWriteReadCustomBounds() (gas: 34896) +SSTORE2Test:testWriteReadCustomStartBound() (gas: 34791) +SSTORE2Test:testWriteReadEmptyBound() (gas: 34662) +SSTORE2Test:testWriteReadEmptyOutOfBounds() (gas: 37438) +SSTORE2Test:testWriteReadFullBoundedRead() (gas: 53687) +SSTORE2Test:testWriteReadFullStartBound() (gas: 34770) +SSTORE2Test:testWriteReadOutOfBounds() (gas: 37864) +SSTORE2Test:testWriteReadOutOfStartBound() (gas: 37685) +SafeCastLibTest:testBadSafeCastTo128() (gas: 3709) +SafeCastLibTest:testBadSafeCastTo160() (gas: 3732) +SafeCastLibTest:testBadSafeCastTo192() (gas: 3733) +SafeCastLibTest:testBadSafeCastTo224() (gas: 3710) +SafeCastLibTest:testBadSafeCastTo248() (gas: 3710) +SafeCastLibTest:testBadSafeCastTo32() (gas: 3713) +SafeCastLibTest:testBadSafeCastTo64() (gas: 3691) +SafeCastLibTest:testBadSafeCastTo8() (gas: 3685) +SafeCastLibTest:testBadSafeCastTo96() (gas: 3755) SafeCastLibTest:testSafeCastTo128() (gas: 449) -SafeCastLibTest:testSafeCastTo160() (gas: 470) -SafeCastLibTest:testSafeCastTo192() (gas: 471) -SafeCastLibTest:testSafeCastTo224() (gas: 491) -SafeCastLibTest:testSafeCastTo248() (gas: 427) -SafeCastLibTest:testSafeCastTo32() (gas: 471) -SafeCastLibTest:testSafeCastTo64() (gas: 470) -SafeCastLibTest:testSafeCastTo8() (gas: 469) -SafeCastLibTest:testSafeCastTo96() (gas: 469) -SafeTransferLibTest:testApproveWithMissingReturn() (gas: 30774) +SafeCastLibTest:testSafeCastTo160() (gas: 491) +SafeCastLibTest:testSafeCastTo192() (gas: 470) +SafeCastLibTest:testSafeCastTo224() (gas: 449) +SafeCastLibTest:testSafeCastTo248() (gas: 494) +SafeCastLibTest:testSafeCastTo32() (gas: 493) +SafeCastLibTest:testSafeCastTo64() (gas: 448) +SafeCastLibTest:testSafeCastTo8() (gas: 446) +SafeCastLibTest:testSafeCastTo96() (gas: 513) +SafeTransferLibTest:testApproveWithMissingReturn() (gas: 30730) SafeTransferLibTest:testApproveWithNonContract() (gas: 3014) -SafeTransferLibTest:testApproveWithReturnsTooMuch() (gas: 31155) +SafeTransferLibTest:testApproveWithReturnsTooMuch() (gas: 31133) SafeTransferLibTest:testApproveWithStandardERC20() (gas: 30839) SafeTransferLibTest:testFailApproveWithReturnsFalse() (gas: 5626) -SafeTransferLibTest:testFailApproveWithReturnsTooLittle() (gas: 5569) +SafeTransferLibTest:testFailApproveWithReturnsTooLittle() (gas: 5547) SafeTransferLibTest:testFailApproveWithReverting() (gas: 5524) -SafeTransferLibTest:testFailTransferETHToContractWithoutFallback() (gas: 7244) -SafeTransferLibTest:testFailTransferFromWithReturnsFalse() (gas: 13662) -SafeTransferLibTest:testFailTransferFromWithReturnsTooLittle() (gas: 13500) -SafeTransferLibTest:testFailTransferFromWithReverting() (gas: 9757) -SafeTransferLibTest:testFailTransferWithReturnsFalse() (gas: 8532) -SafeTransferLibTest:testFailTransferWithReturnsTooLittle() (gas: 8473) +SafeTransferLibTest:testFailTransferETHToContractWithoutFallback() (gas: 7266) +SafeTransferLibTest:testFailTransferFromWithReturnsFalse() (gas: 13641) +SafeTransferLibTest:testFailTransferFromWithReturnsTooLittle() (gas: 13544) +SafeTransferLibTest:testFailTransferFromWithReverting() (gas: 9780) +SafeTransferLibTest:testFailTransferWithReturnsFalse() (gas: 8555) +SafeTransferLibTest:testFailTransferWithReturnsTooLittle() (gas: 8517) SafeTransferLibTest:testFailTransferWithReverting() (gas: 8516) -SafeTransferLibTest:testTransferETH() (gas: 34637) -SafeTransferLibTest:testTransferFromWithMissingReturn() (gas: 49153) -SafeTransferLibTest:testTransferFromWithNonContract() (gas: 3036) -SafeTransferLibTest:testTransferFromWithReturnsTooMuch() (gas: 49812) -SafeTransferLibTest:testTransferFromWithStandardERC20() (gas: 47623) -SafeTransferLibTest:testTransferWithMissingReturn() (gas: 36668) -SafeTransferLibTest:testTransferWithNonContract() (gas: 2990) +SafeTransferLibTest:testTransferETH() (gas: 34659) +SafeTransferLibTest:testTransferFromWithMissingReturn() (gas: 49188) +SafeTransferLibTest:testTransferFromWithNonContract() (gas: 3080) +SafeTransferLibTest:testTransferFromWithReturnsTooMuch() (gas: 49829) +SafeTransferLibTest:testTransferFromWithStandardERC20() (gas: 47658) +SafeTransferLibTest:testTransferWithMissingReturn() (gas: 36713) +SafeTransferLibTest:testTransferWithNonContract() (gas: 3013) SafeTransferLibTest:testTransferWithReturnsTooMuch() (gas: 37093) SafeTransferLibTest:testTransferWithStandardERC20() (gas: 36722) -WETHTest:testDeposit() (gas: 63260) -WETHTest:testFallbackDeposit() (gas: 63524) -WETHTest:testPartialWithdraw() (gas: 73281) +TestPlusTest:testBound() (gas: 16799) +TestPlusTest:testBoundMinBiggerThanMax() (gas: 3336) +TestPlusTest:testRelApproxEqBothZeroesPasses() (gas: 459) +WETHTest:testDeposit() (gas: 63239) +WETHTest:testFallbackDeposit() (gas: 63568) +WETHTest:testPartialWithdraw() (gas: 73347) WETHTest:testWithdraw() (gas: 54360) diff --git a/.gitmodules b/.gitmodules index e1247196..888d42dc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "lib/ds-test"] - path = lib/ds-test - url = https://github.com/dapphub/ds-test +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/lib/ds-test b/lib/ds-test deleted file mode 160000 index 2c7dbcc8..00000000 --- a/lib/ds-test +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2c7dbcc8586b33f358e3307a443e524490c17666 diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 00000000..9401f078 --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 9401f07830e31937c9cfa77890c99c2ee50a5229 diff --git a/package-lock.json b/package-lock.json index fdffe65e..d1d4e39f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,173 @@ { "name": "@rari-capital/solmate", "version": "6.2.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "@rari-capital/solmate", + "version": "6.2.0", + "license": "AGPL-3.0-only", + "devDependencies": { + "prettier": "^2.3.1", + "prettier-plugin-solidity": "^1.0.0-beta.13" + } + }, + "node_modules/@solidity-parser/parser": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.13.2.tgz", + "integrity": "sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw==", + "dev": true, + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/prettier-plugin-solidity": { + "version": "1.0.0-beta.16", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.16.tgz", + "integrity": "sha512-xVBcnoWpe52dNnCCbqPHC9ZrTWXcNfldf852ZD0DBcHDqVMwjHTAPEdfBVy6FczbFpVa8bmxQil+G5XkEz5WHA==", + "dev": true, + "dependencies": { + "@solidity-parser/parser": "^0.13.2", + "emoji-regex": "^9.2.2", + "escape-string-regexp": "^4.0.0", + "semver": "^7.3.5", + "solidity-comments-extractor": "^0.0.7", + "string-width": "^4.2.2" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "prettier": "^2.3.0" + } + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/solidity-comments-extractor": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", + "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + }, "dependencies": { "@solidity-parser/parser": { "version": "0.13.2", diff --git a/src/auth/Auth.sol b/src/auth/Auth.sol index 48edaa42..71d4016a 100644 --- a/src/auth/Auth.sol +++ b/src/auth/Auth.sol @@ -38,7 +38,7 @@ abstract contract Auth { function setAuthority(Authority newAuthority) public virtual { // We check if the caller is the owner first because we want to ensure they can // always swap out the authority even if it's reverting or using up a lot of gas. - require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig)); + require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig), "UNAUTHORIZED"); authority = newAuthority; diff --git a/src/test/Auth.t.sol b/src/test/Auth.t.sol index 19a6b846..c577fd5c 100644 --- a/src/test/Auth.t.sol +++ b/src/test/Auth.t.sol @@ -1,10 +1,9 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol"; import {MockAuthority} from "./utils/mocks/MockAuthority.sol"; - +import {TestPlus} from "./utils/TestPlus.sol"; import {Authority} from "../auth/Auth.sol"; contract OutOfOrderAuthority is Authority { @@ -17,7 +16,7 @@ contract OutOfOrderAuthority is Authority { } } -contract AuthTest is DSTestPlus { +contract AuthTest is TestPlus { MockAuthChild mockAuthChild; function setUp() public { @@ -61,46 +60,55 @@ contract AuthTest is DSTestPlus { mockAuthChild.setAuthority(new MockAuthority(true)); } - function testFailSetOwnerAsNonOwner() public { + function testSetOwnerAsNonOwner() public { mockAuthChild.setOwner(address(0)); + vm.expectRevert("UNAUTHORIZED"); mockAuthChild.setOwner(address(0xBEEF)); } - function testFailSetAuthorityAsNonOwner() public { + function testSetAuthorityAsNonOwner() public { mockAuthChild.setOwner(address(0)); + // Fails since MockAuthChild uses Authority(address(0)) which can't call `canCall` function + vm.expectRevert(); mockAuthChild.setAuthority(Authority(address(0xBEEF))); } - function testFailCallFunctionAsNonOwner() public { + function testCallFunctionAsNonOwner() public { mockAuthChild.setOwner(address(0)); + vm.expectRevert("UNAUTHORIZED"); mockAuthChild.updateFlag(); } - function testFailSetOwnerWithRestrictiveAuthority() public { + function testSetOwnerWithRestrictiveAuthority() public { mockAuthChild.setAuthority(new MockAuthority(false)); mockAuthChild.setOwner(address(0)); + vm.expectRevert("UNAUTHORIZED"); mockAuthChild.setOwner(address(this)); } - function testFailSetAuthorityWithRestrictiveAuthority() public { + function testSetAuthorityWithRestrictiveAuthority() public { mockAuthChild.setAuthority(new MockAuthority(false)); mockAuthChild.setOwner(address(0)); + vm.expectRevert("UNAUTHORIZED"); mockAuthChild.setAuthority(Authority(address(0xBEEF))); } - function testFailCallFunctionWithRestrictiveAuthority() public { + function testCallFunctionWithRestrictiveAuthority() public { mockAuthChild.setAuthority(new MockAuthority(false)); mockAuthChild.setOwner(address(0)); + vm.expectRevert("UNAUTHORIZED"); mockAuthChild.updateFlag(); } - function testFailSetOwnerAsOwnerWithOutOfOrderAuthority() public { + function testSetOwnerAsOwnerWithOutOfOrderAuthority() public { mockAuthChild.setAuthority(new OutOfOrderAuthority()); + vm.expectRevert("OUT_OF_ORDER"); mockAuthChild.setOwner(address(0)); } - function testFailCallFunctionAsOwnerWithOutOfOrderAuthority() public { + function testCallFunctionAsOwnerWithOutOfOrderAuthority() public { mockAuthChild.setAuthority(new OutOfOrderAuthority()); + vm.expectRevert("OUT_OF_ORDER"); mockAuthChild.updateFlag(); } @@ -138,55 +146,63 @@ contract AuthTest is DSTestPlus { mockAuthChild.updateFlag(); } - function testFailSetOwnerAsNonOwner(address deadOwner, address newOwner) public { + function testSetOwnerAsNonOwner(address deadOwner, address newOwner) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setOwner(deadOwner); + vm.expectRevert("UNAUTHORIZED"); mockAuthChild.setOwner(newOwner); } - function testFailSetAuthorityAsNonOwner(address deadOwner, Authority newAuthority) public { + function testSetAuthorityAsNonOwner(address deadOwner, Authority newAuthority) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setOwner(deadOwner); + // Fails since MockAuthChild uses Authority(address(0)) which can't call `canCall` function + vm.expectRevert(); mockAuthChild.setAuthority(newAuthority); } - function testFailCallFunctionAsNonOwner(address deadOwner) public { + function testCallFunctionAsNonOwner(address deadOwner) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setOwner(deadOwner); + vm.expectRevert("UNAUTHORIZED"); mockAuthChild.updateFlag(); } - function testFailSetOwnerWithRestrictiveAuthority(address deadOwner, address newOwner) public { + function testSetOwnerWithRestrictiveAuthority(address deadOwner, address newOwner) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new MockAuthority(false)); mockAuthChild.setOwner(deadOwner); + vm.expectRevert("UNAUTHORIZED"); mockAuthChild.setOwner(newOwner); } - function testFailSetAuthorityWithRestrictiveAuthority(address deadOwner, Authority newAuthority) public { + function testSetAuthorityWithRestrictiveAuthority(address deadOwner, Authority newAuthority) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new MockAuthority(false)); mockAuthChild.setOwner(deadOwner); + vm.expectRevert("UNAUTHORIZED"); mockAuthChild.setAuthority(newAuthority); } - function testFailCallFunctionWithRestrictiveAuthority(address deadOwner) public { + function testCallFunctionWithRestrictiveAuthority(address deadOwner) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new MockAuthority(false)); mockAuthChild.setOwner(deadOwner); + vm.expectRevert("UNAUTHORIZED"); mockAuthChild.updateFlag(); } - function testFailSetOwnerAsOwnerWithOutOfOrderAuthority(address deadOwner) public { + function testSetOwnerAsOwnerWithOutOfOrderAuthority(address deadOwner) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new OutOfOrderAuthority()); + vm.expectRevert("OUT_OF_ORDER"); mockAuthChild.setOwner(deadOwner); } } diff --git a/src/test/Bytes32AddressLib.t.sol b/src/test/Bytes32AddressLib.t.sol index 0a85b141..c0897c05 100644 --- a/src/test/Bytes32AddressLib.t.sol +++ b/src/test/Bytes32AddressLib.t.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {Bytes32AddressLib} from "../utils/Bytes32AddressLib.sol"; -contract Bytes32AddressLibTest is DSTestPlus { +contract Bytes32AddressLibTest is TestPlus { function testFillLast12Bytes() public { assertEq( Bytes32AddressLib.fillLast12Bytes(0xfEEDFaCEcaFeBEEFfEEDFACecaFEBeeFfeEdfAce), diff --git a/src/test/CREATE3.t.sol b/src/test/CREATE3.t.sol index 8120632d..b726f8b0 100644 --- a/src/test/CREATE3.t.sol +++ b/src/test/CREATE3.t.sol @@ -2,13 +2,13 @@ pragma solidity 0.8.10; import {WETH} from "../tokens/WETH.sol"; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {MockERC20} from "./utils/mocks/MockERC20.sol"; import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol"; import {CREATE3} from "../utils/CREATE3.sol"; -contract CREATE3Test is DSTestPlus { +contract CREATE3Test is TestPlus { function testDeployERC20() public { bytes32 salt = keccak256(bytes("A salt!")); @@ -27,17 +27,19 @@ contract CREATE3Test is DSTestPlus { assertEq(deployed.decimals(), 18); } - function testFailDoubleDeploySameBytecode() public { + function testDoubleDeploySameBytecode() public { bytes32 salt = keccak256(bytes("Salty...")); CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0); + vm.expectRevert("DEPLOYMENT_FAILED"); CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0); } - function testFailDoubleDeployDifferentBytecode() public { + function testDoubleDeployDifferentBytecode() public { bytes32 salt = keccak256(bytes("and sweet!")); CREATE3.deploy(salt, type(WETH).creationCode, 0); + vm.expectRevert("DEPLOYMENT_FAILED"); CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0); } diff --git a/src/test/ERC1155.t.sol b/src/test/ERC1155.t.sol index c3d3deca..06b41cf7 100644 --- a/src/test/ERC1155.t.sol +++ b/src/test/ERC1155.t.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import "forge-std/Test.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; import {MockERC1155} from "./utils/mocks/MockERC1155.sol"; @@ -108,7 +109,7 @@ contract WrongReturnDataERC1155Recipient is ERC1155TokenReceiver { contract NonERC1155Recipient {} -contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { +contract ERC1155Test is TestPlus, ERC1155TokenReceiver { MockERC1155 token; mapping(address => mapping(uint256 => uint256)) public userMintAmounts; @@ -245,7 +246,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.mint(from, 1337, 100, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeTransferFrom(from, address(0xBEEF), 1337, 70, ""); @@ -261,7 +262,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.mint(from, 1337, 100, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeTransferFrom(from, address(to), 1337, 70, "testing 123"); @@ -310,7 +311,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, ids, mintAmounts, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeBatchTransferFrom(from, address(0xBEEF), ids, transferAmounts, ""); @@ -359,7 +360,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, ids, mintAmounts, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeBatchTransferFrom(from, address(to), ids, transferAmounts, "testing 123"); @@ -416,51 +417,62 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { assertEq(balances[4], 500); } - function testFailMintToZero() public { + function testMintToZero() public { + vm.expectRevert("UNSAFE_RECIPIENT"); token.mint(address(0), 1337, 1, ""); } - function testFailMintToNonERC155Recipient() public { - token.mint(address(new NonERC1155Recipient()), 1337, 1, ""); + function testMintToNonERC155Recipient() public { + address to = address(new NonERC1155Recipient()); + vm.expectRevert(); + token.mint(to, 1337, 1, ""); } function testFailMintToRevertingERC155Recipient() public { - token.mint(address(new RevertingERC1155Recipient()), 1337, 1, ""); + address to = address(new RevertingERC1155Recipient()); + token.mint(to, 1337, 1, ""); } function testFailMintToWrongReturnDataERC155Recipient() public { - token.mint(address(new RevertingERC1155Recipient()), 1337, 1, ""); + address to = address(new RevertingERC1155Recipient()); + token.mint(to, 1337, 1, ""); } - function testFailBurnInsufficientBalance() public { + function testBurnInsufficientBalance() public { token.mint(address(0xBEEF), 1337, 70, ""); + vm.expectRevert(stdError.arithmeticError); token.burn(address(0xBEEF), 1337, 100); } - function testFailSafeTransferFromInsufficientBalance() public { + function testSafeTransferFromInsufficientBalance() public { address from = address(0xABCD); token.mint(from, 1337, 70, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); + vm.expectRevert(stdError.arithmeticError); token.safeTransferFrom(from, address(0xBEEF), 1337, 100, ""); } - function testFailSafeTransferFromSelfInsufficientBalance() public { + function testSafeTransferFromSelfInsufficientBalance() public { token.mint(address(this), 1337, 70, ""); + vm.expectRevert(stdError.arithmeticError); token.safeTransferFrom(address(this), address(0xBEEF), 1337, 100, ""); } - function testFailSafeTransferFromToZero() public { + function testSafeTransferFromToZero() public { token.mint(address(this), 1337, 100, ""); + vm.expectRevert("UNSAFE_RECIPIENT"); token.safeTransferFrom(address(this), address(0), 1337, 70, ""); } - function testFailSafeTransferFromToNonERC155Recipient() public { + function testSafeTransferFromToNonERC155Recipient() public { token.mint(address(this), 1337, 100, ""); - token.safeTransferFrom(address(this), address(new NonERC1155Recipient()), 1337, 70, ""); + address recipient = address(new NonERC1155Recipient()); + vm.expectRevert(); + token.safeTransferFrom(address(this), recipient, 1337, 70, ""); } function testFailSafeTransferFromToRevertingERC1155Recipient() public { @@ -468,12 +480,14 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.safeTransferFrom(address(this), address(new RevertingERC1155Recipient()), 1337, 70, ""); } - function testFailSafeTransferFromToWrongReturnDataERC1155Recipient() public { + function testSafeTransferFromToWrongReturnDataERC1155Recipient() public { token.mint(address(this), 1337, 100, ""); - token.safeTransferFrom(address(this), address(new WrongReturnDataERC1155Recipient()), 1337, 70, ""); + address recipient = address(new WrongReturnDataERC1155Recipient()); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeTransferFrom(address(this), recipient, 1337, 70, ""); } - function testFailSafeBatchTransferInsufficientBalance() public { + function testSafeBatchTransferInsufficientBalance() public { address from = address(0xABCD); uint256[] memory ids = new uint256[](5); @@ -500,13 +514,14 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, ids, mintAmounts, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); + vm.expectRevert(stdError.arithmeticError); token.safeBatchTransferFrom(from, address(0xBEEF), ids, transferAmounts, ""); } - function testFailSafeBatchTransferFromToZero() public { + function testSafeBatchTransferFromToZero() public { address from = address(0xABCD); uint256[] memory ids = new uint256[](5); @@ -532,13 +547,14 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, ids, mintAmounts, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); + vm.expectRevert("UNSAFE_RECIPIENT"); token.safeBatchTransferFrom(from, address(0), ids, transferAmounts, ""); } - function testFailSafeBatchTransferFromToNonERC1155Recipient() public { + function testSafeBatchTransferFromToNonERC1155Recipient() public { address from = address(0xABCD); uint256[] memory ids = new uint256[](5); @@ -564,10 +580,13 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, ids, mintAmounts, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); - token.safeBatchTransferFrom(from, address(new NonERC1155Recipient()), ids, transferAmounts, ""); + address recipient = address(new NonERC1155Recipient()); + + vm.expectRevert(); + token.safeBatchTransferFrom(from, recipient, ids, transferAmounts, ""); } function testFailSafeBatchTransferFromToRevertingERC1155Recipient() public { @@ -596,13 +615,13 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, ids, mintAmounts, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeBatchTransferFrom(from, address(new RevertingERC1155Recipient()), ids, transferAmounts, ""); } - function testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() public { + function testSafeBatchTransferFromToWrongReturnDataERC1155Recipient() public { address from = address(0xABCD); uint256[] memory ids = new uint256[](5); @@ -628,13 +647,16 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, ids, mintAmounts, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); - token.safeBatchTransferFrom(from, address(new WrongReturnDataERC1155Recipient()), ids, transferAmounts, ""); + address recipient = address(new WrongReturnDataERC1155Recipient()); + + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeBatchTransferFrom(from, recipient, ids, transferAmounts, ""); } - function testFailSafeBatchTransferFromWithArrayLengthMismatch() public { + function testSafeBatchTransferFromWithArrayLengthMismatch() public { address from = address(0xABCD); uint256[] memory ids = new uint256[](5); @@ -659,13 +681,14 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, ids, mintAmounts, ""); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); + vm.expectRevert("LENGTH_MISMATCH"); token.safeBatchTransferFrom(from, address(0xBEEF), ids, transferAmounts, ""); } - function testFailBatchMintToZero() public { + function testBatchMintToZero() public { uint256[] memory ids = new uint256[](5); ids[0] = 1337; ids[1] = 1338; @@ -680,10 +703,11 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { mintAmounts[3] = 400; mintAmounts[4] = 500; + vm.expectRevert("UNSAFE_RECIPIENT"); token.batchMint(address(0), ids, mintAmounts, ""); } - function testFailBatchMintToNonERC1155Recipient() public { + function testBatchMintToNonERC1155Recipient() public { NonERC1155Recipient to = new NonERC1155Recipient(); uint256[] memory ids = new uint256[](5); @@ -700,6 +724,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { mintAmounts[3] = 400; mintAmounts[4] = 500; + vm.expectRevert(); token.batchMint(address(to), ids, mintAmounts, ""); } @@ -723,7 +748,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(address(to), ids, mintAmounts, ""); } - function testFailBatchMintToWrongReturnDataERC1155Recipient() public { + function testBatchMintToWrongReturnDataERC1155Recipient() public { WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient(); uint256[] memory ids = new uint256[](5); @@ -740,10 +765,11 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { mintAmounts[3] = 400; mintAmounts[4] = 500; + vm.expectRevert("UNSAFE_RECIPIENT"); token.batchMint(address(to), ids, mintAmounts, ""); } - function testFailBatchMintWithArrayMismatch() public { + function testBatchMintWithArrayMismatch() public { uint256[] memory ids = new uint256[](5); ids[0] = 1337; ids[1] = 1338; @@ -757,10 +783,11 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { amounts[2] = 300; amounts[3] = 400; + vm.expectRevert("LENGTH_MISMATCH"); token.batchMint(address(0xBEEF), ids, amounts, ""); } - function testFailBatchBurnInsufficientBalance() public { + function testBatchBurnInsufficientBalance() public { uint256[] memory ids = new uint256[](5); ids[0] = 1337; ids[1] = 1338; @@ -784,10 +811,11 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(address(0xBEEF), ids, mintAmounts, ""); + vm.expectRevert(stdError.arithmeticError); token.batchBurn(address(0xBEEF), ids, burnAmounts); } - function testFailBatchBurnWithArrayLengthMismatch() public { + function testBatchBurnWithArrayLengthMismatch() public { uint256[] memory ids = new uint256[](5); ids[0] = 1337; ids[1] = 1338; @@ -810,10 +838,11 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(address(0xBEEF), ids, mintAmounts, ""); + vm.expectRevert("LENGTH_MISMATCH"); token.batchBurn(address(0xBEEF), ids, burnAmounts); } - function testFailBalanceOfBatchWithArrayMismatch() public view { + function testBalanceOfBatchWithArrayMismatch() public { address[] memory tos = new address[](5); tos[0] = address(0xBEEF); tos[1] = address(0xCAFE); @@ -827,6 +856,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ids[2] = 1339; ids[3] = 1340; + vm.expectRevert("LENGTH_MISMATCH"); token.balanceOfBatch(tos, ids); } @@ -838,7 +868,8 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ) public { if (to == address(0)) to = address(0xBEEF); - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; + vm.assume(uint256(uint160(to)) > 18); + vm.assume(to.code.length == 0); token.mint(to, id, amount, mintData); @@ -870,7 +901,8 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ) public { if (to == address(0)) to = address(0xBEEF); - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; + vm.assume(uint256(uint160(to)) > 18); + vm.assume(to.code.length == 0); uint256 minLength = min2(ids.length, amounts.length); @@ -948,7 +980,8 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ) public { if (to == address(0)) to = address(0xBEEF); - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; + vm.assume(uint256(uint160(to)) > 18); + vm.assume(to.code.length == 0); burnAmount = bound(burnAmount, 0, mintAmount); @@ -968,7 +1001,8 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ) public { if (to == address(0)) to = address(0xBEEF); - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; + vm.assume(uint256(uint160(to)) > 18); + vm.assume(to.code.length == 0); uint256 minLength = min3(ids.length, mintAmounts.length, burnAmounts.length); @@ -1016,7 +1050,8 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ) public { if (to == address(0)) to = address(0xBEEF); - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; + vm.assume(uint256(uint160(to)) > 18); + vm.assume(to.code.length == 0); transferAmount = bound(transferAmount, 0, mintAmount); @@ -1024,7 +1059,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.mint(from, id, mintAmount, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeTransferFrom(from, to, id, transferAmount, transferData); @@ -1048,7 +1083,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.mint(from, id, mintAmount, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeTransferFrom(from, address(to), id, transferAmount, transferData); @@ -1072,7 +1107,8 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ) public { if (to == address(0)) to = address(0xBEEF); - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; + vm.assume(uint256(uint160(to)) > 18); + vm.assume(to.code.length == 0); transferAmount = bound(transferAmount, 0, mintAmount); @@ -1092,11 +1128,11 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { bytes memory mintData, bytes memory transferData ) public { - if (to == address(0)) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; - address from = address(0xABCD); + if (to == address(0) || to == from) to = address(0xBEEF); + + vm.assume(uint256(uint160(to)) > 18); + vm.assume(to.code.length == 0); uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); @@ -1122,7 +1158,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeBatchTransferFrom(from, to, normalizedIds, normalizedTransferAmounts, transferData); @@ -1170,7 +1206,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeBatchTransferFrom(from, address(to), normalizedIds, normalizedTransferAmounts, transferData); @@ -1224,20 +1260,25 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { } } - function testFailMintToZero( + function testMintToZero( uint256 id, uint256 amount, bytes memory data ) public { + vm.expectRevert("UNSAFE_RECIPIENT"); token.mint(address(0), id, amount, data); } - function testFailMintToNonERC155Recipient( + function testMintToNonERC155Recipient( uint256 id, uint256 mintAmount, bytes memory mintData ) public { - token.mint(address(new NonERC1155Recipient()), id, mintAmount, mintData); + id = bound(id, 1, type(uint256).max); + mintAmount = bound(mintAmount, 1, type(uint256).max); + address recipient = address(new NonERC1155Recipient()); + vm.expectRevert(); + token.mint(recipient, id, mintAmount, mintData); } function testFailMintToRevertingERC155Recipient( @@ -1248,28 +1289,33 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.mint(address(new RevertingERC1155Recipient()), id, mintAmount, mintData); } - function testFailMintToWrongReturnDataERC155Recipient( + function testMintToWrongReturnDataERC155Recipient( uint256 id, uint256 mintAmount, bytes memory mintData ) public { - token.mint(address(new RevertingERC1155Recipient()), id, mintAmount, mintData); + address recipient = address(new WrongReturnDataERC1155Recipient()); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.mint(recipient, id, mintAmount, mintData); } - function testFailBurnInsufficientBalance( + function testBurnInsufficientBalance( address to, uint256 id, uint256 mintAmount, uint256 burnAmount, bytes memory mintData ) public { + if (to == address(0)) to = address(0xDEAD); + mintAmount = bound(mintAmount, 0, type(uint256).max - 1); burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max); token.mint(to, id, mintAmount, mintData); + vm.expectRevert(stdError.arithmeticError); token.burn(to, id, burnAmount); } - function testFailSafeTransferFromInsufficientBalance( + function testSafeTransferFromInsufficientBalance( address to, uint256 id, uint256 mintAmount, @@ -1278,18 +1324,21 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { bytes memory transferData ) public { address from = address(0xABCD); + if (to == address(0) || to == from) to = address(0xDEAD); + mintAmount = bound(mintAmount, 0, type(uint256).max - 1); transferAmount = bound(transferAmount, mintAmount + 1, type(uint256).max); token.mint(from, id, mintAmount, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); + vm.expectRevert(stdError.arithmeticError); token.safeTransferFrom(from, to, id, transferAmount, transferData); } - function testFailSafeTransferFromSelfInsufficientBalance( + function testSafeTransferFromSelfInsufficientBalance( address to, uint256 id, uint256 mintAmount, @@ -1297,13 +1346,16 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { bytes memory mintData, bytes memory transferData ) public { + if (to == address(0)) to = address(0xDEAD); + mintAmount = bound(mintAmount, 0, type(uint256).max - 1); transferAmount = bound(transferAmount, mintAmount + 1, type(uint256).max); token.mint(address(this), id, mintAmount, mintData); + vm.expectRevert(stdError.arithmeticError); token.safeTransferFrom(address(this), to, id, transferAmount, transferData); } - function testFailSafeTransferFromToZero( + function testSafeTransferFromToZero( uint256 id, uint256 mintAmount, uint256 transferAmount, @@ -1313,10 +1365,11 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { transferAmount = bound(transferAmount, 0, mintAmount); token.mint(address(this), id, mintAmount, mintData); + vm.expectRevert("UNSAFE_RECIPIENT"); token.safeTransferFrom(address(this), address(0), id, transferAmount, transferData); } - function testFailSafeTransferFromToNonERC155Recipient( + function testSafeTransferFromToNonERC155Recipient( uint256 id, uint256 mintAmount, uint256 transferAmount, @@ -1326,7 +1379,9 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { transferAmount = bound(transferAmount, 0, mintAmount); token.mint(address(this), id, mintAmount, mintData); - token.safeTransferFrom(address(this), address(new NonERC1155Recipient()), id, transferAmount, transferData); + address recipient = address(new NonERC1155Recipient()); + vm.expectRevert(); + token.safeTransferFrom(address(this), recipient, id, transferAmount, transferData); } function testFailSafeTransferFromToRevertingERC1155Recipient( @@ -1348,7 +1403,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ); } - function testFailSafeTransferFromToWrongReturnDataERC1155Recipient( + function testSafeTransferFromToWrongReturnDataERC1155Recipient( uint256 id, uint256 mintAmount, uint256 transferAmount, @@ -1358,16 +1413,12 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { transferAmount = bound(transferAmount, 0, mintAmount); token.mint(address(this), id, mintAmount, mintData); - token.safeTransferFrom( - address(this), - address(new WrongReturnDataERC1155Recipient()), - id, - transferAmount, - transferData - ); + address recipient = address(new WrongReturnDataERC1155Recipient()); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeTransferFrom(address(this), recipient, id, transferAmount, transferData); } - function testFailSafeBatchTransferInsufficientBalance( + function testSafeBatchTransferInsufficientBalance( address to, uint256[] memory ids, uint256[] memory mintAmounts, @@ -1379,7 +1430,9 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); - if (minLength == 0) revert(); + vm.assume(minLength != 0); + + if (to == address(0) || to == from) to = address(0xDEAD); uint256[] memory normalizedIds = new uint256[](minLength); uint256[] memory normalizedMintAmounts = new uint256[](minLength); @@ -1388,7 +1441,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { for (uint256 i = 0; i < minLength; i++) { uint256 id = ids[i]; - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[from][id]; + uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[from][id] - 1; uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId); uint256 transferAmount = bound(transferAmounts[i], mintAmount + 1, type(uint256).max); @@ -1402,13 +1455,14 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); + vm.expectRevert(stdError.arithmeticError); token.safeBatchTransferFrom(from, to, normalizedIds, normalizedTransferAmounts, transferData); } - function testFailSafeBatchTransferFromToZero( + function testSafeBatchTransferFromToZero( uint256[] memory ids, uint256[] memory mintAmounts, uint256[] memory transferAmounts, @@ -1440,13 +1494,14 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); + vm.expectRevert("UNSAFE_RECIPIENT"); token.safeBatchTransferFrom(from, address(0), normalizedIds, normalizedTransferAmounts, transferData); } - function testFailSafeBatchTransferFromToNonERC1155Recipient( + function testSafeBatchTransferFromToNonERC1155Recipient( uint256[] memory ids, uint256[] memory mintAmounts, uint256[] memory transferAmounts, @@ -1456,6 +1511,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { address from = address(0xABCD); uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); + vm.assume(minLength != 0); uint256[] memory normalizedIds = new uint256[](minLength); uint256[] memory normalizedMintAmounts = new uint256[](minLength); @@ -1478,16 +1534,13 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); - token.safeBatchTransferFrom( - from, - address(new NonERC1155Recipient()), - normalizedIds, - normalizedTransferAmounts, - transferData - ); + address recipient = address(new NonERC1155Recipient()); + + vm.expectRevert(); + token.safeBatchTransferFrom(from, recipient, normalizedIds, normalizedTransferAmounts, transferData); } function testFailSafeBatchTransferFromToRevertingERC1155Recipient( @@ -1522,7 +1575,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeBatchTransferFrom( @@ -1534,7 +1587,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ); } - function testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient( + function testSafeBatchTransferFromToWrongReturnDataERC1155Recipient( uint256[] memory ids, uint256[] memory mintAmounts, uint256[] memory transferAmounts, @@ -1544,6 +1597,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { address from = address(0xABCD); uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); + vm.assume(minLength != 0); uint256[] memory normalizedIds = new uint256[](minLength); uint256[] memory normalizedMintAmounts = new uint256[](minLength); @@ -1566,16 +1620,13 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); - token.safeBatchTransferFrom( - from, - address(new WrongReturnDataERC1155Recipient()), - normalizedIds, - normalizedTransferAmounts, - transferData - ); + address recipient = address(new WrongReturnDataERC1155Recipient()); + + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeBatchTransferFrom(from, recipient, normalizedIds, normalizedTransferAmounts, transferData); } function testFailSafeBatchTransferFromWithArrayLengthMismatch( @@ -1588,22 +1639,26 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ) public { address from = address(0xABCD); - if (ids.length == transferAmounts.length) revert(); + if (to == address(0) || to == from) to = address(0xDEAD); + + if (ids.length <= transferAmounts.length) revert(); + if (ids.length != mintAmounts.length) revert(); token.batchMint(from, ids, mintAmounts, mintData); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeBatchTransferFrom(from, to, ids, transferAmounts, transferData); } - function testFailBatchMintToZero( + function testBatchMintToZero( uint256[] memory ids, uint256[] memory amounts, bytes memory mintData ) public { uint256 minLength = min2(ids.length, amounts.length); + vm.assume(minLength != 0); uint256[] memory normalizedIds = new uint256[](minLength); uint256[] memory normalizedAmounts = new uint256[](minLength); @@ -1621,10 +1676,11 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { userMintAmounts[address(0)][id] += mintAmount; } + vm.expectRevert("UNSAFE_RECIPIENT"); token.batchMint(address(0), normalizedIds, normalizedAmounts, mintData); } - function testFailBatchMintToNonERC1155Recipient( + function testBatchMintToNonERC1155Recipient( uint256[] memory ids, uint256[] memory amounts, bytes memory mintData @@ -1632,6 +1688,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { NonERC1155Recipient to = new NonERC1155Recipient(); uint256 minLength = min2(ids.length, amounts.length); + vm.assume(minLength != 0); uint256[] memory normalizedIds = new uint256[](minLength); uint256[] memory normalizedAmounts = new uint256[](minLength); @@ -1649,6 +1706,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { userMintAmounts[address(to)][id] += mintAmount; } + vm.expectRevert(); token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData); } @@ -1680,7 +1738,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData); } - function testFailBatchMintToWrongReturnDataERC1155Recipient( + function testBatchMintToWrongReturnDataERC1155Recipient( uint256[] memory ids, uint256[] memory amounts, bytes memory mintData @@ -1688,6 +1746,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient(); uint256 minLength = min2(ids.length, amounts.length); + vm.assume(minLength != 0); uint256[] memory normalizedIds = new uint256[](minLength); uint256[] memory normalizedAmounts = new uint256[](minLength); @@ -1705,21 +1764,24 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { userMintAmounts[address(to)][id] += mintAmount; } + vm.expectRevert("UNSAFE_RECIPIENT"); token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData); } - function testFailBatchMintWithArrayMismatch( + function testBatchMintWithArrayMismatch( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory mintData ) public { - if (ids.length == amounts.length) revert(); + vm.assume(ids.length != amounts.length); + if (to == address(0)) to = address(0xDEAD); + vm.expectRevert("LENGTH_MISMATCH"); token.batchMint(address(to), ids, amounts, mintData); } - function testFailBatchBurnInsufficientBalance( + function testBatchBurnInsufficientBalance( address to, uint256[] memory ids, uint256[] memory mintAmounts, @@ -1728,7 +1790,8 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { ) public { uint256 minLength = min3(ids.length, mintAmounts.length, burnAmounts.length); - if (minLength == 0) revert(); + vm.assume(minLength != 0); + if (to == address(0)) to = address(0xDEAD); uint256[] memory normalizedIds = new uint256[](minLength); uint256[] memory normalizedMintAmounts = new uint256[](minLength); @@ -1737,7 +1800,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { for (uint256 i = 0; i < minLength; i++) { uint256 id = ids[i]; - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id]; + uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id] - 1; normalizedIds[i] = id; normalizedMintAmounts[i] = bound(mintAmounts[i], 0, remainingMintAmountForId); @@ -1748,6 +1811,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.batchMint(to, normalizedIds, normalizedMintAmounts, mintData); + vm.expectRevert(stdError.arithmeticError); token.batchBurn(to, normalizedIds, normalizedBurnAmounts); } @@ -1758,16 +1822,25 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { uint256[] memory burnAmounts, bytes memory mintData ) public { + if (to == address(0)) to = address(0xDEAD); if (ids.length == burnAmounts.length) revert(); + if (ids.length != mintAmounts.length) revert(); token.batchMint(to, ids, mintAmounts, mintData); token.batchBurn(to, ids, burnAmounts); } - function testFailBalanceOfBatchWithArrayMismatch(address[] memory tos, uint256[] memory ids) public view { - if (tos.length == ids.length) revert(); + function testBalanceOfBatchWithArrayMismatch(address[] memory tos, uint256[] memory ids) public { + vm.assume(tos.length != ids.length); + + for (uint256 i = 0; i < tos.length; i++) { + if (tos[i] == address(0)) { + tos[i] = address(0xDEAD); + } + } + vm.expectRevert("LENGTH_MISMATCH"); token.balanceOfBatch(tos, ids); } } diff --git a/src/test/ERC20.t.sol b/src/test/ERC20.t.sol index 15c6f4ae..03be6e97 100644 --- a/src/test/ERC20.t.sol +++ b/src/test/ERC20.t.sol @@ -1,14 +1,18 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import "forge-std/Test.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; import {MockERC20} from "./utils/mocks/MockERC20.sol"; -contract ERC20Test is DSTestPlus { +contract ERC20Test is TestPlus { MockERC20 token; + event Transfer(address indexed from, address indexed to, uint256 amount); + event Approval(address indexed owner, address indexed spender, uint256 amount); + bytes32 constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); @@ -23,6 +27,8 @@ contract ERC20Test is DSTestPlus { } function testMint() public { + vm.expectEmit(true, true, true, true); + emit Transfer(address(0), address(0xBEEF), 1e18); token.mint(address(0xBEEF), 1e18); assertEq(token.totalSupply(), 1e18); @@ -31,6 +37,9 @@ contract ERC20Test is DSTestPlus { function testBurn() public { token.mint(address(0xBEEF), 1e18); + + vm.expectEmit(true, true, true, true); + emit Transfer(address(0xBEEF), address(0), 0.9e18); token.burn(address(0xBEEF), 0.9e18); assertEq(token.totalSupply(), 1e18 - 0.9e18); @@ -38,6 +47,8 @@ contract ERC20Test is DSTestPlus { } function testApprove() public { + vm.expectEmit(true, true, true, true); + emit Approval(address(this), address(0xBEEF), 1e18); assertTrue(token.approve(address(0xBEEF), 1e18)); assertEq(token.allowance(address(this), address(0xBEEF)), 1e18); @@ -46,6 +57,8 @@ contract ERC20Test is DSTestPlus { function testTransfer() public { token.mint(address(this), 1e18); + vm.expectEmit(true, true, true, true); + emit Transfer(address(this), address(0xBEEF), 1e18); assertTrue(token.transfer(address(0xBEEF), 1e18)); assertEq(token.totalSupply(), 1e18); @@ -58,9 +71,11 @@ contract ERC20Test is DSTestPlus { token.mint(from, 1e18); - hevm.prank(from); + vm.prank(from); token.approve(address(this), 1e18); + vm.expectEmit(true, true, true, true); + emit Transfer(from, address(0xBEEF), 1e18); assertTrue(token.transferFrom(from, address(0xBEEF), 1e18)); assertEq(token.totalSupply(), 1e18); @@ -75,9 +90,13 @@ contract ERC20Test is DSTestPlus { token.mint(from, 1e18); - hevm.prank(from); + vm.prank(from); + vm.expectEmit(true, true, true, true); + emit Approval(from, address(this), type(uint256).max); token.approve(address(this), type(uint256).max); + vm.expectEmit(true, true, true, true); + emit Transfer(from, address(0xBEEF), 1e18); assertTrue(token.transferFrom(from, address(0xBEEF), 1e18)); assertEq(token.totalSupply(), 1e18); @@ -89,9 +108,9 @@ contract ERC20Test is DSTestPlus { function testPermit() public { uint256 privateKey = 0xBEEF; - address owner = hevm.addr(privateKey); + address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( + (uint8 v, bytes32 r, bytes32 s) = vm.sign( privateKey, keccak256( abi.encodePacked( @@ -102,44 +121,49 @@ contract ERC20Test is DSTestPlus { ) ); + vm.expectEmit(true, true, true, true); + emit Approval(owner, address(0xCAFE), 1e18); token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); assertEq(token.allowance(owner, address(0xCAFE)), 1e18); assertEq(token.nonces(owner), 1); } - function testFailTransferInsufficientBalance() public { + function testTransferInsufficientBalance() public { token.mint(address(this), 0.9e18); + vm.expectRevert(stdError.arithmeticError); token.transfer(address(0xBEEF), 1e18); } - function testFailTransferFromInsufficientAllowance() public { + function testTransferFromInsufficientAllowance() public { address from = address(0xABCD); token.mint(from, 1e18); - hevm.prank(from); + vm.prank(from); token.approve(address(this), 0.9e18); + vm.expectRevert(stdError.arithmeticError); token.transferFrom(from, address(0xBEEF), 1e18); } - function testFailTransferFromInsufficientBalance() public { + function testTransferFromInsufficientBalance() public { address from = address(0xABCD); token.mint(from, 0.9e18); - hevm.prank(from); + vm.prank(from); token.approve(address(this), 1e18); + vm.expectRevert(stdError.arithmeticError); token.transferFrom(from, address(0xBEEF), 1e18); } - function testFailPermitBadNonce() public { + function testPermitBadNonce() public { uint256 privateKey = 0xBEEF; - address owner = hevm.addr(privateKey); + address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( + (uint8 v, bytes32 r, bytes32 s) = vm.sign( privateKey, keccak256( abi.encodePacked( @@ -150,14 +174,15 @@ contract ERC20Test is DSTestPlus { ) ); + vm.expectRevert("INVALID_SIGNER"); token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); } - function testFailPermitBadDeadline() public { + function testPermitBadDeadline() public { uint256 privateKey = 0xBEEF; - address owner = hevm.addr(privateKey); + address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( + (uint8 v, bytes32 r, bytes32 s) = vm.sign( privateKey, keccak256( abi.encodePacked( @@ -168,32 +193,38 @@ contract ERC20Test is DSTestPlus { ) ); + vm.expectRevert("INVALID_SIGNER"); token.permit(owner, address(0xCAFE), 1e18, block.timestamp + 1, v, r, s); } - function testFailPermitPastDeadline() public { + function testPermitPastDeadline() public { uint256 privateKey = 0xBEEF; - address owner = hevm.addr(privateKey); + address owner = vm.addr(privateKey); + uint256 deadline = block.timestamp == 0 ? 0 : block.timestamp - 1; - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( + bytes32 domain_separator = token.DOMAIN_SEPARATOR(); + (uint8 v, bytes32 r, bytes32 s) = vm.sign( privateKey, keccak256( abi.encodePacked( "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp - 1)) + domain_separator, + keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, deadline)) ) ) ); - token.permit(owner, address(0xCAFE), 1e18, block.timestamp - 1, v, r, s); + vm.warp(deadline + 1); + + vm.expectRevert("PERMIT_DEADLINE_EXPIRED"); + token.permit(owner, address(0xCAFE), 1e18, deadline, v, r, s); } - function testFailPermitReplay() public { + function testPermitReplay() public { uint256 privateKey = 0xBEEF; - address owner = hevm.addr(privateKey); + address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( + (uint8 v, bytes32 r, bytes32 s) = vm.sign( privateKey, keccak256( abi.encodePacked( @@ -205,6 +236,7 @@ contract ERC20Test is DSTestPlus { ); token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); + vm.expectRevert("INVALID_SIGNER"); token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); } @@ -219,11 +251,13 @@ contract ERC20Test is DSTestPlus { assertEq(tkn.decimals(), decimals); } - function testMint(address from, uint256 amount) public { - token.mint(from, amount); + function testMint(address to, uint256 amount) public { + vm.expectEmit(true, true, true, true); + emit Transfer(address(0), to, amount); + token.mint(to, amount); assertEq(token.totalSupply(), amount); - assertEq(token.balanceOf(from), amount); + assertEq(token.balanceOf(to), amount); } function testBurn( @@ -234,6 +268,9 @@ contract ERC20Test is DSTestPlus { burnAmount = bound(burnAmount, 0, mintAmount); token.mint(from, mintAmount); + + vm.expectEmit(true, true, true, true); + emit Transfer(from, address(0), burnAmount); token.burn(from, burnAmount); assertEq(token.totalSupply(), mintAmount - burnAmount); @@ -241,22 +278,26 @@ contract ERC20Test is DSTestPlus { } function testApprove(address to, uint256 amount) public { + vm.expectEmit(true, true, true, true); + emit Approval(address(this), to, amount); assertTrue(token.approve(to, amount)); assertEq(token.allowance(address(this), to), amount); } - function testTransfer(address from, uint256 amount) public { + function testTransfer(address to, uint256 amount) public { token.mint(address(this), amount); - assertTrue(token.transfer(from, amount)); + vm.expectEmit(true, true, true, true); + emit Transfer(address(this), to, amount); + assertTrue(token.transfer(to, amount)); assertEq(token.totalSupply(), amount); - if (address(this) == from) { + if (address(this) == to) { assertEq(token.balanceOf(address(this)), amount); } else { assertEq(token.balanceOf(address(this)), 0); - assertEq(token.balanceOf(from), amount); + assertEq(token.balanceOf(to), amount); } } @@ -271,9 +312,11 @@ contract ERC20Test is DSTestPlus { token.mint(from, amount); - hevm.prank(from); + vm.prank(from); token.approve(address(this), approval); + vm.expectEmit(true, true, true, true); + emit Transfer(from, to, amount); assertTrue(token.transferFrom(from, to, amount)); assertEq(token.totalSupply(), amount); @@ -298,9 +341,9 @@ contract ERC20Test is DSTestPlus { if (deadline < block.timestamp) deadline = block.timestamp; if (privateKey == 0) privateKey = 1; - address owner = hevm.addr(privateKey); + address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( + (uint8 v, bytes32 r, bytes32 s) = vm.sign( privateKey, keccak256( abi.encodePacked( @@ -311,70 +354,80 @@ contract ERC20Test is DSTestPlus { ) ); + vm.expectEmit(true, true, true, true); + emit Approval(owner, to, amount); token.permit(owner, to, amount, deadline, v, r, s); assertEq(token.allowance(owner, to), amount); assertEq(token.nonces(owner), 1); } - function testFailBurnInsufficientBalance( + function testBurnInsufficientBalance( address to, uint256 mintAmount, uint256 burnAmount ) public { + if (mintAmount == type(uint256).max) mintAmount -= 1; burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max); token.mint(to, mintAmount); + vm.expectRevert(stdError.arithmeticError); token.burn(to, burnAmount); } - function testFailTransferInsufficientBalance( + function testTransferInsufficientBalance( address to, uint256 mintAmount, uint256 sendAmount ) public { + if (mintAmount == type(uint256).max) mintAmount -= 1; sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max); token.mint(address(this), mintAmount); + vm.expectRevert(stdError.arithmeticError); token.transfer(to, sendAmount); } - function testFailTransferFromInsufficientAllowance( + function testTransferFromInsufficientAllowance( address to, uint256 approval, uint256 amount ) public { + if (approval == type(uint256).max) approval -= 1; amount = bound(amount, approval + 1, type(uint256).max); address from = address(0xABCD); token.mint(from, amount); - hevm.prank(from); + vm.prank(from); token.approve(address(this), approval); + vm.expectRevert(stdError.arithmeticError); token.transferFrom(from, to, amount); } - function testFailTransferFromInsufficientBalance( + function testTransferFromInsufficientBalance( address to, uint256 mintAmount, uint256 sendAmount ) public { + if (mintAmount == type(uint256).max) mintAmount -= 1; sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max); address from = address(0xABCD); token.mint(from, mintAmount); - hevm.prank(from); + vm.prank(from); token.approve(address(this), sendAmount); + vm.expectRevert(stdError.arithmeticError); token.transferFrom(from, to, sendAmount); } - function testFailPermitBadNonce( - uint256 privateKey, + function testPermitBadNonce( + uint128 privateKey, address to, uint256 amount, uint256 deadline, @@ -384,9 +437,9 @@ contract ERC20Test is DSTestPlus { if (privateKey == 0) privateKey = 1; if (nonce == 0) nonce = 1; - address owner = hevm.addr(privateKey); + address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( + (uint8 v, bytes32 r, bytes32 s) = vm.sign( privateKey, keccak256( abi.encodePacked( @@ -397,21 +450,23 @@ contract ERC20Test is DSTestPlus { ) ); + vm.expectRevert("INVALID_SIGNER"); token.permit(owner, to, amount, deadline, v, r, s); } - function testFailPermitBadDeadline( - uint256 privateKey, + function testPermitBadDeadline( + uint128 privateKey, address to, uint256 amount, uint256 deadline ) public { + if (deadline == type(uint256).max) deadline -= 1; if (deadline < block.timestamp) deadline = block.timestamp; if (privateKey == 0) privateKey = 1; - address owner = hevm.addr(privateKey); + address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( + (uint8 v, bytes32 r, bytes32 s) = vm.sign( privateKey, keccak256( abi.encodePacked( @@ -422,36 +477,44 @@ contract ERC20Test is DSTestPlus { ) ); + vm.expectRevert("INVALID_SIGNER"); token.permit(owner, to, amount, deadline + 1, v, r, s); } - function testFailPermitPastDeadline( - uint256 privateKey, + function testPermitPastDeadline( + uint128 privateKey, address to, uint256 amount, uint256 deadline ) public { - deadline = bound(deadline, 0, block.timestamp - 1); + if (deadline == type(uint256).max) deadline -= 1; + vm.warp(deadline); + + // private key cannot be 0 for secp256k1 pubkey generation if (privateKey == 0) privateKey = 1; - address owner = hevm.addr(privateKey); + address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( + bytes32 domain_separator = token.DOMAIN_SEPARATOR(); + (uint8 v, bytes32 r, bytes32 s) = vm.sign( privateKey, keccak256( abi.encodePacked( "\x19\x01", - token.DOMAIN_SEPARATOR(), + domain_separator, keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline)) ) ) ); + vm.warp(deadline + 1); + + vm.expectRevert("PERMIT_DEADLINE_EXPIRED"); token.permit(owner, to, amount, deadline, v, r, s); } - function testFailPermitReplay( - uint256 privateKey, + function testPermitReplay( + uint128 privateKey, address to, uint256 amount, uint256 deadline @@ -459,9 +522,9 @@ contract ERC20Test is DSTestPlus { if (deadline < block.timestamp) deadline = block.timestamp; if (privateKey == 0) privateKey = 1; - address owner = hevm.addr(privateKey); + address owner = vm.addr(privateKey); - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( + (uint8 v, bytes32 r, bytes32 s) = vm.sign( privateKey, keccak256( abi.encodePacked( @@ -473,11 +536,12 @@ contract ERC20Test is DSTestPlus { ); token.permit(owner, to, amount, deadline, v, r, s); + vm.expectRevert("INVALID_SIGNER"); token.permit(owner, to, amount, deadline, v, r, s); } } -contract ERC20Invariants is DSTestPlus, DSInvariantTest { +contract ERC20Invariants is TestPlus, DSInvariantTest { BalanceSum balanceSum; MockERC20 token; diff --git a/src/test/ERC4626.t.sol b/src/test/ERC4626.t.sol index 56a17527..727eb3e1 100644 --- a/src/test/ERC4626.t.sol +++ b/src/test/ERC4626.t.sol @@ -1,12 +1,13 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import "forge-std/Test.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {MockERC20} from "./utils/mocks/MockERC20.sol"; import {MockERC4626} from "./utils/mocks/MockERC4626.sol"; -contract ERC4626Test is DSTestPlus { +contract ERC4626Test is TestPlus { MockERC20 underlying; MockERC4626 vault; @@ -37,13 +38,13 @@ contract ERC4626Test is DSTestPlus { underlying.mint(alice, aliceUnderlyingAmount); - hevm.prank(alice); + vm.prank(alice); underlying.approve(address(vault), aliceUnderlyingAmount); assertEq(underlying.allowance(alice, address(vault)), aliceUnderlyingAmount); uint256 alicePreDepositBal = underlying.balanceOf(alice); - hevm.prank(alice); + vm.prank(alice); uint256 aliceShareAmount = vault.deposit(aliceUnderlyingAmount, alice); assertEq(vault.afterDepositHookCalledCounter(), 1); @@ -58,7 +59,7 @@ contract ERC4626Test is DSTestPlus { assertEq(vault.convertToAssets(vault.balanceOf(alice)), aliceUnderlyingAmount); assertEq(underlying.balanceOf(alice), alicePreDepositBal - aliceUnderlyingAmount); - hevm.prank(alice); + vm.prank(alice); vault.withdraw(aliceUnderlyingAmount, alice, alice); assertEq(vault.beforeWithdrawHookCalledCounter(), 1); @@ -78,13 +79,13 @@ contract ERC4626Test is DSTestPlus { underlying.mint(alice, aliceShareAmount); - hevm.prank(alice); + vm.prank(alice); underlying.approve(address(vault), aliceShareAmount); assertEq(underlying.allowance(alice, address(vault)), aliceShareAmount); uint256 alicePreDepositBal = underlying.balanceOf(alice); - hevm.prank(alice); + vm.prank(alice); uint256 aliceUnderlyingAmount = vault.mint(aliceShareAmount, alice); assertEq(vault.afterDepositHookCalledCounter(), 1); @@ -99,7 +100,7 @@ contract ERC4626Test is DSTestPlus { assertEq(vault.convertToAssets(vault.balanceOf(alice)), aliceUnderlyingAmount); assertEq(underlying.balanceOf(alice), alicePreDepositBal - aliceUnderlyingAmount); - hevm.prank(alice); + vm.prank(alice); vault.redeem(aliceShareAmount, alice, alice); assertEq(vault.beforeWithdrawHookCalledCounter(), 1); @@ -171,20 +172,20 @@ contract ERC4626Test is DSTestPlus { underlying.mint(alice, 4000); - hevm.prank(alice); + vm.prank(alice); underlying.approve(address(vault), 4000); assertEq(underlying.allowance(alice, address(vault)), 4000); underlying.mint(bob, 7001); - hevm.prank(bob); + vm.prank(bob); underlying.approve(address(vault), 7001); assertEq(underlying.allowance(bob, address(vault)), 7001); // 1. Alice mints 2000 shares (costs 2000 tokens) - hevm.prank(alice); + vm.prank(alice); uint256 aliceUnderlyingAmount = vault.mint(2000, alice); uint256 aliceShareAmount = vault.previewDeposit(aliceUnderlyingAmount); @@ -204,7 +205,7 @@ contract ERC4626Test is DSTestPlus { assertEq(vault.totalAssets(), aliceUnderlyingAmount); // 2. Bob deposits 4000 tokens (mints 4000 shares) - hevm.prank(bob); + vm.prank(bob); uint256 bobShareAmount = vault.deposit(4000, bob); uint256 bobUnderlyingAmount = vault.previewWithdraw(bobShareAmount); assertEq(vault.afterDepositHookCalledCounter(), 2); @@ -244,7 +245,7 @@ contract ERC4626Test is DSTestPlus { assertEq(vault.convertToAssets(vault.balanceOf(bob)), bobUnderlyingAmount + (mutationUnderlyingAmount / 3) * 2); // 4. Alice deposits 2000 tokens (mints 1333 shares) - hevm.prank(alice); + vm.prank(alice); vault.deposit(2000, alice); assertEq(vault.totalSupply(), 7333); @@ -256,7 +257,7 @@ contract ERC4626Test is DSTestPlus { // 5. Bob mints 2000 shares (costs 3001 assets) // NOTE: Bob's assets spent got rounded up // NOTE: Alices's vault assets got rounded up - hevm.prank(bob); + vm.prank(bob); vault.mint(2000, bob); assertEq(vault.totalSupply(), 9333); @@ -280,7 +281,7 @@ contract ERC4626Test is DSTestPlus { assertEq(vault.convertToAssets(vault.balanceOf(bob)), 10929); // 7. Alice redeem 1333 shares (2428 assets) - hevm.prank(alice); + vm.prank(alice); vault.redeem(1333, alice, alice); assertEq(underlying.balanceOf(alice), 2428); @@ -292,7 +293,7 @@ contract ERC4626Test is DSTestPlus { assertEq(vault.convertToAssets(vault.balanceOf(bob)), 10929); // 8. Bob withdraws 2929 assets (1608 shares) - hevm.prank(bob); + vm.prank(bob); vault.withdraw(2929, bob, bob); assertEq(underlying.balanceOf(bob), 2929); @@ -305,7 +306,7 @@ contract ERC4626Test is DSTestPlus { // 9. Alice withdraws 3643 assets (2000 shares) // NOTE: Bob's assets have been rounded back up - hevm.prank(alice); + vm.prank(alice); vault.withdraw(3643, alice, alice); assertEq(underlying.balanceOf(alice), 6071); @@ -317,7 +318,7 @@ contract ERC4626Test is DSTestPlus { assertEq(vault.convertToAssets(vault.balanceOf(bob)), 8001); // 10. Bob redeem 4392 shares (8001 tokens) - hevm.prank(bob); + vm.prank(bob); vault.redeem(4392, bob, bob); assertEq(underlying.balanceOf(bob), 10930); assertEq(vault.totalSupply(), 0); @@ -331,49 +332,57 @@ contract ERC4626Test is DSTestPlus { assertEq(underlying.balanceOf(address(vault)), 0); } - function testFailDepositWithNotEnoughApproval() public { + function testBadDepositWithNotEnoughApproval() public { underlying.mint(address(this), 0.5e18); underlying.approve(address(vault), 0.5e18); assertEq(underlying.allowance(address(this), address(vault)), 0.5e18); + vm.expectRevert("TRANSFER_FROM_FAILED"); vault.deposit(1e18, address(this)); } - function testFailWithdrawWithNotEnoughUnderlyingAmount() public { + function testBadWithdrawWithNotEnoughUnderlyingAmount() public { underlying.mint(address(this), 0.5e18); underlying.approve(address(vault), 0.5e18); vault.deposit(0.5e18, address(this)); + vm.expectRevert(stdError.arithmeticError); vault.withdraw(1e18, address(this), address(this)); } - function testFailRedeemWithNotEnoughShareAmount() public { + function testBadRedeemWithNotEnoughShareAmount() public { underlying.mint(address(this), 0.5e18); underlying.approve(address(vault), 0.5e18); vault.deposit(0.5e18, address(this)); + vm.expectRevert(stdError.arithmeticError); vault.redeem(1e18, address(this), address(this)); } - function testFailWithdrawWithNoUnderlyingAmount() public { + function testBadWithdrawWithNoUnderlyingAmount() public { + vm.expectRevert(stdError.arithmeticError); vault.withdraw(1e18, address(this), address(this)); } - function testFailRedeemWithNoShareAmount() public { + function testBadRedeemWithNoShareAmount() public { + vm.expectRevert(stdError.arithmeticError); vault.redeem(1e18, address(this), address(this)); } - function testFailDepositWithNoApproval() public { + function testBadDepositWithNoApproval() public { + vm.expectRevert("TRANSFER_FROM_FAILED"); vault.deposit(1e18, address(this)); } - function testFailMintWithNoApproval() public { + function testBadMintWithNoApproval() public { + vm.expectRevert("TRANSFER_FROM_FAILED"); vault.mint(1e18, address(this)); } - function testFailDepositZero() public { + function testBadDepositZero() public { + vm.expectRevert("ZERO_SHARES"); vault.deposit(0, address(this)); } @@ -386,7 +395,8 @@ contract ERC4626Test is DSTestPlus { assertEq(vault.totalAssets(), 0); } - function testFailRedeemZero() public { + function testBadRedeemZero() public { + vm.expectRevert("ZERO_ASSETS"); vault.redeem(0, address(this), address(this)); } @@ -406,14 +416,14 @@ contract ERC4626Test is DSTestPlus { underlying.mint(alice, 1e18); underlying.mint(bob, 1e18); - hevm.prank(alice); + vm.prank(alice); underlying.approve(address(vault), 1e18); - hevm.prank(bob); + vm.prank(bob); underlying.approve(address(vault), 1e18); // alice deposits 1e18 for bob - hevm.prank(alice); + vm.prank(alice); vault.deposit(1e18, bob); assertEq(vault.balanceOf(alice), 0); @@ -421,14 +431,14 @@ contract ERC4626Test is DSTestPlus { assertEq(underlying.balanceOf(alice), 0); // bob mint 1e18 for alice - hevm.prank(bob); + vm.prank(bob); vault.mint(1e18, alice); assertEq(vault.balanceOf(alice), 1e18); assertEq(vault.balanceOf(bob), 1e18); assertEq(underlying.balanceOf(bob), 0); // alice redeem 1e18 for bob - hevm.prank(alice); + vm.prank(alice); vault.redeem(1e18, bob, alice); assertEq(vault.balanceOf(alice), 0); @@ -436,7 +446,7 @@ contract ERC4626Test is DSTestPlus { assertEq(underlying.balanceOf(bob), 1e18); // bob withdraw 1e18 for alice - hevm.prank(bob); + vm.prank(bob); vault.withdraw(1e18, alice, bob); assertEq(vault.balanceOf(alice), 0); diff --git a/src/test/ERC721.t.sol b/src/test/ERC721.t.sol index b5b4b8a5..f299530f 100644 --- a/src/test/ERC721.t.sol +++ b/src/test/ERC721.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; import {MockERC721} from "./utils/mocks/MockERC721.sol"; @@ -53,7 +53,7 @@ contract WrongReturnDataERC721Recipient is ERC721TokenReceiver { contract NonERC721Recipient {} -contract ERC721Test is DSTestPlus { +contract ERC721Test is TestPlus { MockERC721 token; function setUp() public { @@ -78,7 +78,7 @@ contract ERC721Test is DSTestPlus { assertEq(token.balanceOf(address(0xBEEF)), 0); - hevm.expectRevert("NOT_MINTED"); + vm.expectRevert("NOT_MINTED"); token.ownerOf(1337); } @@ -100,7 +100,7 @@ contract ERC721Test is DSTestPlus { assertEq(token.balanceOf(address(this)), 0); assertEq(token.getApproved(1337), address(0)); - hevm.expectRevert("NOT_MINTED"); + vm.expectRevert("NOT_MINTED"); token.ownerOf(1337); } @@ -115,7 +115,7 @@ contract ERC721Test is DSTestPlus { token.mint(from, 1337); - hevm.prank(from); + vm.prank(from); token.approve(address(this), 1337); token.transferFrom(from, address(0xBEEF), 1337); @@ -142,7 +142,7 @@ contract ERC721Test is DSTestPlus { token.mint(from, 1337); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.transferFrom(from, address(0xBEEF), 1337); @@ -158,7 +158,7 @@ contract ERC721Test is DSTestPlus { token.mint(from, 1337); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeTransferFrom(from, address(0xBEEF), 1337); @@ -175,7 +175,7 @@ contract ERC721Test is DSTestPlus { token.mint(from, 1337); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeTransferFrom(from, address(recipient), 1337); @@ -197,7 +197,7 @@ contract ERC721Test is DSTestPlus { token.mint(from, 1337); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeTransferFrom(from, address(recipient), 1337, "testing 123"); @@ -248,123 +248,155 @@ contract ERC721Test is DSTestPlus { assertBytesEq(to.data(), "testing 123"); } - function testFailMintToZero() public { + function testMintToZero() public { + vm.expectRevert("INVALID_RECIPIENT"); token.mint(address(0), 1337); } - function testFailDoubleMint() public { + function testDoubleMint() public { token.mint(address(0xBEEF), 1337); + vm.expectRevert("ALREADY_MINTED"); token.mint(address(0xBEEF), 1337); } - function testFailBurnUnMinted() public { + function testBurnUnMinted() public { + vm.expectRevert("NOT_MINTED"); token.burn(1337); } - function testFailDoubleBurn() public { + function testDoubleBurn() public { token.mint(address(0xBEEF), 1337); token.burn(1337); + vm.expectRevert("NOT_MINTED"); token.burn(1337); } - function testFailApproveUnMinted() public { + function testApproveUnMinted() public { + vm.expectRevert("NOT_AUTHORIZED"); token.approve(address(0xBEEF), 1337); } - function testFailApproveUnAuthorized() public { + function testApproveUnAuthorized() public { token.mint(address(0xCAFE), 1337); + vm.expectRevert("NOT_AUTHORIZED"); token.approve(address(0xBEEF), 1337); } - function testFailTransferFromUnOwned() public { + function testTransferFromUnOwned() public { + vm.expectRevert("WRONG_FROM"); token.transferFrom(address(0xFEED), address(0xBEEF), 1337); } - function testFailTransferFromWrongFrom() public { + function testTransferFromWrongFrom() public { token.mint(address(0xCAFE), 1337); + vm.expectRevert("WRONG_FROM"); token.transferFrom(address(0xFEED), address(0xBEEF), 1337); } - function testFailTransferFromToZero() public { + function testTransferFromToZero() public { token.mint(address(this), 1337); + vm.expectRevert("INVALID_RECIPIENT"); token.transferFrom(address(this), address(0), 1337); } - function testFailTransferFromNotOwner() public { + function testTransferFromNotOwner() public { token.mint(address(0xFEED), 1337); + vm.expectRevert("NOT_AUTHORIZED"); token.transferFrom(address(0xFEED), address(0xBEEF), 1337); } - function testFailSafeTransferFromToNonERC721Recipient() public { + function testSafeTransferFromToNonERC721Recipient() public { token.mint(address(this), 1337); - token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337); + address recipient = address(new NonERC721Recipient()); + vm.expectRevert(); + token.safeTransferFrom(address(this), recipient, 1337); } - function testFailSafeTransferFromToNonERC721RecipientWithData() public { + function testSafeTransferFromToNonERC721RecipientWithData() public { token.mint(address(this), 1337); - token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337, "testing 123"); + address recipient = address(new NonERC721Recipient()); + vm.expectRevert(); + token.safeTransferFrom(address(this), recipient, 1337, "testing 123"); } function testFailSafeTransferFromToRevertingERC721Recipient() public { token.mint(address(this), 1337); - token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337); + address recipient = address(new RevertingERC721Recipient()); + token.safeTransferFrom(address(this), recipient, 1337); } function testFailSafeTransferFromToRevertingERC721RecipientWithData() public { token.mint(address(this), 1337); - token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337, "testing 123"); + address recipient = address(new RevertingERC721Recipient()); + token.safeTransferFrom(address(this), recipient, 1337, "testing 123"); } - function testFailSafeTransferFromToERC721RecipientWithWrongReturnData() public { + function testSafeTransferFromToERC721RecipientWithWrongReturnData() public { token.mint(address(this), 1337); - token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337); + address recipient = address(new WrongReturnDataERC721Recipient()); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeTransferFrom(address(this), recipient, 1337); } - function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() public { + function testSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() public { token.mint(address(this), 1337); - token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337, "testing 123"); + address recipient = address(new WrongReturnDataERC721Recipient()); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeTransferFrom(address(this), recipient, 1337, "testing 123"); } - function testFailSafeMintToNonERC721Recipient() public { - token.safeMint(address(new NonERC721Recipient()), 1337); + function testSafeMintToNonERC721Recipient() public { + address recipient = address(new NonERC721Recipient()); + vm.expectRevert(); + token.safeMint(recipient, 1337); } - function testFailSafeMintToNonERC721RecipientWithData() public { - token.safeMint(address(new NonERC721Recipient()), 1337, "testing 123"); + function testSafeMintToNonERC721RecipientWithData() public { + address recipient = address(new NonERC721Recipient()); + vm.expectRevert(); + token.safeMint(recipient, 1337, "testing 123"); } function testFailSafeMintToRevertingERC721Recipient() public { - token.safeMint(address(new RevertingERC721Recipient()), 1337); + address recipient = address(new RevertingERC721Recipient()); + token.safeMint(recipient, 1337); } function testFailSafeMintToRevertingERC721RecipientWithData() public { - token.safeMint(address(new RevertingERC721Recipient()), 1337, "testing 123"); + address recipient = address(new RevertingERC721Recipient()); + token.safeMint(recipient, 1337, "testing 123"); } - function testFailSafeMintToERC721RecipientWithWrongReturnData() public { - token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337); + function testSafeMintToERC721RecipientWithWrongReturnData() public { + address recipient = address(new WrongReturnDataERC721Recipient()); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeMint(recipient, 1337); } - function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() public { - token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337, "testing 123"); + function testSafeMintToERC721RecipientWithWrongReturnDataWithData() public { + address recipient = address(new WrongReturnDataERC721Recipient()); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeMint(recipient, 1337, "testing 123"); } - function testFailBalanceOfZeroAddress() public view { + function testBalanceOfZeroAddress() public { + vm.expectRevert("ZERO_ADDRESS"); token.balanceOf(address(0)); } - function testFailOwnerOfUnminted() public view { + function testOwnerOfUnminted() public { + vm.expectRevert("NOT_MINTED"); token.ownerOf(1337); } @@ -392,7 +424,7 @@ contract ERC721Test is DSTestPlus { assertEq(token.balanceOf(to), 0); - hevm.expectRevert("NOT_MINTED"); + vm.expectRevert("NOT_MINTED"); token.ownerOf(id); } @@ -416,7 +448,7 @@ contract ERC721Test is DSTestPlus { assertEq(token.balanceOf(address(this)), 0); assertEq(token.getApproved(id), address(0)); - hevm.expectRevert("NOT_MINTED"); + vm.expectRevert("NOT_MINTED"); token.ownerOf(id); } @@ -428,12 +460,11 @@ contract ERC721Test is DSTestPlus { function testTransferFrom(uint256 id, address to) public { address from = address(0xABCD); - if (to == address(0) || to == from) to = address(0xBEEF); token.mint(from, id); - hevm.prank(from); + vm.prank(from); token.approve(address(this), id); token.transferFrom(from, to, id); @@ -458,13 +489,12 @@ contract ERC721Test is DSTestPlus { } function testTransferFromApproveAll(uint256 id, address to) public { - if (to == address(0) || to == address(this)) to = address(0xBEEF); - address from = address(0xABCD); + if (to == address(0) || to == address(this) || to == from) to = address(0xBEEF); token.mint(from, id); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.transferFrom(from, to, id); @@ -477,14 +507,14 @@ contract ERC721Test is DSTestPlus { function testSafeTransferFromToEOA(uint256 id, address to) public { address from = address(0xABCD); + if (to == address(0) || to == address(this) || to == from) to = address(0xBEEF); - if (to == address(0) || to == address(this)) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; + vm.assume(uint256(uint160(to)) > 18); + vm.assume(to.code.length == 0); token.mint(from, id); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeTransferFrom(from, to, id); @@ -501,7 +531,7 @@ contract ERC721Test is DSTestPlus { token.mint(from, id); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeTransferFrom(from, address(recipient), id); @@ -523,7 +553,7 @@ contract ERC721Test is DSTestPlus { token.mint(from, id); - hevm.prank(from); + vm.prank(from); token.setApprovalForAll(address(this), true); token.safeTransferFrom(from, address(recipient), id, data); @@ -542,7 +572,8 @@ contract ERC721Test is DSTestPlus { function testSafeMintToEOA(uint256 id, address to) public { if (to == address(0)) to = address(0xBEEF); - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; + vm.assume(uint256(uint160(to)) > 18); + vm.assume(to.code.length == 0); token.safeMint(to, id); @@ -578,35 +609,40 @@ contract ERC721Test is DSTestPlus { assertBytesEq(to.data(), data); } - function testFailMintToZero(uint256 id) public { + function testMintToZero(uint256 id) public { + vm.expectRevert("INVALID_RECIPIENT"); token.mint(address(0), id); } - function testFailDoubleMint(uint256 id, address to) public { + function testDoubleMint(uint256 id, address to) public { if (to == address(0)) to = address(0xBEEF); token.mint(to, id); + vm.expectRevert("ALREADY_MINTED"); token.mint(to, id); } - function testFailBurnUnMinted(uint256 id) public { + function testBurnUnMinted(uint256 id) public { + vm.expectRevert("NOT_MINTED"); token.burn(id); } - function testFailDoubleBurn(uint256 id, address to) public { + function testDoubleBurn(uint256 id, address to) public { if (to == address(0)) to = address(0xBEEF); token.mint(to, id); token.burn(id); + vm.expectRevert("NOT_MINTED"); token.burn(id); } - function testFailApproveUnMinted(uint256 id, address to) public { + function testApproveUnMinted(uint256 id, address to) public { + vm.expectRevert("NOT_AUTHORIZED"); token.approve(to, id); } - function testFailApproveUnAuthorized( + function testApproveUnAuthorized( address owner, uint256 id, address to @@ -615,112 +651,143 @@ contract ERC721Test is DSTestPlus { token.mint(owner, id); + vm.expectRevert("NOT_AUTHORIZED"); token.approve(to, id); } - function testFailTransferFromUnOwned( + function testTransferFromUnOwned( address from, address to, uint256 id ) public { + if (to == address(0)) to = address(0xDEAD); + if (from == address(0) || from == to) from = address(0xBEEF); + vm.expectRevert("WRONG_FROM"); token.transferFrom(from, to, id); } - function testFailTransferFromWrongFrom( + function testTransferFromWrongFrom( address owner, address from, address to, uint256 id ) public { - if (owner == address(0)) to = address(0xBEEF); - if (from == owner) revert(); + if (to == address(0)) to = address(0xBEEF); + if (from == address(0)) from = address(0xDEAD); + if (owner == address(0)) owner = address(0xDEAF); + + vm.assume(from != to); + vm.assume(from != owner); token.mint(owner, id); + vm.expectRevert("WRONG_FROM"); token.transferFrom(from, to, id); } - function testFailTransferFromToZero(uint256 id) public { + function testTransferFromToZero(uint256 id) public { token.mint(address(this), id); + vm.expectRevert("INVALID_RECIPIENT"); token.transferFrom(address(this), address(0), id); } - function testFailTransferFromNotOwner( + function testTransferFromNotOwner( address from, address to, uint256 id ) public { - if (from == address(this)) from = address(0xBEEF); + if (from == address(this) || from == address(0)) from = address(0xBEEF); + if (to == address(0) || to == from) to = address(0xDEAF); token.mint(from, id); + vm.expectRevert("NOT_AUTHORIZED"); token.transferFrom(from, to, id); } - function testFailSafeTransferFromToNonERC721Recipient(uint256 id) public { + function testSafeTransferFromToNonERC721Recipient(uint256 id) public { token.mint(address(this), id); + address recipient = address(new NonERC721Recipient()); - token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id); + vm.expectRevert(); + token.safeTransferFrom(address(this), recipient, id); } - function testFailSafeTransferFromToNonERC721RecipientWithData(uint256 id, bytes calldata data) public { + function testSafeTransferFromToNonERC721RecipientWithData(uint256 id, bytes calldata data) public { token.mint(address(this), id); + address recipient = address(new NonERC721Recipient()); - token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id, data); + vm.expectRevert(); + token.safeTransferFrom(address(this), recipient, id, data); } function testFailSafeTransferFromToRevertingERC721Recipient(uint256 id) public { token.mint(address(this), id); + address recipient = address(new RevertingERC721Recipient()); - token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id); + token.safeTransferFrom(address(this), recipient, id); } function testFailSafeTransferFromToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public { token.mint(address(this), id); + address recipient = address(new RevertingERC721Recipient()); - token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id, data); + token.safeTransferFrom(address(this), recipient, id, data); } - function testFailSafeTransferFromToERC721RecipientWithWrongReturnData(uint256 id) public { + function testSafeTransferFromToERC721RecipientWithWrongReturnData(uint256 id) public { token.mint(address(this), id); + address recipient = address(new WrongReturnDataERC721Recipient()); - token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeTransferFrom(address(this), recipient, id); } - function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data) - public - { + function testSafeTransferFromToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data) public { token.mint(address(this), id); + address recipient = address(new WrongReturnDataERC721Recipient()); - token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id, data); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeTransferFrom(address(this), recipient, id, data); } - function testFailSafeMintToNonERC721Recipient(uint256 id) public { - token.safeMint(address(new NonERC721Recipient()), id); + function testSafeMintToNonERC721Recipient(uint256 id) public { + address recipient = address(new NonERC721Recipient()); + vm.expectRevert(); + token.safeMint(recipient, id); } - function testFailSafeMintToNonERC721RecipientWithData(uint256 id, bytes calldata data) public { - token.safeMint(address(new NonERC721Recipient()), id, data); + function testSafeMintToNonERC721RecipientWithData(uint256 id, bytes calldata data) public { + address recipient = address(new NonERC721Recipient()); + vm.expectRevert(); + token.safeMint(recipient, id, data); } function testFailSafeMintToRevertingERC721Recipient(uint256 id) public { - token.safeMint(address(new RevertingERC721Recipient()), id); + address recipient = address(new RevertingERC721Recipient()); + token.safeMint(recipient, id); } function testFailSafeMintToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public { - token.safeMint(address(new RevertingERC721Recipient()), id, data); + address recipient = address(new RevertingERC721Recipient()); + token.safeMint(recipient, id, data); } - function testFailSafeMintToERC721RecipientWithWrongReturnData(uint256 id) public { - token.safeMint(address(new WrongReturnDataERC721Recipient()), id); + function testSafeMintToERC721RecipientWithWrongReturnData(uint256 id) public { + address recipient = address(new WrongReturnDataERC721Recipient()); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeMint(recipient, id); } - function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data) public { - token.safeMint(address(new WrongReturnDataERC721Recipient()), id, data); + function testSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data) public { + address recipient = address(new WrongReturnDataERC721Recipient()); + vm.expectRevert("UNSAFE_RECIPIENT"); + token.safeMint(recipient, id, data); } - function testFailOwnerOfUnminted(uint256 id) public view { + function testOwnerOfUnminted(uint256 id) public { + vm.expectRevert("NOT_MINTED"); token.ownerOf(id); } } diff --git a/src/test/FixedPointMathLib.t.sol b/src/test/FixedPointMathLib.t.sol index 7d5fbcab..a63545ee 100644 --- a/src/test/FixedPointMathLib.t.sol +++ b/src/test/FixedPointMathLib.t.sol @@ -1,11 +1,13 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import "forge-std/Test.sol"; + +import {TestPlus} from "./utils/TestPlus.sol"; import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol"; -contract FixedPointMathLibTest is DSTestPlus { +contract FixedPointMathLibTest is TestPlus { function testMulWadDown() public { assertEq(FixedPointMathLib.mulWadDown(2.5e18, 0.5e18), 1.25e18); assertEq(FixedPointMathLib.mulWadDown(3e18, 1e18), 3e18); @@ -40,7 +42,8 @@ contract FixedPointMathLibTest is DSTestPlus { assertEq(FixedPointMathLib.divWadDown(0, 1e18), 0); } - function testFailDivWadDownZeroDenominator() public pure { + function testDivWadDownZeroDenominator() public { + vm.expectRevert(); FixedPointMathLib.divWadDown(1e18, 0); } @@ -54,7 +57,8 @@ contract FixedPointMathLibTest is DSTestPlus { assertEq(FixedPointMathLib.divWadUp(0, 1e18), 0); } - function testFailDivWadUpZeroDenominator() public pure { + function testDivWadUpZeroDenominator() public { + vm.expectRevert(); FixedPointMathLib.divWadUp(1e18, 0); } @@ -79,7 +83,8 @@ contract FixedPointMathLibTest is DSTestPlus { assertEq(FixedPointMathLib.mulDivDown(0, 0, 1e18), 0); } - function testFailMulDivDownZeroDenominator() public pure { + function testMulDivDownZeroDenominator() public { + vm.expectRevert(); FixedPointMathLib.mulDivDown(1e18, 1e18, 0); } @@ -104,7 +109,8 @@ contract FixedPointMathLibTest is DSTestPlus { assertEq(FixedPointMathLib.mulDivUp(0, 0, 1e18), 0); } - function testFailMulDivUpZeroDenominator() public pure { + function testMulDivUpZeroDenominator() public { + vm.expectRevert(); FixedPointMathLib.mulDivUp(1e18, 1e18, 0); } @@ -132,12 +138,16 @@ contract FixedPointMathLibTest is DSTestPlus { assertEq(FixedPointMathLib.mulWadDown(x, y), (x * y) / 1e18); } - function testFailMulWadDownOverflow(uint256 x, uint256 y) public pure { + function testMulWadDownOverflow(uint256 x, uint256 y) public { + // x shouldn't be zero. + vm.assume(x != 0); + // Ignore cases where x * y does not overflow. unchecked { - if ((x * y) / x == y) revert(); + if ((x * y) / x == y) return; } + vm.expectRevert(); FixedPointMathLib.mulWadDown(x, y); } @@ -150,56 +160,76 @@ contract FixedPointMathLibTest is DSTestPlus { assertEq(FixedPointMathLib.mulWadUp(x, y), x * y == 0 ? 0 : (x * y - 1) / 1e18 + 1); } - function testFailMulWadUpOverflow(uint256 x, uint256 y) public pure { + function testMulWadUpOverflow(uint256 x, uint256 y) public { + // x shouldn't be zero. + vm.assume(x != 0); + // Ignore cases where x * y does not overflow. unchecked { - if ((x * y) / x == y) revert(); + if ((x * y) / x == y) return; } + vm.expectRevert(); FixedPointMathLib.mulWadUp(x, y); } function testDivWadDown(uint256 x, uint256 y) public { - // Ignore cases where x * WAD overflows or y is 0. + // The denominator should not be 0 (tested below). + vm.assume(y != 0); + + // Ignore cases where x * WAD overflows. unchecked { - if (y == 0 || (x != 0 && (x * 1e18) / 1e18 != x)) return; + if (x != 0 && (x * 1e18) / 1e18 != x) return; } assertEq(FixedPointMathLib.divWadDown(x, y), (x * 1e18) / y); } - function testFailDivWadDownOverflow(uint256 x, uint256 y) public pure { - // Ignore cases where x * WAD does not overflow or y is 0. + function testDivWadDownOverflow(uint256 x, uint256 y) public { + // The denominator should not be 0 (tested below). + vm.assume(y != 0); + + // Ignore cases where x * WAD does not overflow. unchecked { - if (y == 0 || (x * 1e18) / 1e18 == x) revert(); + if ((x * 1e18) / 1e18 == x) return; } + vm.expectRevert(); FixedPointMathLib.divWadDown(x, y); } - function testFailDivWadDownZeroDenominator(uint256 x) public pure { + function testDivWadDownZeroDenominator(uint256 x) public { + vm.expectRevert(); FixedPointMathLib.divWadDown(x, 0); } function testDivWadUp(uint256 x, uint256 y) public { - // Ignore cases where x * WAD overflows or y is 0. + // The denominator should not be 0 (tested below). + vm.assume(y != 0); + + // Ignore cases where x * WAD overflows. unchecked { - if (y == 0 || (x != 0 && (x * 1e18) / 1e18 != x)) return; + if (x != 0 && (x * 1e18) / 1e18 != x) return; } assertEq(FixedPointMathLib.divWadUp(x, y), x == 0 ? 0 : (x * 1e18 - 1) / y + 1); } - function testFailDivWadUpOverflow(uint256 x, uint256 y) public pure { - // Ignore cases where x * WAD does not overflow or y is 0. + function testDivWadUpOverflow(uint256 x, uint256 y) public { + // The denominator should not be 0 (tested below). + vm.assume(y != 0); + + // Ignore cases where x * WAD does not overflow. unchecked { - if (y == 0 || (x * 1e18) / 1e18 == x) revert(); + if ((x * 1e18) / 1e18 == x) return; } + vm.expectRevert(); FixedPointMathLib.divWadUp(x, y); } - function testFailDivWadUpZeroDenominator(uint256 x) public pure { + function testDivWadUpZeroDenominator(uint256 x) public { + vm.expectRevert(); FixedPointMathLib.divWadUp(x, 0); } @@ -208,28 +238,36 @@ contract FixedPointMathLibTest is DSTestPlus { uint256 y, uint256 denominator ) public { - // Ignore cases where x * y overflows or denominator is 0. + // The denominator should not be 0 (tested below). + vm.assume(denominator != 0); + + // Ignore cases where x * y overflows (tested below). unchecked { - if (denominator == 0 || (x != 0 && (x * y) / x != y)) return; + if (x != 0 && (x * y) / x != y) return; } assertEq(FixedPointMathLib.mulDivDown(x, y, denominator), (x * y) / denominator); } - function testFailMulDivDownOverflow( + function testMulDivDownOverflow( uint256 x, uint256 y, uint256 denominator - ) public pure { - // Ignore cases where x * y does not overflow or denominator is 0. + ) public { + // The denominator should not be 0 (tested below). + vm.assume(denominator != 0); + + // Ignore cases where x * y does not overflow. unchecked { - if (denominator == 0 || (x * y) / x == y) revert(); + if (x == 0 || (x * y) / x == y) return; } + vm.expectRevert(); FixedPointMathLib.mulDivDown(x, y, denominator); } - function testFailMulDivDownZeroDenominator(uint256 x, uint256 y) public pure { + function testMulDivDownZeroDenominator(uint256 x, uint256 y) public { + vm.expectRevert(); FixedPointMathLib.mulDivDown(x, y, 0); } @@ -238,28 +276,36 @@ contract FixedPointMathLibTest is DSTestPlus { uint256 y, uint256 denominator ) public { - // Ignore cases where x * y overflows or denominator is 0. + // The denominator should not be 0 (tested below). + vm.assume(denominator != 0); + + // Ignore cases where x * y overflows (tested below). unchecked { - if (denominator == 0 || (x != 0 && (x * y) / x != y)) return; + if (x != 0 && (x * y) / x != y) return; } assertEq(FixedPointMathLib.mulDivUp(x, y, denominator), x * y == 0 ? 0 : (x * y - 1) / denominator + 1); } - function testFailMulDivUpOverflow( + function testMulDivUpOverflow( uint256 x, uint256 y, uint256 denominator - ) public pure { - // Ignore cases where x * y does not overflow or denominator is 0. + ) public { + // The denominator should not be 0 (tested below). + vm.assume(denominator != 0); + + // Ignore cases where x * y does not overflow. unchecked { - if (denominator == 0 || (x * y) / x == y) revert(); + if (x == 0 || (x * y) / x == y) return; } + vm.expectRevert(); FixedPointMathLib.mulDivUp(x, y, denominator); } - function testFailMulDivUpZeroDenominator(uint256 x, uint256 y) public pure { + function testMulDivUpZeroDenominator(uint256 x, uint256 y) public { + vm.expectRevert(); FixedPointMathLib.mulDivUp(x, y, 0); } diff --git a/src/test/MultiRolesAuthority.t.sol b/src/test/MultiRolesAuthority.t.sol index 85308875..bc22f3f7 100644 --- a/src/test/MultiRolesAuthority.t.sol +++ b/src/test/MultiRolesAuthority.t.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {MockAuthority} from "./utils/mocks/MockAuthority.sol"; import {Authority} from "../auth/Auth.sol"; import {MultiRolesAuthority} from "../auth/authorities/MultiRolesAuthority.sol"; -contract MultiRolesAuthorityTest is DSTestPlus { +contract MultiRolesAuthorityTest is TestPlus { MultiRolesAuthority multiRolesAuthority; function setUp() public { diff --git a/src/test/ReentrancyGuard.t.sol b/src/test/ReentrancyGuard.t.sol index eb8a36cc..2e118107 100644 --- a/src/test/ReentrancyGuard.t.sol +++ b/src/test/ReentrancyGuard.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {ReentrancyGuard} from "../utils/ReentrancyGuard.sol"; @@ -27,7 +27,7 @@ contract RiskyContract is ReentrancyGuard { function overprotectedCall() public nonReentrant {} } -contract ReentrancyGuardTest is DSTestPlus { +contract ReentrancyGuardTest is TestPlus { RiskyContract riskyContract; function setUp() public { @@ -35,19 +35,18 @@ contract ReentrancyGuardTest is DSTestPlus { } function invariantReentrancyStatusAlways1() public { - assertEq(uint256(hevm.load(address(riskyContract), 0)), 1); + assertEq(uint256(vm.load(address(riskyContract), 0)), 1); } - function testFailUnprotectedCall() public { + function testUnprotectedCall() public { riskyContract.unprotectedCall(); - assertEq(riskyContract.enterTimes(), 1); + assertEq(riskyContract.enterTimes(), 2); } function testProtectedCall() public { - try riskyContract.protectedCall() { - fail("Reentrancy Guard Failed To Stop Attacker"); - } catch {} + vm.expectRevert("REENTRANCY"); + riskyContract.protectedCall(); } function testNoReentrancy() public { diff --git a/src/test/RolesAuthority.t.sol b/src/test/RolesAuthority.t.sol index 88c43fcc..05668366 100644 --- a/src/test/RolesAuthority.t.sol +++ b/src/test/RolesAuthority.t.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {MockAuthority} from "./utils/mocks/MockAuthority.sol"; import {Authority} from "../auth/Auth.sol"; import {RolesAuthority} from "../auth/authorities/RolesAuthority.sol"; -contract RolesAuthorityTest is DSTestPlus { +contract RolesAuthorityTest is TestPlus { RolesAuthority rolesAuthority; function setUp() public { diff --git a/src/test/SSTORE2.t.sol b/src/test/SSTORE2.t.sol index fe7e5e32..954558da 100644 --- a/src/test/SSTORE2.t.sol +++ b/src/test/SSTORE2.t.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import "forge-std/Test.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {SSTORE2} from "../utils/SSTORE2.sol"; -contract SSTORE2Test is DSTestPlus { +contract SSTORE2Test is TestPlus { function testWriteRead() public { bytes memory testBytes = abi.encode("this is a test"); @@ -36,28 +37,38 @@ contract SSTORE2Test is DSTestPlus { SSTORE2.read(SSTORE2.write(hex"11223344"), 3, 3); } - function testFailReadInvalidPointer() public view { + function testReadInvalidPointer() public { + vm.expectRevert(stdError.arithmeticError); SSTORE2.read(DEAD_ADDRESS); } - function testFailReadInvalidPointerCustomStartBound() public view { + function testReadInvalidPointerCustomStartBound() public { + vm.expectRevert(stdError.arithmeticError); SSTORE2.read(DEAD_ADDRESS, 1); } - function testFailReadInvalidPointerCustomBounds() public view { + function testReadInvalidPointerCustomBounds() public { + vm.expectRevert("OUT_OF_BOUNDS"); SSTORE2.read(DEAD_ADDRESS, 2, 4); } - function testFailWriteReadOutOfStartBound() public { - SSTORE2.read(SSTORE2.write(hex"11223344"), 41000); + function testWriteReadOutOfStartBound() public { + address pointer = SSTORE2.write(hex"11223344"); + vm.expectRevert(stdError.arithmeticError); + SSTORE2.read(pointer, 41000); } - function testFailWriteReadEmptyOutOfBounds() public { - SSTORE2.read(SSTORE2.write(hex"11223344"), 42000, 42000); + function testWriteReadEmptyOutOfBounds() public { + address pointer = SSTORE2.write(hex"11223344"); + vm.expectRevert("OUT_OF_BOUNDS"); + SSTORE2.read(pointer, 42000, 42000); } - function testFailWriteReadOutOfBounds() public { - SSTORE2.read(SSTORE2.write(hex"11223344"), 41000, 42000); + function testWriteReadOutOfBounds() public { + address pointer = SSTORE2.write(hex"11223344"); + vm.assume(pointer.code.length != 0); + vm.expectRevert("OUT_OF_BOUNDS"); + SSTORE2.read(pointer, 41000, 42000); } function testWriteRead(bytes calldata testBytes) public { @@ -65,7 +76,7 @@ contract SSTORE2Test is DSTestPlus { } function testWriteReadCustomStartBound(bytes calldata testBytes, uint256 startIndex) public { - if (testBytes.length == 0) return; + vm.assume(testBytes.length != 0); startIndex = bound(startIndex, 0, testBytes.length); @@ -77,12 +88,12 @@ contract SSTORE2Test is DSTestPlus { uint256 startIndex, uint256 endIndex ) public { - if (testBytes.length == 0) return; + vm.assume(testBytes.length != 0); endIndex = bound(endIndex, 0, testBytes.length); startIndex = bound(startIndex, 0, testBytes.length); - if (startIndex > endIndex) return; + if (startIndex > endIndex) (startIndex, endIndex) = (endIndex, startIndex); assertBytesEq( SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex), @@ -90,41 +101,54 @@ contract SSTORE2Test is DSTestPlus { ); } - function testFailReadInvalidPointer(address pointer) public view { - if (pointer.code.length > 0) revert(); + function testReadInvalidPointer(address pointer) public { + vm.assume(pointer.code.length == 0); + vm.expectRevert(stdError.arithmeticError); SSTORE2.read(pointer); } - function testFailReadInvalidPointerCustomStartBound(address pointer, uint256 startIndex) public view { - if (pointer.code.length > 0) revert(); + function testReadInvalidPointerCustomStartBound(address pointer, uint256 startIndex) public { + vm.assume(pointer.code.length == 0); + vm.expectRevert(stdError.arithmeticError); SSTORE2.read(pointer, startIndex); } - function testFailReadInvalidPointerCustomBounds( + function testReadInvalidPointerCustomBounds( address pointer, uint256 startIndex, uint256 endIndex - ) public view { - if (pointer.code.length > 0) revert(); + ) public { + startIndex = bound(startIndex, pointer.code.length, type(uint256).max - 1); + endIndex = bound(endIndex, pointer.code.length, type(uint256).max - 1); + if (startIndex > endIndex) (startIndex, endIndex) = (endIndex, startIndex); + vm.expectRevert("OUT_OF_BOUNDS"); SSTORE2.read(pointer, startIndex, endIndex); } - function testFailWriteReadCustomStartBoundOutOfRange(bytes calldata testBytes, uint256 startIndex) public { - startIndex = bound(startIndex, testBytes.length + 1, type(uint256).max); + function testWriteReadCustomStartBoundOutOfRange(bytes calldata testBytes, uint256 startIndex) public { + vm.assume(testBytes.length != 0); + startIndex = bound(startIndex, testBytes.length + 1, type(uint256).max - 1); - SSTORE2.read(SSTORE2.write(testBytes), startIndex); + address pointer = SSTORE2.write(testBytes); + vm.expectRevert(stdError.arithmeticError); + SSTORE2.read(pointer, startIndex); } - function testFailWriteReadCustomBoundsOutOfRange( + function testWriteReadCustomBoundsOutOfRange( bytes calldata testBytes, uint256 startIndex, uint256 endIndex ) public { - endIndex = bound(endIndex, testBytes.length + 1, type(uint256).max); + vm.assume(testBytes.length != 0); + endIndex = bound(endIndex, testBytes.length + 1, type(uint256).max - 1); + startIndex = bound(startIndex, testBytes.length + 1, type(uint256).max - 1); + if (startIndex > endIndex) (startIndex, endIndex) = (endIndex, startIndex); - SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex); + address pointer = SSTORE2.write(testBytes); + vm.expectRevert("OUT_OF_BOUNDS"); + SSTORE2.read(pointer, startIndex, endIndex); } } diff --git a/src/test/SafeCastLib.t.sol b/src/test/SafeCastLib.t.sol index 48a2a76f..9e293578 100644 --- a/src/test/SafeCastLib.t.sol +++ b/src/test/SafeCastLib.t.sol @@ -1,11 +1,13 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import "forge-std/Test.sol"; + +import {TestPlus} from "./utils/TestPlus.sol"; import {SafeCastLib} from "../utils/SafeCastLib.sol"; -contract SafeCastLibTest is DSTestPlus { +contract SafeCastLibTest is TestPlus { function testSafeCastTo248() public { assertEq(SafeCastLib.safeCastTo248(2.5e45), 2.5e45); assertEq(SafeCastLib.safeCastTo248(2.5e27), 2.5e27); @@ -51,39 +53,48 @@ contract SafeCastLibTest is DSTestPlus { assertEq(SafeCastLib.safeCastTo8(250), 250); } - function testFailSafeCastTo248() public pure { + function testBadSafeCastTo248() public { + vm.expectRevert(stdError.arithmeticError); SafeCastLib.safeCastTo248(type(uint248).max + 1); } - function testFailSafeCastTo224() public pure { + function testBadSafeCastTo224() public { + vm.expectRevert(stdError.arithmeticError); SafeCastLib.safeCastTo224(type(uint224).max + 1); } - function testFailSafeCastTo192() public pure { + function testBadSafeCastTo192() public { + vm.expectRevert(stdError.arithmeticError); SafeCastLib.safeCastTo192(type(uint192).max + 1); } - function testFailSafeCastTo160() public pure { + function testBadSafeCastTo160() public { + vm.expectRevert(stdError.arithmeticError); SafeCastLib.safeCastTo160(type(uint160).max + 1); } - function testFailSafeCastTo128() public pure { + function testBadSafeCastTo128() public { + vm.expectRevert(stdError.arithmeticError); SafeCastLib.safeCastTo128(type(uint128).max + 1); } - function testFailSafeCastTo96() public pure { + function testBadSafeCastTo96() public { + vm.expectRevert(stdError.arithmeticError); SafeCastLib.safeCastTo96(type(uint96).max + 1); } - function testFailSafeCastTo64() public pure { + function testBadSafeCastTo64() public { + vm.expectRevert(stdError.arithmeticError); SafeCastLib.safeCastTo64(type(uint64).max + 1); } - function testFailSafeCastTo32() public pure { + function testBadSafeCastTo32() public { + vm.expectRevert(stdError.arithmeticError); SafeCastLib.safeCastTo32(type(uint32).max + 1); } - function testFailSafeCastTo8() public pure { + function testBadSafeCastTo8() public { + vm.expectRevert(stdError.arithmeticError); SafeCastLib.safeCastTo8(type(uint8).max + 1); } @@ -141,57 +152,66 @@ contract SafeCastLibTest is DSTestPlus { assertEq(SafeCastLib.safeCastTo8(x), x); } - function testFailSafeCastTo248(uint256 x) public { - x = bound(x, type(uint248).max + 1, type(uint256).max); + function testBadSafeCastTo248(uint256 x) public { + x = bound(x, uint256(type(uint248).max) + 1, type(uint256).max); + vm.expectRevert(); SafeCastLib.safeCastTo248(x); } - function testFailSafeCastTo224(uint256 x) public { - x = bound(x, type(uint224).max + 1, type(uint256).max); + function testBadSafeCastTo224(uint256 x) public { + x = bound(x, uint256(type(uint224).max) + 1, type(uint256).max); + vm.expectRevert(); SafeCastLib.safeCastTo224(x); } - function testFailSafeCastTo192(uint256 x) public { - x = bound(x, type(uint192).max + 1, type(uint256).max); + function testBadSafeCastTo192(uint256 x) public { + x = bound(x, uint256(type(uint192).max) + 1, type(uint256).max); + vm.expectRevert(); SafeCastLib.safeCastTo192(x); } - function testFailSafeCastTo160(uint256 x) public { - x = bound(x, type(uint160).max + 1, type(uint256).max); + function testBadSafeCastTo160(uint256 x) public { + x = bound(x, uint256(type(uint160).max) + 1, type(uint256).max); + vm.expectRevert(); SafeCastLib.safeCastTo160(x); } - function testFailSafeCastTo128(uint256 x) public { - x = bound(x, type(uint128).max + 1, type(uint256).max); + function testBadSafeCastTo128(uint256 x) public { + x = bound(x, uint256(type(uint128).max) + 1, type(uint256).max); + vm.expectRevert(); SafeCastLib.safeCastTo128(x); } - function testFailSafeCastTo96(uint256 x) public { - x = bound(x, type(uint96).max + 1, type(uint256).max); + function testBadSafeCastTo96(uint256 x) public { + x = bound(x, uint256(type(uint96).max) + 1, type(uint256).max); + vm.expectRevert(); SafeCastLib.safeCastTo96(x); } - function testFailSafeCastTo64(uint256 x) public { - x = bound(x, type(uint64).max + 1, type(uint256).max); + function testBadSafeCastTo64(uint256 x) public { + x = bound(x, uint256(type(uint64).max) + 1, type(uint256).max); + vm.expectRevert(); SafeCastLib.safeCastTo64(x); } - function testFailSafeCastTo32(uint256 x) public { - x = bound(x, type(uint32).max + 1, type(uint256).max); + function testBadSafeCastTo32(uint256 x) public { + x = bound(x, uint256(type(uint32).max) + 1, type(uint256).max); + vm.expectRevert(); SafeCastLib.safeCastTo32(x); } - function testFailSafeCastTo8(uint256 x) public { - x = bound(x, type(uint8).max + 1, type(uint256).max); + function testBadSafeCastTo8(uint256 x) public { + x = bound(x, uint256(type(uint8).max) + 1, type(uint256).max); + vm.expectRevert(); SafeCastLib.safeCastTo8(x); } } diff --git a/src/test/SafeTransferLib.t.sol b/src/test/SafeTransferLib.t.sol index 70fe051d..6c63a464 100644 --- a/src/test/SafeTransferLib.t.sol +++ b/src/test/SafeTransferLib.t.sol @@ -10,12 +10,12 @@ import {ReturnsTooMuchToken} from "./utils/weird-tokens/ReturnsTooMuchToken.sol" import {ReturnsGarbageToken} from "./utils/weird-tokens/ReturnsGarbageToken.sol"; import {ReturnsTooLittleToken} from "./utils/weird-tokens/ReturnsTooLittleToken.sol"; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {ERC20} from "../tokens/ERC20.sol"; import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; -contract SafeTransferLibTest is DSTestPlus { +contract SafeTransferLibTest is TestPlus { RevertingToken reverting; ReturnsTwoToken returnsTwo; ReturnsFalseToken returnsFalse; @@ -520,7 +520,7 @@ contract SafeTransferLibTest is DSTestPlus { ) internal { uint256 slot = token == address(erc20) ? 4 : 2; // Standard ERC20 name and symbol aren't constant. - hevm.store( + vm.store( token, keccak256(abi.encode(to, keccak256(abi.encode(from, uint256(slot))))), bytes32(uint256(amount)) diff --git a/src/test/DSTestPlus.t.sol b/src/test/TestPlus.t.sol similarity index 80% rename from src/test/DSTestPlus.t.sol rename to src/test/TestPlus.t.sol index 5e08f7e8..9c2f2173 100644 --- a/src/test/DSTestPlus.t.sol +++ b/src/test/TestPlus.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; -contract DSTestPlusTest is DSTestPlus { +contract TestPlusTest is TestPlus { function testBound() public { assertEq(bound(5, 0, 4), 0); assertEq(bound(0, 69, 69), 69); @@ -13,7 +13,8 @@ contract DSTestPlusTest is DSTestPlus { assertEq(bound(9999, 1337, 6666), 4669); } - function testFailBoundMinBiggerThanMax() public { + function testBoundMinBiggerThanMax() public { + vm.expectRevert("MAX_LESS_THAN_MIN"); bound(5, 100, 10); } @@ -35,7 +36,7 @@ contract DSTestPlusTest is DSTestPlus { assertLe(bounded, max); } - function testFailBoundMinBiggerThanMax( + function testBoundMinBiggerThanMax( uint256 num, uint256 min, uint256 max @@ -48,6 +49,7 @@ contract DSTestPlusTest is DSTestPlus { if (max > min) (min, max) = (max, min); + vm.expectRevert("MAX_LESS_THAN_MIN"); bound(num, min, max); } } diff --git a/src/test/WETH.t.sol b/src/test/WETH.t.sol index f2d8b9e1..328adcd2 100644 --- a/src/test/WETH.t.sol +++ b/src/test/WETH.t.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.10; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; +import {TestPlus} from "./utils/TestPlus.sol"; import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; import {WETH} from "../tokens/WETH.sol"; -contract WETHTest is DSTestPlus { +contract WETHTest is TestPlus { WETH weth; function setUp() public { @@ -107,7 +107,7 @@ contract WETHTest is DSTestPlus { receive() external payable {} } -contract WETHInvariants is DSTestPlus, DSInvariantTest { +contract WETHInvariants is TestPlus, DSInvariantTest { WETHTester wethTester; WETH weth; diff --git a/src/test/utils/Hevm.sol b/src/test/utils/Hevm.sol deleted file mode 100644 index 8ca0eff9..00000000 --- a/src/test/utils/Hevm.sol +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -interface Hevm { - /// @notice Sets the block timestamp. - function warp(uint256) external; - - /// @notice Sets the block height. - function roll(uint256) external; - - /// @notice Sets the block base fee. - function fee(uint256) external; - - /// @notice Loads a storage slot from an address. - function load(address, bytes32) external returns (bytes32); - - /// @notice Stores a value to an address' storage slot. - function store( - address, - bytes32, - bytes32 - ) external; - - /// @notice Signs a digest with a private key, returns v r s. - function sign(uint256, bytes32) - external - returns ( - uint8, - bytes32, - bytes32 - ); - - /// @notice Gets address for a given private key. - function addr(uint256) external returns (address); - - /// @notice Performs a foreign function call via a terminal call. - function ffi(string[] calldata) external returns (bytes memory); - - /// @notice Sets the next call's msg.sender to be the input address. - function prank(address) external; - - /// @notice Sets all subsequent calls' msg.sender to be the input address until stopPrank is called. - function startPrank(address) external; - - /// @notice Sets the next call's msg.sender to be the input address and the tx.origin to be the second input. - function prank(address, address) external; - - /// @notice Sets all subsequent calls' msg.sender to be the input address and - /// sets tx.origin to be the second address inputted until stopPrank is called. - function startPrank(address, address) external; - - /// @notice Resets msg.sender to its original value before a prank. - function stopPrank() external; - - /// @notice Sets an address' balance. - function deal(address, uint256) external; - - /// @notice Sets an address' code. - function etch(address, bytes calldata) external; - - /// @notice Expects an error from the next call. - function expectRevert(bytes calldata) external; - - /// @notice Expects a revert from the next call. - function expectRevert(bytes4) external; - - /// @notice Record all storage reads and writes. - function record() external; - - /// @notice Gets all accessed reads and write slots from a recording session, for a given address. - function accesses(address) external returns (bytes32[] memory reads, bytes32[] memory writes); - - /// @notice Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). - /// @notice Call this function, then emit an event, then call a function. Internally after the call, we check - /// if logs were emitted in the expected order with the expected topics and data as specified by the booleans. - function expectEmit( - bool, - bool, - bool, - bool - ) external; - - /// @notice Mocks the behavior of a contract call, setting the input and output for a function. - /// @notice Calldata can either be strict or a partial match, e.g. if only passed - /// a selector to the expected calldata, then the entire function will be mocked. - function mockCall( - address, - bytes calldata, - bytes calldata - ) external; - - /// @notice Clears all mocked calls. - function clearMockedCalls() external; - - /// @notice Expect a call to an address with the specified calldata. - /// @notice Calldata can either be strict or a partial match. - function expectCall(address, bytes calldata) external; - - /// @notice Fetches the contract bytecode from its artifact file. - function getCode(string calldata) external returns (bytes memory); - - /// @notice Label an address in test traces. - function label(address addr, string calldata label) external; - - /// @notice When fuzzing, generate new inputs if the input conditional is not met. - function assume(bool) external; -} diff --git a/src/test/utils/DSTestPlus.sol b/src/test/utils/TestPlus.sol similarity index 92% rename from src/test/utils/DSTestPlus.sol rename to src/test/utils/TestPlus.sol index 0da7da7e..660fcc77 100644 --- a/src/test/utils/DSTestPlus.sol +++ b/src/test/utils/TestPlus.sol @@ -1,15 +1,11 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; -import {DSTest} from "ds-test/test.sol"; - -import {Hevm} from "./Hevm.sol"; +import "forge-std/Test.sol"; /// @notice Extended testing framework for DappTools projects. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/test/utils/DSTestPlus.sol) -contract DSTestPlus is DSTest { - Hevm internal constant hevm = Hevm(HEVM_ADDRESS); - +/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/test/utils/TestPlus.sol) +contract TestPlus is Test { address internal constant DEAD_ADDRESS = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF; string private checkpointLabel; @@ -135,6 +131,16 @@ contract DSTestPlus is DSTest { emit log_named_uint("Bound Result", result); } + function bound( + uint256[] memory vals, + uint256 min, + uint256 max + ) internal returns (uint256[] memory result) { + for (uint256 i = 0; i < vals.length; i++) { + result[i] = bound(vals[i], min, max); + } + } + function min3( uint256 a, uint256 b,