diff --git a/.gas-snapshot b/.gas-snapshot index cb2d1653..94d5146f 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,222 +1,538 @@ -AuthTest:testCallFunctionAsOwner() (gas: 29871) -AuthTest:testCallFunctionWithPermissiveAuthority() (gas: 124249) -AuthTest:testFailCallFunctionAsNonOwner() (gas: 15491) +AuthTest:testCallFunctionAsOwner() (gas: 29784) +AuthTest:testCallFunctionWithPermissiveAuthority() (gas: 124292) +AuthTest:testCallFunctionWithPermissiveAuthority(address) (runs: 256, μ: 129235, ~: 129235) +AuthTest:testFailCallFunctionAsNonOwner() (gas: 15523) +AuthTest:testFailCallFunctionAsNonOwner(address) (runs: 256, μ: 15685, ~: 15685) 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) +AuthTest:testFailCallFunctionWithRestrictiveAuthority() (gas: 129144) +AuthTest:testFailCallFunctionWithRestrictiveAuthority(address) (runs: 256, μ: 129329, ~: 129329) +AuthTest:testFailSetAuthorityAsNonOwner() (gas: 18325) +AuthTest:testFailSetAuthorityAsNonOwner(address,address) (runs: 256, μ: 18594, ~: 18594) +AuthTest:testFailSetAuthorityWithRestrictiveAuthority() (gas: 129077) +AuthTest:testFailSetAuthorityWithRestrictiveAuthority(address,address) (runs: 256, μ: 129409, ~: 129409) +AuthTest:testFailTransferOwnershipAsNonOwner() (gas: 15641) +AuthTest:testFailTransferOwnershipAsNonOwner(address,address) (runs: 256, μ: 15922, ~: 15922) +AuthTest:testFailTransferOwnershipAsOwnerWithOutOfOrderAuthority() (gas: 136159) +AuthTest:testFailTransferOwnershipAsOwnerWithOutOfOrderAuthority(address) (runs: 256, μ: 136344, ~: 136344) +AuthTest:testFailTransferOwnershipWithRestrictiveAuthority() (gas: 129338) +AuthTest:testFailTransferOwnershipWithRestrictiveAuthority(address,address) (runs: 256, μ: 129588, ~: 129588) +AuthTest:testSetAuthorityAsOwner() (gas: 32214) +AuthTest:testSetAuthorityAsOwner(address) (runs: 256, μ: 32306, ~: 32384) +AuthTest:testSetAuthorityAsOwnerWithOutOfOrderAuthority() (gas: 226419) +AuthTest:testSetAuthorityWithPermissiveAuthority() (gas: 125962) +AuthTest:testSetAuthorityWithPermissiveAuthority(address,address) (runs: 256, μ: 130899, ~: 131055) +AuthTest:testTransferOwnershipAsOwner() (gas: 15298) +AuthTest:testTransferOwnershipAsOwner(address) (runs: 256, μ: 15450, ~: 15469) +AuthTest:testTransferOwnershipWithPermissiveAuthority() (gas: 127926) +AuthTest:testTransferOwnershipWithPermissiveAuthority(address,address) (runs: 256, μ: 130962, ~: 131000) Bytes32AddressLibTest:testFillLast12Bytes() (gas: 223) Bytes32AddressLibTest:testFromLast20Bytes() (gas: 191) -CREATE3Test:testDeployERC20() (gas: 852410) -CREATE3Test:testFailDoubleDeployDifferentBytecode() (gas: 9079256848778914164) +CREATE3Test:testDeployERC20() (gas: 853119) +CREATE3Test:testDeployERC20(bytes32,string,string,uint8) (runs: 256, μ: 937988, ~: 944481) +CREATE3Test:testFailDoubleDeployDifferentBytecode() (gas: 9079256848778914174) +CREATE3Test:testFailDoubleDeployDifferentBytecode(bytes32,bytes,bytes) (runs: 256, μ: 5830252765258982965, ~: 8937393460516727579) CREATE3Test:testFailDoubleDeploySameBytecode() (gas: 9079256848778906218) -DSTestPlusTest:testBound() (gas: 14208) +CREATE3Test:testFailDoubleDeploySameBytecode(bytes32,bytes) (runs: 256, μ: 5620782606028124357, ~: 8937393460516728723) +DSTestPlusTest:testBound() (gas: 14214) +DSTestPlusTest:testBound(uint256,uint256,uint256) (runs: 256, μ: 2787, ~: 2793) DSTestPlusTest:testBrutalizeMemory() (gas: 823) DSTestPlusTest:testFailBoundMinBiggerThanMax() (gas: 309) -DSTestPlusTest:testRelApproxEqBothZeroesPasses() (gas: 413) +DSTestPlusTest:testFailBoundMinBiggerThanMax(uint256,uint256,uint256) (runs: 256, μ: 460, ~: 460) +DSTestPlusTest:testRelApproxEqBothZeroesPasses() (gas: 425) ERC1155Test:testApproveAll() (gas: 31009) +ERC1155Test:testApproveAll(address,bool) (runs: 256, μ: 16950, ~: 11440) ERC1155Test:testBatchBalanceOf() (gas: 157631) +ERC1155Test:testBatchBalanceOf(address[],uint256[],uint256[],bytes) (runs: 256, μ: 3309912, ~: 2596398) ERC1155Test:testBatchBurn() (gas: 151074) +ERC1155Test:testBatchBurn(address,uint256[],uint256[],uint256[],bytes) (runs: 256, μ: 3490125, ~: 3058687) ERC1155Test:testBatchMintToEOA() (gas: 137337) -ERC1155Test:testBatchMintToERC1155Recipient() (gas: 942650) +ERC1155Test:testBatchMintToEOA(address,uint256[],uint256[],bytes) (runs: 256, μ: 3309311, ~: 2953384) +ERC1155Test:testBatchMintToERC1155Recipient() (gas: 995703) +ERC1155Test:testBatchMintToERC1155Recipient(uint256[],uint256[],bytes) (runs: 256, μ: 7395823, ~: 6396323) ERC1155Test:testBurn() (gas: 38598) +ERC1155Test:testBurn(address,uint256,uint256,bytes,uint256) (runs: 256, μ: 40221, ~: 42098) ERC1155Test:testFailBalanceOfBatchWithArrayMismatch() (gas: 7933) +ERC1155Test:testFailBalanceOfBatchWithArrayMismatch(address[],uint256[]) (runs: 256, μ: 53386, ~: 54066) ERC1155Test:testFailBatchBurnInsufficientBalance() (gas: 136156) +ERC1155Test:testFailBatchBurnInsufficientBalance(address,uint256[],uint256[],uint256[],bytes) (runs: 256, μ: 1301529, ~: 440335) ERC1155Test:testFailBatchBurnWithArrayLengthMismatch() (gas: 135542) +ERC1155Test:testFailBatchBurnWithArrayLengthMismatch(address,uint256[],uint256[],uint256[],bytes) (runs: 256, μ: 77137, ~: 78751) ERC1155Test:testFailBatchMintToNonERC1155Recipient() (gas: 167292) +ERC1155Test:testFailBatchMintToNonERC1155Recipient(uint256[],uint256[],bytes) (runs: 256, μ: 3190100, ~: 2673077) ERC1155Test:testFailBatchMintToRevertingERC1155Recipient() (gas: 358811) +ERC1155Test:testFailBatchMintToRevertingERC1155Recipient(uint256[],uint256[],bytes) (runs: 256, μ: 3381638, ~: 2864613) ERC1155Test:testFailBatchMintToWrongReturnDataERC1155Recipient() (gas: 310743) +ERC1155Test:testFailBatchMintToWrongReturnDataERC1155Recipient(uint256[],uint256[],bytes) (runs: 256, μ: 3333596, ~: 2816572) ERC1155Test:testFailBatchMintToZero() (gas: 131737) +ERC1155Test:testFailBatchMintToZero(uint256[],uint256[],bytes) (runs: 256, μ: 3130600, ~: 2612336) ERC1155Test:testFailBatchMintWithArrayMismatch() (gas: 9600) +ERC1155Test:testFailBatchMintWithArrayMismatch(address,uint256[],uint256[],bytes) (runs: 256, μ: 69252, ~: 68809) ERC1155Test:testFailBurnInsufficientBalance() (gas: 34852) +ERC1155Test:testFailBurnInsufficientBalance(address,uint256,uint256,uint256,bytes) (runs: 256, μ: 35951, ~: 38209) ERC1155Test:testFailMintToNonERC155Recipient() (gas: 68191) +ERC1155Test:testFailMintToNonERC155Recipient(uint256,uint256,bytes) (runs: 256, μ: 68507, ~: 69197) ERC1155Test:testFailMintToRevertingERC155Recipient() (gas: 259435) +ERC1155Test:testFailMintToRevertingERC155Recipient(uint256,uint256,bytes) (runs: 256, μ: 259682, ~: 260373) ERC1155Test:testFailMintToWrongReturnDataERC155Recipient() (gas: 259389) +ERC1155Test:testFailMintToWrongReturnDataERC155Recipient(uint256,uint256,bytes) (runs: 256, μ: 259706, ~: 260397) ERC1155Test:testFailMintToZero() (gas: 33705) +ERC1155Test:testFailMintToZero(uint256,uint256,bytes) (runs: 256, μ: 33815, ~: 34546) ERC1155Test:testFailSafeBatchTransferFromToNonERC1155Recipient() (gas: 321377) +ERC1155Test:testFailSafeBatchTransferFromToNonERC1155Recipient(uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 3541296, ~: 2963551) ERC1155Test:testFailSafeBatchTransferFromToRevertingERC1155Recipient() (gas: 512956) +ERC1155Test:testFailSafeBatchTransferFromToRevertingERC1155Recipient(uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 3732833, ~: 3155082) ERC1155Test:testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() (gas: 464847) +ERC1155Test:testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient(uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 3684751, ~: 3107003) ERC1155Test:testFailSafeBatchTransferFromToZero() (gas: 286556) +ERC1155Test:testFailSafeBatchTransferFromToZero(uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 3505960, ~: 2928396) ERC1155Test:testFailSafeBatchTransferFromWithArrayLengthMismatch() (gas: 162674) +ERC1155Test:testFailSafeBatchTransferFromWithArrayLengthMismatch(address,uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 81184, ~: 82042) ERC1155Test:testFailSafeBatchTransferInsufficientBalance() (gas: 163555) +ERC1155Test:testFailSafeBatchTransferInsufficientBalance(address,uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 1514140, ~: 499517) ERC1155Test:testFailSafeTransferFromInsufficientBalance() (gas: 63245) +ERC1155Test:testFailSafeTransferFromInsufficientBalance(address,uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 63986, ~: 67405) ERC1155Test:testFailSafeTransferFromSelfInsufficientBalance() (gas: 34297) +ERC1155Test:testFailSafeTransferFromSelfInsufficientBalance(address,uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 36266, ~: 38512) ERC1155Test:testFailSafeTransferFromToNonERC155Recipient() (gas: 96510) +ERC1155Test:testFailSafeTransferFromToNonERC155Recipient(uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 96657, ~: 100546) ERC1155Test:testFailSafeTransferFromToRevertingERC1155Recipient() (gas: 287731) +ERC1155Test:testFailSafeTransferFromToRevertingERC1155Recipient(uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 287828, ~: 291719) ERC1155Test:testFailSafeTransferFromToWrongReturnDataERC1155Recipient() (gas: 239587) +ERC1155Test:testFailSafeTransferFromToWrongReturnDataERC1155Recipient(uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 239707, ~: 243598) ERC1155Test:testFailSafeTransferFromToZero() (gas: 62014) +ERC1155Test:testFailSafeTransferFromToZero(uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 62068, ~: 66037) ERC1155Test:testMintToEOA() (gas: 34765) -ERC1155Test:testMintToERC1155Recipient() (gas: 608328) +ERC1155Test:testMintToEOA(address,uint256,uint256,bytes) (runs: 256, μ: 35552, ~: 35907) +ERC1155Test:testMintToERC1155Recipient() (gas: 661411) +ERC1155Test:testMintToERC1155Recipient(uint256,uint256,bytes) (runs: 256, μ: 691094, ~: 684374) ERC1155Test:testSafeBatchTransferFromToEOA() (gas: 297822) -ERC1155Test:testSafeBatchTransferFromToERC1155Recipient() (gas: 1122274) +ERC1155Test:testSafeBatchTransferFromToEOA(address,uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 4801633, ~: 3787204) +ERC1155Test:testSafeBatchTransferFromToERC1155Recipient() (gas: 1175327) +ERC1155Test:testSafeBatchTransferFromToERC1155Recipient(uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 7759541, ~: 6618414) ERC1155Test:testSafeTransferFromSelf() (gas: 64177) +ERC1155Test:testSafeTransferFromSelf(uint256,uint256,bytes,uint256,address,bytes) (runs: 256, μ: 64490, ~: 68564) ERC1155Test:testSafeTransferFromToEOA() (gas: 93167) -ERC1155Test:testSafeTransferFromToERC1155Recipient() (gas: 686500) +ERC1155Test:testSafeTransferFromToEOA(uint256,uint256,bytes,uint256,address,bytes) (runs: 256, μ: 91921, ~: 97450) +ERC1155Test:testSafeTransferFromToERC1155Recipient() (gas: 739583) +ERC1155Test:testSafeTransferFromToERC1155Recipient(uint256,uint256,bytes,uint256,bytes) (runs: 256, μ: 769591, ~: 765729) +ERC20Invariants:invariantBalanceSum() (runs: 256, calls: 3840, reverts: 2398) +ERC20Test:invariantMetadata() (runs: 256, calls: 3840, reverts: 2597) ERC20Test:testApprove() (gas: 31058) +ERC20Test:testApprove(address,uint256) (runs: 256, μ: 30424, ~: 31280) ERC20Test:testBurn() (gas: 56970) -ERC20Test:testFailPermitBadDeadline() (gas: 36924) +ERC20Test:testBurn(address,uint256,uint256) (runs: 256, μ: 56678, ~: 59645) +ERC20Test:testFailBurnInsufficientBalance(address,uint256,uint256) (runs: 256, μ: 51897, ~: 55492) +ERC20Test:testFailPermitBadDeadline() (gas: 36935) +ERC20Test:testFailPermitBadDeadline(uint256,address,uint256,uint256) (runs: 256, μ: 32016, ~: 37218) ERC20Test:testFailPermitBadNonce() (gas: 36874) -ERC20Test:testFailPermitPastDeadline() (gas: 10938) -ERC20Test:testFailPermitReplay() (gas: 66285) +ERC20Test:testFailPermitBadNonce(uint256,address,uint256,uint256,uint256) (runs: 256, μ: 31497, ~: 37187) +ERC20Test:testFailPermitPastDeadline() (gas: 11191) +ERC20Test:testFailPermitPastDeadline(uint256,address,uint256,uint256) (runs: 256, μ: 12007, ~: 13101) +ERC20Test:testFailPermitReplay() (gas: 66274) +ERC20Test:testFailPermitReplay(uint256,address,uint256,uint256) (runs: 256, μ: 56747, ~: 66592) ERC20Test:testFailTransferFromInsufficientAllowance() (gas: 80882) +ERC20Test:testFailTransferFromInsufficientAllowance(address,uint256,uint256) (runs: 256, μ: 79858, ~: 83393) ERC20Test:testFailTransferFromInsufficientBalance() (gas: 81358) +ERC20Test:testFailTransferFromInsufficientBalance(address,uint256,uint256) (runs: 256, μ: 79359, ~: 83870) ERC20Test:testFailTransferInsufficientBalance() (gas: 52806) +ERC20Test:testFailTransferInsufficientBalance(address,uint256,uint256) (runs: 256, μ: 51720, ~: 55310) ERC20Test:testInfiniteApproveTransferFrom() (gas: 89793) +ERC20Test:testMetadata(string,string,uint8) (runs: 256, μ: 871453, ~: 863266) ERC20Test:testMint() (gas: 53746) +ERC20Test:testMint(address,uint256) (runs: 256, μ: 52214, ~: 53925) ERC20Test:testPermit() (gas: 63193) +ERC20Test:testPermit(uint248,address,uint256,uint256) (runs: 256, μ: 62584, ~: 63517) ERC20Test:testTransfer() (gas: 60272) +ERC20Test:testTransfer(address,uint256) (runs: 256, μ: 58773, ~: 60484) 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) +ERC20Test:testTransferFrom(address,uint256,uint256) (runs: 256, μ: 86308, ~: 92841) +ERC4626Test:invariantMetadata() (runs: 256, calls: 3840, reverts: 2947) +ERC4626Test:testFailDepositWithNoApproval() (gas: 13369) +ERC4626Test:testFailDepositWithNotEnoughApproval() (gas: 87005) +ERC4626Test:testFailDepositZero() (gas: 7780) +ERC4626Test:testFailMintWithNoApproval() (gas: 13308) +ERC4626Test:testFailRedeemWithNoShareAmount() (gas: 32342) +ERC4626Test:testFailRedeemWithNotEnoughShareAmount() (gas: 203643) +ERC4626Test:testFailRedeemZero() (gas: 7967) +ERC4626Test:testFailWithdrawWithNoUnderlyingAmount() (gas: 32289) +ERC4626Test:testFailWithdrawWithNotEnoughUnderlyingAmount() (gas: 203607) +ERC4626Test:testMetadata(string,string) (runs: 256, μ: 1505442, ~: 1494715) +ERC4626Test:testMintZero() (gas: 54607) +ERC4626Test:testMultipleMintDepositRedeemWithdraw() (gas: 411804) +ERC4626Test:testSingleDepositWithdraw(uint128) (runs: 256, μ: 201539, ~: 201550) +ERC4626Test:testSingleMintRedeem(uint128) (runs: 256, μ: 201465, ~: 201476) +ERC4626Test:testVaultInteractionsForSomeoneElse() (gas: 286238) +ERC4626Test:testWithdrawZero() (gas: 52468) +ERC721Test:invariantMetadata() (runs: 256, calls: 3840, reverts: 2175) ERC721Test:testApprove() (gas: 78427) +ERC721Test:testApprove(address,uint256) (runs: 256, μ: 78637, ~: 78637) ERC721Test:testApproveAll() (gas: 31063) +ERC721Test:testApproveAll(address,bool) (runs: 256, μ: 17048, ~: 11538) ERC721Test:testApproveBurn() (gas: 65550) +ERC721Test:testApproveBurn(address,uint256) (runs: 256, μ: 65361, ~: 65619) ERC721Test:testBurn() (gas: 46107) +ERC721Test:testBurn(address,uint256) (runs: 256, μ: 46150, ~: 46160) ERC721Test:testFailApproveUnAuthorized() (gas: 55598) +ERC721Test:testFailApproveUnAuthorized(address,uint256,address) (runs: 256, μ: 55873, ~: 55873) ERC721Test:testFailApproveUnMinted() (gas: 10236) +ERC721Test:testFailApproveUnMinted(uint256,address) (runs: 256, μ: 10363, ~: 10363) ERC721Test:testFailBalanceOfZeroAddress() (gas: 5555) ERC721Test:testFailBurnUnMinted() (gas: 7857) +ERC721Test:testFailBurnUnMinted(uint256) (runs: 256, μ: 7938, ~: 7938) ERC721Test:testFailDoubleBurn() (gas: 58943) +ERC721Test:testFailDoubleBurn(uint256,address) (runs: 256, μ: 59174, ~: 59174) ERC721Test:testFailDoubleMint() (gas: 53286) +ERC721Test:testFailDoubleMint(uint256,address) (runs: 256, μ: 53496, ~: 53496) ERC721Test:testFailMintToZero() (gas: 5753) +ERC721Test:testFailMintToZero(uint256) (runs: 256, μ: 5835, ~: 5835) ERC721Test:testFailOwnerOfUnminted() (gas: 7609) +ERC721Test:testFailOwnerOfUnminted(uint256) (runs: 256, μ: 7689, ~: 7689) ERC721Test:testFailSafeMintToERC721RecipientWithWrongReturnData() (gas: 159076) +ERC721Test:testFailSafeMintToERC721RecipientWithWrongReturnData(uint256) (runs: 256, μ: 159125, ~: 159125) ERC721Test:testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() (gas: 159831) +ERC721Test:testFailSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256,bytes) (runs: 256, μ: 160231, ~: 160182) ERC721Test:testFailSafeMintToNonERC721Recipient() (gas: 89210) +ERC721Test:testFailSafeMintToNonERC721Recipient(uint256) (runs: 256, μ: 89279, ~: 89279) ERC721Test:testFailSafeMintToNonERC721RecipientWithData() (gas: 89995) +ERC721Test:testFailSafeMintToNonERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 90420, ~: 90368) ERC721Test:testFailSafeMintToRevertingERC721Recipient() (gas: 204743) +ERC721Test:testFailSafeMintToRevertingERC721Recipient(uint256) (runs: 256, μ: 204815, ~: 204815) ERC721Test:testFailSafeMintToRevertingERC721RecipientWithData() (gas: 205517) +ERC721Test:testFailSafeMintToRevertingERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 205964, ~: 205915) ERC721Test:testFailSafeTransferFromToERC721RecipientWithWrongReturnData() (gas: 187276) +ERC721Test:testFailSafeTransferFromToERC721RecipientWithWrongReturnData(uint256) (runs: 256, μ: 187360, ~: 187360) ERC721Test:testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() (gas: 187728) +ERC721Test:testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData(uint256,bytes) (runs: 256, μ: 188067, ~: 188063) ERC721Test:testFailSafeTransferFromToNonERC721Recipient() (gas: 117413) +ERC721Test:testFailSafeTransferFromToNonERC721Recipient(uint256) (runs: 256, μ: 117495, ~: 117495) ERC721Test:testFailSafeTransferFromToNonERC721RecipientWithData() (gas: 117872) +ERC721Test:testFailSafeTransferFromToNonERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 118280, ~: 118276) ERC721Test:testFailSafeTransferFromToRevertingERC721Recipient() (gas: 233009) +ERC721Test:testFailSafeTransferFromToRevertingERC721Recipient(uint256) (runs: 256, μ: 233050, ~: 233050) ERC721Test:testFailSafeTransferFromToRevertingERC721RecipientWithData() (gas: 233396) +ERC721Test:testFailSafeTransferFromToRevertingERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 233823, ~: 233819) ERC721Test:testFailTransferFromNotOwner() (gas: 57872) +ERC721Test:testFailTransferFromNotOwner(address,address,uint256) (runs: 256, μ: 57905, ~: 58162) ERC721Test:testFailTransferFromToZero() (gas: 53381) +ERC721Test:testFailTransferFromToZero(uint256) (runs: 256, μ: 53463, ~: 53463) ERC721Test:testFailTransferFromUnOwned() (gas: 8000) +ERC721Test:testFailTransferFromUnOwned(address,address,uint256) (runs: 256, μ: 8294, ~: 8241) ERC721Test:testFailTransferFromWrongFrom() (gas: 53361) +ERC721Test:testFailTransferFromWrongFrom(address,address,address,uint256) (runs: 256, μ: 53566, ~: 53752) +ERC721Test:testMetadata(string,string) (runs: 256, μ: 1343967, ~: 1332786) ERC721Test:testMint() (gas: 54336) +ERC721Test:testMint(address,uint256) (runs: 256, μ: 54521, ~: 54521) ERC721Test:testSafeMintToEOA() (gas: 56993) -ERC721Test:testSafeMintToERC721Recipient() (gas: 381737) -ERC721Test:testSafeMintToERC721RecipientWithData() (gas: 402881) +ERC721Test:testSafeMintToEOA(uint256,address) (runs: 256, μ: 57198, ~: 57421) +ERC721Test:testSafeMintToERC721Recipient() (gas: 427035) +ERC721Test:testSafeMintToERC721Recipient(uint256) (runs: 256, μ: 426053, ~: 427142) +ERC721Test:testSafeMintToERC721RecipientWithData() (gas: 448149) +ERC721Test:testSafeMintToERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 480015, ~: 470905) ERC721Test:testSafeTransferFromToEOA() (gas: 95666) -ERC721Test:testSafeTransferFromToERC721Recipient() (gas: 440251) -ERC721Test:testSafeTransferFromToERC721RecipientWithData() (gas: 461049) +ERC721Test:testSafeTransferFromToEOA(uint256,address) (runs: 256, μ: 95725, ~: 96099) +ERC721Test:testSafeTransferFromToERC721Recipient() (gas: 485549) +ERC721Test:testSafeTransferFromToERC721Recipient(uint256) (runs: 256, μ: 484593, ~: 485682) +ERC721Test:testSafeTransferFromToERC721RecipientWithData() (gas: 506317) +ERC721Test:testSafeTransferFromToERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 538126, ~: 529082) ERC721Test:testTransferFrom() (gas: 86347) +ERC721Test:testTransferFrom(uint256,address) (runs: 256, μ: 86461, ~: 86470) ERC721Test:testTransferFromApproveAll() (gas: 92898) +ERC721Test:testTransferFromApproveAll(uint256,address) (runs: 256, μ: 93182, ~: 93182) 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) -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) -OwnedTest:testCallFunctionAsNonOwner() (gas: 11311) -OwnedTest:testCallFunctionAsOwner() (gas: 10479) -OwnedTest:testSetOwner() (gas: 13035) -ReentrancyGuardTest:testFailUnprotectedCall() (gas: 46167) +ERC721Test:testTransferFromSelf(uint256,address) (runs: 256, μ: 65060, ~: 65061) +FixedPointMathLibTest:testDifferentiallyFuzzSqrt(uint256) (runs: 256, μ: 13868, ~: 6222) +FixedPointMathLibTest:testDivWadDown() (gas: 820) +FixedPointMathLibTest:testDivWadDown(uint256,uint256) (runs: 256, μ: 716, ~: 813) +FixedPointMathLibTest:testDivWadDownEdgeCases() (gas: 439) +FixedPointMathLibTest:testDivWadUp() (gas: 943) +FixedPointMathLibTest:testDivWadUp(uint256,uint256) (runs: 256, μ: 799, ~: 952) +FixedPointMathLibTest:testDivWadUpEdgeCases() (gas: 442) +FixedPointMathLibTest:testFailDivWadDownOverflow(uint256,uint256) (runs: 256, μ: 440, ~: 419) +FixedPointMathLibTest:testFailDivWadDownZeroDenominator() (gas: 332) +FixedPointMathLibTest:testFailDivWadDownZeroDenominator(uint256) (runs: 256, μ: 387, ~: 387) +FixedPointMathLibTest:testFailDivWadUpOverflow(uint256,uint256) (runs: 256, μ: 395, ~: 374) +FixedPointMathLibTest:testFailDivWadUpZeroDenominator() (gas: 332) +FixedPointMathLibTest:testFailDivWadUpZeroDenominator(uint256) (runs: 256, μ: 386, ~: 386) +FixedPointMathLibTest:testFailMulDivDownOverflow(uint256,uint256,uint256) (runs: 256, μ: 436, ~: 414) +FixedPointMathLibTest:testFailMulDivDownZeroDenominator() (gas: 328) +FixedPointMathLibTest:testFailMulDivDownZeroDenominator(uint256,uint256) (runs: 256, μ: 385, ~: 385) +FixedPointMathLibTest:testFailMulDivUpOverflow(uint256,uint256,uint256) (runs: 256, μ: 459, ~: 437) +FixedPointMathLibTest:testFailMulDivUpZeroDenominator() (gas: 329) +FixedPointMathLibTest:testFailMulDivUpZeroDenominator(uint256,uint256) (runs: 256, μ: 428, ~: 428) +FixedPointMathLibTest:testFailMulWadDownOverflow(uint256,uint256) (runs: 256, μ: 419, ~: 387) +FixedPointMathLibTest:testFailMulWadUpOverflow(uint256,uint256) (runs: 256, μ: 396, ~: 364) +FixedPointMathLibTest:testMulDivDown() (gas: 1813) +FixedPointMathLibTest:testMulDivDown(uint256,uint256,uint256) (runs: 256, μ: 680, ~: 786) +FixedPointMathLibTest:testMulDivDownEdgeCases() (gas: 686) +FixedPointMathLibTest:testMulDivUp() (gas: 2095) +FixedPointMathLibTest:testMulDivUp(uint256,uint256,uint256) (runs: 256, μ: 810, ~: 1034) +FixedPointMathLibTest:testMulDivUpEdgeCases() (gas: 785) +FixedPointMathLibTest:testMulWadDown() (gas: 823) +FixedPointMathLibTest:testMulWadDown(uint256,uint256) (runs: 256, μ: 688, ~: 803) +FixedPointMathLibTest:testMulWadDownEdgeCases() (gas: 822) +FixedPointMathLibTest:testMulWadUp() (gas: 921) +FixedPointMathLibTest:testMulWadUp(uint256,uint256) (runs: 256, μ: 834, ~: 1053) +FixedPointMathLibTest:testMulWadUpEdgeCases() (gas: 899) +FixedPointMathLibTest:testRPow() (gas: 2164) +FixedPointMathLibTest:testSqrt() (gas: 2580) +FixedPointMathLibTest:testSqrt(uint256) (runs: 256, μ: 997, ~: 1013) +FixedPointMathLibTest:testSqrtBack(uint256) (runs: 256, μ: 14998, ~: 340) +FixedPointMathLibTest:testSqrtBackHashed(uint256) (runs: 256, μ: 59001, ~: 59500) +FixedPointMathLibTest:testSqrtBackHashedSingle() (gas: 58937) +LibStringTest:testDifferentiallyFuzzToString(uint256,bytes) (runs: 256, μ: 20460, ~: 7749) +LibStringTest:testDifferentiallyFuzzToStringInt(int256,bytes) (runs: 256, μ: 20610, ~: 8980) +LibStringTest:testToString() (gas: 10069) +LibStringTest:testToStringDirty() (gas: 8145) +LibStringTest:testToStringIntNegative() (gas: 9634) +LibStringTest:testToStringIntPositive() (gas: 10481) +LibStringTest:testToStringOverwrite() (gas: 506) +MerkleProofLibTest:testValidProofSupplied() (gas: 2153) +MerkleProofLibTest:testVerifyEmptyMerkleProofSuppliedLeafAndRootDifferent() (gas: 1458) +MerkleProofLibTest:testVerifyEmptyMerkleProofSuppliedLeafAndRootSame() (gas: 1452) +MerkleProofLibTest:testVerifyInvalidProofSupplied() (gas: 2172) +MultiRolesAuthorityTest:testCanCallPublicCapability() (gas: 34204) +MultiRolesAuthorityTest:testCanCallPublicCapability(address,address,bytes4) (runs: 256, μ: 34388, ~: 34364) +MultiRolesAuthorityTest:testCanCallWithAuthorizedRole() (gas: 80416) +MultiRolesAuthorityTest:testCanCallWithAuthorizedRole(address,uint8,address,bytes4) (runs: 256, μ: 80702, ~: 80671) +MultiRolesAuthorityTest:testCanCallWithCustomAuthority() (gas: 422439) +MultiRolesAuthorityTest:testCanCallWithCustomAuthority(address,address,bytes4) (runs: 256, μ: 422858, ~: 422858) +MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesPublicCapability() (gas: 247388) +MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesPublicCapability(address,address,bytes4) (runs: 256, μ: 247841, ~: 247841) +MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesUserWithRole() (gas: 256546) +MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesUserWithRole(address,uint8,address,bytes4) (runs: 256, μ: 256879, ~: 256852) +MultiRolesAuthorityTest:testSetPublicCapabilities() (gas: 27727) +MultiRolesAuthorityTest:testSetPublicCapabilities(bytes4) (runs: 256, μ: 27836, ~: 27835) +MultiRolesAuthorityTest:testSetRoleCapabilities() (gas: 28932) +MultiRolesAuthorityTest:testSetRoleCapabilities(uint8,bytes4) (runs: 256, μ: 29073, ~: 29072) +MultiRolesAuthorityTest:testSetRoles() (gas: 28918) +MultiRolesAuthorityTest:testSetRoles(address,uint8) (runs: 256, μ: 29028, ~: 29014) +MultiRolesAuthorityTest:testSetTargetCustomAuthority() (gas: 28102) +MultiRolesAuthorityTest:testSetTargetCustomAuthority(address,address) (runs: 256, μ: 28172, ~: 28146) +OwnedTest:testCallFunctionAsNonOwner() (gas: 11344) +OwnedTest:testCallFunctionAsNonOwner(address) (runs: 256, μ: 16196, ~: 16290) +OwnedTest:testCallFunctionAsOwner() (gas: 10435) +OwnedTest:testTransferOwnership() (gas: 13123) +OwnedTest:testTransferOwnership(address) (runs: 256, μ: 13098, ~: 13192) +ReentrancyGuardTest:invariantReentrancyStatusAlways1() (runs: 256, calls: 3840, reverts: 246) +ReentrancyGuardTest:testFailUnprotectedCall() (gas: 46147) ReentrancyGuardTest:testNoReentrancy() (gas: 7515) -ReentrancyGuardTest:testProtectedCall() (gas: 33470) -RolesAuthorityTest:testCanCallPublicCapability() (gas: 33336) -RolesAuthorityTest:testCanCallWithAuthorizedRole() (gas: 79601) -RolesAuthorityTest:testSetPublicCapabilities() (gas: 29183) -RolesAuthorityTest:testSetRoleCapabilities() (gas: 30258) -RolesAuthorityTest:testSetRoles() (gas: 28986) +ReentrancyGuardTest:testProtectedCall() (gas: 33467) +RolesAuthorityTest:testCanCallPublicCapability() (gas: 33409) +RolesAuthorityTest:testCanCallPublicCapability(address,address,bytes4) (runs: 256, μ: 33559, ~: 33534) +RolesAuthorityTest:testCanCallWithAuthorizedRole() (gas: 79995) +RolesAuthorityTest:testCanCallWithAuthorizedRole(address,uint8,address,bytes4) (runs: 256, μ: 80265, ~: 80238) +RolesAuthorityTest:testSetPublicCapabilities() (gas: 29095) +RolesAuthorityTest:testSetPublicCapabilities(address,bytes4) (runs: 256, μ: 29207, ~: 29192) +RolesAuthorityTest:testSetRoleCapabilities() (gas: 30276) +RolesAuthorityTest:testSetRoleCapabilities(uint8,address,bytes4) (runs: 256, μ: 30503, ~: 30489) +RolesAuthorityTest:testSetRoles() (gas: 29005) +RolesAuthorityTest:testSetRoles(address,uint8) (runs: 256, μ: 29119, ~: 29106) SSTORE2Test:testFailReadInvalidPointer() (gas: 2927) +SSTORE2Test:testFailReadInvalidPointer(address,bytes) (runs: 256, μ: 3879, ~: 3892) SSTORE2Test:testFailReadInvalidPointerCustomBounds() (gas: 3099) +SSTORE2Test:testFailReadInvalidPointerCustomBounds(address,uint256,uint256,bytes) (runs: 256, μ: 4101, ~: 4130) SSTORE2Test:testFailReadInvalidPointerCustomStartBound() (gas: 3004) +SSTORE2Test:testFailReadInvalidPointerCustomStartBound(address,uint256,bytes) (runs: 256, μ: 3960, ~: 3988) +SSTORE2Test:testFailWriteReadCustomBoundsOutOfRange(bytes,uint256,uint256,bytes) (runs: 256, μ: 46236, ~: 43603) +SSTORE2Test:testFailWriteReadCustomStartBoundOutOfRange(bytes,uint256,bytes) (runs: 256, μ: 46017, ~: 43452) SSTORE2Test:testFailWriteReadEmptyOutOfBounds() (gas: 34470) SSTORE2Test:testFailWriteReadOutOfBounds() (gas: 34426) SSTORE2Test:testFailWriteReadOutOfStartBound() (gas: 34362) SSTORE2Test:testWriteRead() (gas: 53497) +SSTORE2Test:testWriteRead(bytes,bytes) (runs: 256, μ: 44019, ~: 41555) SSTORE2Test:testWriteReadCustomBounds() (gas: 34869) +SSTORE2Test:testWriteReadCustomBounds(bytes,uint256,uint256,bytes) (runs: 256, μ: 28372, ~: 41573) SSTORE2Test:testWriteReadCustomStartBound() (gas: 34740) +SSTORE2Test:testWriteReadCustomStartBound(bytes,uint256,bytes) (runs: 256, μ: 46485, ~: 44053) SSTORE2Test:testWriteReadEmptyBound() (gas: 34677) SSTORE2Test:testWriteReadFullBoundedRead() (gas: 53672) SSTORE2Test:testWriteReadFullStartBound() (gas: 34764) -SafeCastLibTest:testFailSafeCastTo128() (gas: 321) -SafeCastLibTest:testFailSafeCastTo160() (gas: 342) -SafeCastLibTest:testFailSafeCastTo192() (gas: 344) -SafeCastLibTest:testFailSafeCastTo224() (gas: 343) +SafeCastLibTest:testFailSafeCastTo104() (gas: 387) +SafeCastLibTest:testFailSafeCastTo104(uint256) (runs: 256, μ: 468, ~: 468) +SafeCastLibTest:testFailSafeCastTo112() (gas: 388) +SafeCastLibTest:testFailSafeCastTo112(uint256) (runs: 256, μ: 445, ~: 445) +SafeCastLibTest:testFailSafeCastTo120() (gas: 409) +SafeCastLibTest:testFailSafeCastTo120(uint256) (runs: 256, μ: 490, ~: 490) +SafeCastLibTest:testFailSafeCastTo128() (gas: 365) +SafeCastLibTest:testFailSafeCastTo128(uint256) (runs: 256, μ: 487, ~: 487) +SafeCastLibTest:testFailSafeCastTo136() (gas: 409) +SafeCastLibTest:testFailSafeCastTo136(uint256) (runs: 256, μ: 489, ~: 489) +SafeCastLibTest:testFailSafeCastTo144() (gas: 365) +SafeCastLibTest:testFailSafeCastTo144(uint256) (runs: 256, μ: 423, ~: 423) +SafeCastLibTest:testFailSafeCastTo152() (gas: 368) +SafeCastLibTest:testFailSafeCastTo152(uint256) (runs: 256, μ: 468, ~: 468) +SafeCastLibTest:testFailSafeCastTo16() (gas: 388) +SafeCastLibTest:testFailSafeCastTo16(uint256) (runs: 256, μ: 468, ~: 468) +SafeCastLibTest:testFailSafeCastTo160() (gas: 409) +SafeCastLibTest:testFailSafeCastTo160(uint256) (runs: 256, μ: 444, ~: 444) +SafeCastLibTest:testFailSafeCastTo168() (gas: 341) +SafeCastLibTest:testFailSafeCastTo168(uint256) (runs: 256, μ: 488, ~: 488) +SafeCastLibTest:testFailSafeCastTo176() (gas: 363) +SafeCastLibTest:testFailSafeCastTo176(uint256) (runs: 256, μ: 489, ~: 489) +SafeCastLibTest:testFailSafeCastTo184() (gas: 343) +SafeCastLibTest:testFailSafeCastTo184(uint256) (runs: 256, μ: 490, ~: 490) +SafeCastLibTest:testFailSafeCastTo192() (gas: 367) +SafeCastLibTest:testFailSafeCastTo192(uint256) (runs: 256, μ: 446, ~: 446) +SafeCastLibTest:testFailSafeCastTo200() (gas: 343) +SafeCastLibTest:testFailSafeCastTo200(uint256) (runs: 256, μ: 490, ~: 490) +SafeCastLibTest:testFailSafeCastTo208() (gas: 386) +SafeCastLibTest:testFailSafeCastTo208(uint256) (runs: 256, μ: 446, ~: 446) +SafeCastLibTest:testFailSafeCastTo216() (gas: 365) +SafeCastLibTest:testFailSafeCastTo216(uint256) (runs: 256, μ: 424, ~: 424) +SafeCastLibTest:testFailSafeCastTo224() (gas: 409) +SafeCastLibTest:testFailSafeCastTo224(uint256) (runs: 256, μ: 423, ~: 423) +SafeCastLibTest:testFailSafeCastTo232() (gas: 410) +SafeCastLibTest:testFailSafeCastTo232(uint256) (runs: 256, μ: 467, ~: 467) +SafeCastLibTest:testFailSafeCastTo24() (gas: 387) +SafeCastLibTest:testFailSafeCastTo24(uint256) (runs: 256, μ: 424, ~: 424) +SafeCastLibTest:testFailSafeCastTo240() (gas: 364) +SafeCastLibTest:testFailSafeCastTo240(uint256) (runs: 256, μ: 467, ~: 467) SafeCastLibTest:testFailSafeCastTo248() (gas: 365) +SafeCastLibTest:testFailSafeCastTo248(uint256) (runs: 256, μ: 466, ~: 466) SafeCastLibTest:testFailSafeCastTo32() (gas: 364) -SafeCastLibTest:testFailSafeCastTo64() (gas: 321) -SafeCastLibTest:testFailSafeCastTo8() (gas: 296) -SafeCastLibTest:testFailSafeCastTo96() (gas: 321) -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: 30751) -SafeTransferLibTest:testApproveWithNonContract() (gas: 3035) -SafeTransferLibTest:testApproveWithReturnsTooMuch() (gas: 31134) -SafeTransferLibTest:testApproveWithStandardERC20() (gas: 30882) -SafeTransferLibTest:testFailApproveWithReturnsFalse() (gas: 5627) -SafeTransferLibTest:testFailApproveWithReturnsTooLittle() (gas: 5568) -SafeTransferLibTest:testFailApproveWithReverting() (gas: 5502) +SafeCastLibTest:testFailSafeCastTo32(uint256) (runs: 256, μ: 468, ~: 468) +SafeCastLibTest:testFailSafeCastTo40() (gas: 366) +SafeCastLibTest:testFailSafeCastTo40(uint256) (runs: 256, μ: 422, ~: 422) +SafeCastLibTest:testFailSafeCastTo48() (gas: 366) +SafeCastLibTest:testFailSafeCastTo48(uint256) (runs: 256, μ: 488, ~: 488) +SafeCastLibTest:testFailSafeCastTo56() (gas: 388) +SafeCastLibTest:testFailSafeCastTo56(uint256) (runs: 256, μ: 445, ~: 445) +SafeCastLibTest:testFailSafeCastTo64() (gas: 410) +SafeCastLibTest:testFailSafeCastTo64(uint256) (runs: 256, μ: 446, ~: 446) +SafeCastLibTest:testFailSafeCastTo72() (gas: 410) +SafeCastLibTest:testFailSafeCastTo72(uint256) (runs: 256, μ: 467, ~: 467) +SafeCastLibTest:testFailSafeCastTo8() (gas: 341) +SafeCastLibTest:testFailSafeCastTo8(uint256) (runs: 256, μ: 421, ~: 421) +SafeCastLibTest:testFailSafeCastTo80() (gas: 343) +SafeCastLibTest:testFailSafeCastTo80(uint256) (runs: 256, μ: 424, ~: 424) +SafeCastLibTest:testFailSafeCastTo88() (gas: 344) +SafeCastLibTest:testFailSafeCastTo88(uint256) (runs: 256, μ: 489, ~: 489) +SafeCastLibTest:testFailSafeCastTo96() (gas: 366) +SafeCastLibTest:testFailSafeCastTo96(uint256) (runs: 256, μ: 469, ~: 469) +SafeCastLibTest:testSafeCastTo104() (gas: 515) +SafeCastLibTest:testSafeCastTo104(uint256) (runs: 256, μ: 2779, ~: 2779) +SafeCastLibTest:testSafeCastTo112() (gas: 469) +SafeCastLibTest:testSafeCastTo112(uint256) (runs: 256, μ: 2755, ~: 2755) +SafeCastLibTest:testSafeCastTo120() (gas: 491) +SafeCastLibTest:testSafeCastTo120(uint256) (runs: 256, μ: 2735, ~: 2735) +SafeCastLibTest:testSafeCastTo128() (gas: 516) +SafeCastLibTest:testSafeCastTo128(uint256) (runs: 256, μ: 2735, ~: 2735) +SafeCastLibTest:testSafeCastTo136() (gas: 470) +SafeCastLibTest:testSafeCastTo136(uint256) (runs: 256, μ: 2757, ~: 2757) +SafeCastLibTest:testSafeCastTo144() (gas: 514) +SafeCastLibTest:testSafeCastTo144(uint256) (runs: 256, μ: 2798, ~: 2798) +SafeCastLibTest:testSafeCastTo152() (gas: 494) +SafeCastLibTest:testSafeCastTo152(uint256) (runs: 256, μ: 2734, ~: 2734) +SafeCastLibTest:testSafeCastTo16() (gas: 469) +SafeCastLibTest:testSafeCastTo16(uint256) (runs: 256, μ: 2779, ~: 2779) +SafeCastLibTest:testSafeCastTo160() (gas: 491) +SafeCastLibTest:testSafeCastTo160(uint256) (runs: 256, μ: 2775, ~: 2775) +SafeCastLibTest:testSafeCastTo168() (gas: 494) +SafeCastLibTest:testSafeCastTo168(uint256) (runs: 256, μ: 2799, ~: 2799) +SafeCastLibTest:testSafeCastTo176() (gas: 493) +SafeCastLibTest:testSafeCastTo176(uint256) (runs: 256, μ: 2734, ~: 2734) +SafeCastLibTest:testSafeCastTo184() (gas: 513) +SafeCastLibTest:testSafeCastTo184(uint256) (runs: 256, μ: 2801, ~: 2801) +SafeCastLibTest:testSafeCastTo192() (gas: 494) +SafeCastLibTest:testSafeCastTo192(uint256) (runs: 256, μ: 2734, ~: 2734) +SafeCastLibTest:testSafeCastTo200() (gas: 470) +SafeCastLibTest:testSafeCastTo200(uint256) (runs: 256, μ: 2734, ~: 2734) +SafeCastLibTest:testSafeCastTo208() (gas: 472) +SafeCastLibTest:testSafeCastTo208(uint256) (runs: 256, μ: 2756, ~: 2756) +SafeCastLibTest:testSafeCastTo216() (gas: 493) +SafeCastLibTest:testSafeCastTo216(uint256) (runs: 256, μ: 2777, ~: 2777) +SafeCastLibTest:testSafeCastTo224() (gas: 469) +SafeCastLibTest:testSafeCastTo224(uint256) (runs: 256, μ: 2733, ~: 2733) +SafeCastLibTest:testSafeCastTo232() (gas: 492) +SafeCastLibTest:testSafeCastTo232(uint256) (runs: 256, μ: 2735, ~: 2735) +SafeCastLibTest:testSafeCastTo24() (gas: 515) +SafeCastLibTest:testSafeCastTo24(uint256) (runs: 256, μ: 2733, ~: 2733) +SafeCastLibTest:testSafeCastTo240() (gas: 513) +SafeCastLibTest:testSafeCastTo240(uint256) (runs: 256, μ: 2800, ~: 2800) +SafeCastLibTest:testSafeCastTo248() (gas: 472) +SafeCastLibTest:testSafeCastTo248(uint256) (runs: 256, μ: 2777, ~: 2777) +SafeCastLibTest:testSafeCastTo32() (gas: 516) +SafeCastLibTest:testSafeCastTo32(uint256) (runs: 256, μ: 2777, ~: 2777) +SafeCastLibTest:testSafeCastTo40() (gas: 517) +SafeCastLibTest:testSafeCastTo40(uint256) (runs: 256, μ: 2756, ~: 2756) +SafeCastLibTest:testSafeCastTo48() (gas: 469) +SafeCastLibTest:testSafeCastTo48(uint256) (runs: 256, μ: 2778, ~: 2778) +SafeCastLibTest:testSafeCastTo56() (gas: 470) +SafeCastLibTest:testSafeCastTo56(uint256) (runs: 256, μ: 2801, ~: 2801) +SafeCastLibTest:testSafeCastTo64() (gas: 537) +SafeCastLibTest:testSafeCastTo64(uint256) (runs: 256, μ: 2799, ~: 2799) +SafeCastLibTest:testSafeCastTo72(uint256) (runs: 256, μ: 2798, ~: 2798) +SafeCastLibTest:testSafeCastTo8() (gas: 513) +SafeCastLibTest:testSafeCastTo8(uint256) (runs: 256, μ: 2755, ~: 2755) +SafeCastLibTest:testSafeCastTo80(uint256) (runs: 256, μ: 2736, ~: 2736) +SafeCastLibTest:testSafeCastTo88(uint256) (runs: 256, μ: 2755, ~: 2755) +SafeCastLibTest:testSafeCastTo96() (gas: 536) +SafeCastLibTest:testSafeCastTo96(uint256) (runs: 256, μ: 2800, ~: 2800) +SafeTransferLibTest:testApproveWithGarbage(address,uint256,bytes,bytes) (runs: 256, μ: 2651, ~: 2228) +SafeTransferLibTest:testApproveWithMissingReturn() (gas: 30757) +SafeTransferLibTest:testApproveWithMissingReturn(address,uint256,bytes) (runs: 256, μ: 30334, ~: 31572) +SafeTransferLibTest:testApproveWithNonContract() (gas: 3041) +SafeTransferLibTest:testApproveWithNonContract(address,address,uint256,bytes) (runs: 256, μ: 4093, ~: 4123) +SafeTransferLibTest:testApproveWithReturnsTooMuch() (gas: 31140) +SafeTransferLibTest:testApproveWithReturnsTooMuch(address,uint256,bytes) (runs: 256, μ: 30802, ~: 32040) +SafeTransferLibTest:testApproveWithStandardERC20() (gas: 30888) +SafeTransferLibTest:testApproveWithStandardERC20(address,uint256,bytes) (runs: 256, μ: 30528, ~: 31766) +SafeTransferLibTest:testFailApproveWithGarbage(address,uint256,bytes,bytes) (runs: 256, μ: 83705, ~: 77915) +SafeTransferLibTest:testFailApproveWithReturnsFalse() (gas: 5633) +SafeTransferLibTest:testFailApproveWithReturnsFalse(address,uint256,bytes) (runs: 256, μ: 6486, ~: 6481) +SafeTransferLibTest:testFailApproveWithReturnsTooLittle() (gas: 5574) +SafeTransferLibTest:testFailApproveWithReturnsTooLittle(address,uint256,bytes) (runs: 256, μ: 6450, ~: 6445) +SafeTransferLibTest:testFailApproveWithReturnsTwo(address,uint256,bytes) (runs: 256, μ: 6458, ~: 6453) +SafeTransferLibTest:testFailApproveWithReverting() (gas: 5508) +SafeTransferLibTest:testFailApproveWithReverting(address,uint256,bytes) (runs: 256, μ: 6409, ~: 6404) SafeTransferLibTest:testFailTransferETHToContractWithoutFallback() (gas: 7244) -SafeTransferLibTest:testFailTransferFromWithReturnsFalse() (gas: 13663) -SafeTransferLibTest:testFailTransferFromWithReturnsTooLittle() (gas: 13544) +SafeTransferLibTest:testFailTransferETHToContractWithoutFallback(uint256,bytes) (runs: 256, μ: 7758, ~: 8055) +SafeTransferLibTest:testFailTransferFromWithGarbage(address,address,uint256,bytes,bytes) (runs: 256, μ: 122802, ~: 117413) +SafeTransferLibTest:testFailTransferFromWithReturnsFalse() (gas: 13675) +SafeTransferLibTest:testFailTransferFromWithReturnsFalse(address,address,uint256,bytes) (runs: 256, μ: 14605, ~: 14600) +SafeTransferLibTest:testFailTransferFromWithReturnsTooLittle() (gas: 13556) +SafeTransferLibTest:testFailTransferFromWithReturnsTooLittle(address,address,uint256,bytes) (runs: 256, μ: 14464, ~: 14459) +SafeTransferLibTest:testFailTransferFromWithReturnsTwo(address,address,uint256,bytes) (runs: 256, μ: 14571, ~: 14566) SafeTransferLibTest:testFailTransferFromWithReverting() (gas: 9757) -SafeTransferLibTest:testFailTransferWithReturnsFalse() (gas: 8532) -SafeTransferLibTest:testFailTransferWithReturnsTooLittle() (gas: 8538) -SafeTransferLibTest:testFailTransferWithReverting() (gas: 8494) +SafeTransferLibTest:testFailTransferFromWithReverting(address,address,uint256,bytes) (runs: 256, μ: 10685, ~: 10680) +SafeTransferLibTest:testFailTransferWithGarbage(address,uint256,bytes,bytes) (runs: 256, μ: 89567, ~: 83995) +SafeTransferLibTest:testFailTransferWithReturnsFalse() (gas: 8538) +SafeTransferLibTest:testFailTransferWithReturnsFalse(address,uint256,bytes) (runs: 256, μ: 9457, ~: 9452) +SafeTransferLibTest:testFailTransferWithReturnsTooLittle() (gas: 8544) +SafeTransferLibTest:testFailTransferWithReturnsTooLittle(address,uint256,bytes) (runs: 256, μ: 9397, ~: 9392) +SafeTransferLibTest:testFailTransferWithReturnsTwo(address,uint256,bytes) (runs: 256, μ: 9384, ~: 9379) +SafeTransferLibTest:testFailTransferWithReverting() (gas: 8500) +SafeTransferLibTest:testFailTransferWithReverting(address,uint256,bytes) (runs: 256, μ: 9356, ~: 9351) SafeTransferLibTest:testTransferETH() (gas: 34592) -SafeTransferLibTest:testTransferFromWithMissingReturn() (gas: 49188) -SafeTransferLibTest:testTransferFromWithNonContract() (gas: 3035) -SafeTransferLibTest:testTransferFromWithReturnsTooMuch() (gas: 49812) -SafeTransferLibTest:testTransferFromWithStandardERC20() (gas: 47605) -SafeTransferLibTest:testTransferWithMissingReturn() (gas: 36669) -SafeTransferLibTest:testTransferWithNonContract() (gas: 3012) -SafeTransferLibTest:testTransferWithReturnsTooMuch() (gas: 37115) -SafeTransferLibTest:testTransferWithStandardERC20() (gas: 36699) -WETHTest:testDeposit() (gas: 63260) -WETHTest:testFallbackDeposit() (gas: 63524) +SafeTransferLibTest:testTransferETH(address,uint256,bytes) (runs: 256, μ: 35064, ~: 37975) +SafeTransferLibTest:testTransferFromWithGarbage(address,address,uint256,bytes,bytes) (runs: 256, μ: 2916, ~: 2247) +SafeTransferLibTest:testTransferFromWithMissingReturn() (gas: 49196) +SafeTransferLibTest:testTransferFromWithMissingReturn(address,address,uint256,bytes) (runs: 256, μ: 48352, ~: 49602) +SafeTransferLibTest:testTransferFromWithNonContract() (gas: 3047) +SafeTransferLibTest:testTransferFromWithNonContract(address,address,address,uint256,bytes) (runs: 256, μ: 4200, ~: 4240) +SafeTransferLibTest:testTransferFromWithReturnsTooMuch() (gas: 49820) +SafeTransferLibTest:testTransferFromWithReturnsTooMuch(address,address,uint256,bytes) (runs: 256, μ: 49000, ~: 50242) +SafeTransferLibTest:testTransferFromWithStandardERC20() (gas: 47612) +SafeTransferLibTest:testTransferFromWithStandardERC20(address,address,uint256,bytes) (runs: 256, μ: 46781, ~: 48054) +SafeTransferLibTest:testTransferWithGarbage(address,uint256,bytes,bytes) (runs: 256, μ: 2607, ~: 2184) +SafeTransferLibTest:testTransferWithMissingReturn() (gas: 36672) +SafeTransferLibTest:testTransferWithMissingReturn(address,uint256,bytes) (runs: 256, μ: 36007, ~: 37552) +SafeTransferLibTest:testTransferWithNonContract() (gas: 3018) +SafeTransferLibTest:testTransferWithNonContract(address,address,uint256,bytes) (runs: 256, μ: 4157, ~: 4187) +SafeTransferLibTest:testTransferWithReturnsTooMuch() (gas: 37118) +SafeTransferLibTest:testTransferWithReturnsTooMuch(address,uint256,bytes) (runs: 256, μ: 36410, ~: 37955) +SafeTransferLibTest:testTransferWithStandardERC20() (gas: 36702) +SafeTransferLibTest:testTransferWithStandardERC20(address,uint256,bytes) (runs: 256, μ: 36060, ~: 37605) +SignedWadMathTest:testFailWadDivOverflow(int256,int256) (runs: 256, μ: 367, ~: 351) +SignedWadMathTest:testFailWadDivZeroDenominator(int256) (runs: 256, μ: 296, ~: 296) +SignedWadMathTest:testFailWadMulOverflow(int256,int256) (runs: 256, μ: 325, ~: 296) +SignedWadMathTest:testWadDiv(uint256,uint256,bool,bool) (runs: 256, μ: 5698, ~: 5714) +SignedWadMathTest:testWadMul(uint256,uint256,bool,bool) (runs: 256, μ: 5721, ~: 5738) +WETHInvariants:invariantTotalSupplyEqualsBalance() (runs: 256, calls: 3840, reverts: 1848) +WETHTest:testDeposit() (gas: 63535) +WETHTest:testDeposit(uint256) (runs: 256, μ: 63155, ~: 65880) +WETHTest:testFallbackDeposit() (gas: 63249) +WETHTest:testFallbackDeposit(uint256) (runs: 256, μ: 62879, ~: 65604) WETHTest:testPartialWithdraw() (gas: 73281) WETHTest:testWithdraw() (gas: 54360) +WETHTest:testWithdraw(uint256,uint256) (runs: 256, μ: 74974, ~: 78076) \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index e664563b..7c5f3db3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1 @@ -*.sol linguist-language=Solidity .gas-snapshot linguist-language=Julia \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 74939bef..f91a167c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "solidity.packageDefaultDependenciesContractsDirectory": "src", "solidity.packageDefaultDependenciesDirectory": "lib", - "solidity.compileUsingRemoteVersion": "v0.8.10", + "solidity.compileUsingRemoteVersion": "v0.8.15", "search.exclude": { "lib": true }, "files.associations": { ".gas-snapshot": "julia" diff --git a/README.md b/README.md index 58b207c7..2bc3e3a8 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,12 @@ tokens ├─ ERC721 — "Modern, minimalist, and gas efficient ERC721 implementation" ├─ ERC1155 — "Minimalist and gas efficient standard ERC1155 implementation" utils -├─ SSTORE2 - "Library for cheaper reads and writes to persistent storage" +├─ SSTORE2 — "Library for cheaper reads and writes to persistent storage" ├─ CREATE3 — "Deploy to deterministic addresses without an initcode factor" -├─ SafeCastLib - "Safe unsigned integer casting lib that reverts on overflow" +├─ LibString — "Library for creating string representations of uint values" +├─ SafeCastLib — "Safe unsigned integer casting lib that reverts on overflow" +├─ SignedWadMath — "Signed integer 18 decimal fixed point arithmetic library" +├─ MerkleProofLib — "Efficient merkle tree inclusion proof verification library" ├─ ReentrancyGuard — "Gas optimized reentrancy protection for smart contracts" ├─ FixedPointMathLib — "Arithmetic library with operations for fixed-point numbers" ├─ Bytes32AddressLib — "Library for converting between addresses and bytes32 values" @@ -45,13 +48,13 @@ We **do not give any warranties** and **will not be liable for any loss** incurr To install with [**Foundry**](https://github.com/gakonst/foundry): ```sh -forge install rari-capital/solmate +forge install transmissions11/solmate ``` To install with [**Hardhat**](https://github.com/nomiclabs/hardhat) or [**Truffle**](https://github.com/trufflesuite/truffle): ```sh -npm install @rari-capital/solmate +npm install solmate ``` ## Acknowledgements diff --git a/foundry.toml b/foundry.toml index 8a4fd22d..ebdfa111 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,7 +1,7 @@ -[default] -solc = "0.8.10" +[profile.default] +solc = "0.8.15" bytecode_hash = "none" optimizer_runs = 1000000 -[intense] -fuzz_runs = 10000 +[profile.intense.fuzz] +runs = 10000 diff --git a/lib/ds-test b/lib/ds-test index c7a36fb2..cd98eff2 160000 --- a/lib/ds-test +++ b/lib/ds-test @@ -1 +1 @@ -Subproject commit c7a36fb236f298e04edf28e2fee385b80f53945f +Subproject commit cd98eff28324bfac652e63a239a60632a761790b diff --git a/package-lock.json b/package-lock.json index 5031552f..ed210a37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "@rari-capital/solmate", - "version": "6.4.0", + "name": "solmate", + "version": "6.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b671cb2c..24a55852 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,14 @@ { - "name": "@rari-capital/solmate", + "name": "solmate", "license": "AGPL-3.0-only", - "version": "6.4.0", + "version": "6.1.0", "description": "Modern, opinionated and gas optimized building blocks for smart contract development.", "files": [ "src/**/*.sol" ], "repository": { "type": "git", - "url": "git+https://github.com/Rari-Capital/solmate.git" + "url": "git+https://github.com/transmissions11/solmate.git" }, "devDependencies": { "prettier": "^2.3.1", diff --git a/src/auth/Auth.sol b/src/auth/Auth.sol index 48edaa42..3807ccda 100644 --- a/src/auth/Auth.sol +++ b/src/auth/Auth.sol @@ -2,10 +2,10 @@ pragma solidity >=0.8.0; /// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol) /// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol) abstract contract Auth { - event OwnerUpdated(address indexed user, address indexed newOwner); + event OwnershipTransferred(address indexed user, address indexed newOwner); event AuthorityUpdated(address indexed user, Authority indexed newAuthority); @@ -17,7 +17,7 @@ abstract contract Auth { owner = _owner; authority = _authority; - emit OwnerUpdated(msg.sender, _owner); + emit OwnershipTransferred(msg.sender, _owner); emit AuthorityUpdated(msg.sender, _authority); } @@ -45,15 +45,15 @@ abstract contract Auth { emit AuthorityUpdated(msg.sender, newAuthority); } - function setOwner(address newOwner) public virtual requiresAuth { + function transferOwnership(address newOwner) public virtual requiresAuth { owner = newOwner; - emit OwnerUpdated(msg.sender, newOwner); + emit OwnershipTransferred(msg.sender, newOwner); } } /// @notice A generic interface for a contract which provides authorization data to an Auth instance. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol) /// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol) interface Authority { function canCall( diff --git a/src/auth/Owned.sol b/src/auth/Owned.sol index 415d845b..e82b44d8 100644 --- a/src/auth/Owned.sol +++ b/src/auth/Owned.sol @@ -2,13 +2,13 @@ pragma solidity >=0.8.0; /// @notice Simple single owner authorization mixin. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol) abstract contract Owned { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ - event OwnerUpdated(address indexed user, address indexed newOwner); + event OwnershipTransferred(address indexed user, address indexed newOwner); /*////////////////////////////////////////////////////////////// OWNERSHIP STORAGE @@ -29,16 +29,16 @@ abstract contract Owned { constructor(address _owner) { owner = _owner; - emit OwnerUpdated(address(0), _owner); + emit OwnershipTransferred(address(0), _owner); } /*////////////////////////////////////////////////////////////// OWNERSHIP LOGIC //////////////////////////////////////////////////////////////*/ - function setOwner(address newOwner) public virtual onlyOwner { + function transferOwnership(address newOwner) public virtual onlyOwner { owner = newOwner; - emit OwnerUpdated(msg.sender, newOwner); + emit OwnershipTransferred(msg.sender, newOwner); } } diff --git a/src/auth/authorities/MultiRolesAuthority.sol b/src/auth/authorities/MultiRolesAuthority.sol index 8ecd3cdd..3ff80bb0 100644 --- a/src/auth/authorities/MultiRolesAuthority.sol +++ b/src/auth/authorities/MultiRolesAuthority.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.0; import {Auth, Authority} from "../Auth.sol"; /// @notice Flexible and target agnostic role based Authority that supports up to 256 roles. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/authorities/MultiRolesAuthority.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/authorities/MultiRolesAuthority.sol) contract MultiRolesAuthority is Auth, Authority { /*////////////////////////////////////////////////////////////// EVENTS diff --git a/src/auth/authorities/RolesAuthority.sol b/src/auth/authorities/RolesAuthority.sol index afefe1ad..aa5cc71c 100644 --- a/src/auth/authorities/RolesAuthority.sol +++ b/src/auth/authorities/RolesAuthority.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.0; import {Auth, Authority} from "../Auth.sol"; /// @notice Role based Authority that supports up to 256 roles. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/authorities/RolesAuthority.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/authorities/RolesAuthority.sol) /// @author Modified from Dappsys (https://github.com/dapphub/ds-roles/blob/master/src/roles.sol) contract RolesAuthority is Auth, Authority { /*////////////////////////////////////////////////////////////// diff --git a/src/mixins/ERC4626.sol b/src/mixins/ERC4626.sol index 704e0d44..af56c156 100644 --- a/src/mixins/ERC4626.sol +++ b/src/mixins/ERC4626.sol @@ -6,7 +6,7 @@ import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol"; /// @notice Minimal ERC4626 tokenized Vault implementation. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol) abstract contract ERC4626 is ERC20 { using SafeTransferLib for ERC20; using FixedPointMathLib for uint256; diff --git a/src/test/Auth.t.sol b/src/test/Auth.t.sol index 19a6b846..9e315288 100644 --- a/src/test/Auth.t.sol +++ b/src/test/Auth.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol"; @@ -24,8 +24,8 @@ contract AuthTest is DSTestPlus { mockAuthChild = new MockAuthChild(); } - function testSetOwnerAsOwner() public { - mockAuthChild.setOwner(address(0xBEEF)); + function testTransferOwnershipAsOwner() public { + mockAuthChild.transferOwnership(address(0xBEEF)); assertEq(mockAuthChild.owner(), address(0xBEEF)); } @@ -38,21 +38,21 @@ contract AuthTest is DSTestPlus { mockAuthChild.updateFlag(); } - function testSetOwnerWithPermissiveAuthority() public { + function testTransferOwnershipWithPermissiveAuthority() public { mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.setOwner(address(0)); - mockAuthChild.setOwner(address(this)); + mockAuthChild.transferOwnership(address(0)); + mockAuthChild.transferOwnership(address(this)); } function testSetAuthorityWithPermissiveAuthority() public { mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.setOwner(address(0)); + mockAuthChild.transferOwnership(address(0)); mockAuthChild.setAuthority(Authority(address(0xBEEF))); } function testCallFunctionWithPermissiveAuthority() public { mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.setOwner(address(0)); + mockAuthChild.transferOwnership(address(0)); mockAuthChild.updateFlag(); } @@ -61,42 +61,42 @@ contract AuthTest is DSTestPlus { mockAuthChild.setAuthority(new MockAuthority(true)); } - function testFailSetOwnerAsNonOwner() public { - mockAuthChild.setOwner(address(0)); - mockAuthChild.setOwner(address(0xBEEF)); + function testFailTransferOwnershipAsNonOwner() public { + mockAuthChild.transferOwnership(address(0)); + mockAuthChild.transferOwnership(address(0xBEEF)); } function testFailSetAuthorityAsNonOwner() public { - mockAuthChild.setOwner(address(0)); + mockAuthChild.transferOwnership(address(0)); mockAuthChild.setAuthority(Authority(address(0xBEEF))); } function testFailCallFunctionAsNonOwner() public { - mockAuthChild.setOwner(address(0)); + mockAuthChild.transferOwnership(address(0)); mockAuthChild.updateFlag(); } - function testFailSetOwnerWithRestrictiveAuthority() public { + function testFailTransferOwnershipWithRestrictiveAuthority() public { mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.setOwner(address(0)); - mockAuthChild.setOwner(address(this)); + mockAuthChild.transferOwnership(address(0)); + mockAuthChild.transferOwnership(address(this)); } function testFailSetAuthorityWithRestrictiveAuthority() public { mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.setOwner(address(0)); + mockAuthChild.transferOwnership(address(0)); mockAuthChild.setAuthority(Authority(address(0xBEEF))); } function testFailCallFunctionWithRestrictiveAuthority() public { mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.setOwner(address(0)); + mockAuthChild.transferOwnership(address(0)); mockAuthChild.updateFlag(); } - function testFailSetOwnerAsOwnerWithOutOfOrderAuthority() public { + function testFailTransferOwnershipAsOwnerWithOutOfOrderAuthority() public { mockAuthChild.setAuthority(new OutOfOrderAuthority()); - mockAuthChild.setOwner(address(0)); + mockAuthChild.transferOwnership(address(0)); } function testFailCallFunctionAsOwnerWithOutOfOrderAuthority() public { @@ -104,8 +104,8 @@ contract AuthTest is DSTestPlus { mockAuthChild.updateFlag(); } - function testSetOwnerAsOwner(address newOwner) public { - mockAuthChild.setOwner(newOwner); + function testTransferOwnershipAsOwner(address newOwner) public { + mockAuthChild.transferOwnership(newOwner); assertEq(mockAuthChild.owner(), newOwner); } @@ -114,19 +114,19 @@ contract AuthTest is DSTestPlus { assertEq(address(mockAuthChild.authority()), address(newAuthority)); } - function testSetOwnerWithPermissiveAuthority(address deadOwner, address newOwner) public { + function testTransferOwnershipWithPermissiveAuthority(address deadOwner, address newOwner) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.setOwner(deadOwner); - mockAuthChild.setOwner(newOwner); + mockAuthChild.transferOwnership(deadOwner); + mockAuthChild.transferOwnership(newOwner); } function testSetAuthorityWithPermissiveAuthority(address deadOwner, Authority newAuthority) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.setOwner(deadOwner); + mockAuthChild.transferOwnership(deadOwner); mockAuthChild.setAuthority(newAuthority); } @@ -134,44 +134,44 @@ contract AuthTest is DSTestPlus { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.setOwner(deadOwner); + mockAuthChild.transferOwnership(deadOwner); mockAuthChild.updateFlag(); } - function testFailSetOwnerAsNonOwner(address deadOwner, address newOwner) public { + function testFailTransferOwnershipAsNonOwner(address deadOwner, address newOwner) public { if (deadOwner == address(this)) deadOwner = address(0); - mockAuthChild.setOwner(deadOwner); - mockAuthChild.setOwner(newOwner); + mockAuthChild.transferOwnership(deadOwner); + mockAuthChild.transferOwnership(newOwner); } function testFailSetAuthorityAsNonOwner(address deadOwner, Authority newAuthority) public { if (deadOwner == address(this)) deadOwner = address(0); - mockAuthChild.setOwner(deadOwner); + mockAuthChild.transferOwnership(deadOwner); mockAuthChild.setAuthority(newAuthority); } function testFailCallFunctionAsNonOwner(address deadOwner) public { if (deadOwner == address(this)) deadOwner = address(0); - mockAuthChild.setOwner(deadOwner); + mockAuthChild.transferOwnership(deadOwner); mockAuthChild.updateFlag(); } - function testFailSetOwnerWithRestrictiveAuthority(address deadOwner, address newOwner) public { + function testFailTransferOwnershipWithRestrictiveAuthority(address deadOwner, address newOwner) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.setOwner(deadOwner); - mockAuthChild.setOwner(newOwner); + mockAuthChild.transferOwnership(deadOwner); + mockAuthChild.transferOwnership(newOwner); } function testFailSetAuthorityWithRestrictiveAuthority(address deadOwner, Authority newAuthority) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.setOwner(deadOwner); + mockAuthChild.transferOwnership(deadOwner); mockAuthChild.setAuthority(newAuthority); } @@ -179,14 +179,14 @@ contract AuthTest is DSTestPlus { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.setOwner(deadOwner); + mockAuthChild.transferOwnership(deadOwner); mockAuthChild.updateFlag(); } - function testFailSetOwnerAsOwnerWithOutOfOrderAuthority(address deadOwner) public { + function testFailTransferOwnershipAsOwnerWithOutOfOrderAuthority(address deadOwner) public { if (deadOwner == address(this)) deadOwner = address(0); mockAuthChild.setAuthority(new OutOfOrderAuthority()); - mockAuthChild.setOwner(deadOwner); + mockAuthChild.transferOwnership(deadOwner); } } diff --git a/src/test/Bytes32AddressLib.t.sol b/src/test/Bytes32AddressLib.t.sol index 0a85b141..6c0a3d8e 100644 --- a/src/test/Bytes32AddressLib.t.sol +++ b/src/test/Bytes32AddressLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; diff --git a/src/test/CREATE3.t.sol b/src/test/CREATE3.t.sol index 8120632d..b279eeb2 100644 --- a/src/test/CREATE3.t.sol +++ b/src/test/CREATE3.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {WETH} from "../tokens/WETH.sol"; import {DSTestPlus} from "./utils/DSTestPlus.sol"; diff --git a/src/test/DSTestPlus.t.sol b/src/test/DSTestPlus.t.sol index 8487f84c..db108600 100644 --- a/src/test/DSTestPlus.t.sol +++ b/src/test/DSTestPlus.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; diff --git a/src/test/ERC1155.t.sol b/src/test/ERC1155.t.sol index c3d3deca..9e32d88b 100644 --- a/src/test/ERC1155.t.sol +++ b/src/test/ERC1155.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; @@ -1029,8 +1029,12 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { token.safeTransferFrom(from, to, id, transferAmount, transferData); - assertEq(token.balanceOf(to, id), transferAmount); - assertEq(token.balanceOf(from, id), mintAmount - transferAmount); + if (to == from) { + assertEq(token.balanceOf(to, id), mintAmount); + } else { + assertEq(token.balanceOf(to, id), transferAmount); + assertEq(token.balanceOf(from, id), mintAmount - transferAmount); + } } function testSafeTransferFromToERC1155Recipient( @@ -1203,7 +1207,7 @@ contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { for (uint256 i = 0; i < minLength; i++) { uint256 id = ids[i]; - address to = tos[i] == address(0) ? address(0xBEEF) : tos[i]; + address to = tos[i] == address(0) || tos[i].code.length > 0 ? address(0xBEEF) : tos[i]; uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id]; diff --git a/src/test/ERC20.t.sol b/src/test/ERC20.t.sol index 15c6f4ae..1506d8cf 100644 --- a/src/test/ERC20.t.sol +++ b/src/test/ERC20.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; @@ -172,6 +172,7 @@ contract ERC20Test is DSTestPlus { } function testFailPermitPastDeadline() public { + uint256 oldTimestamp = block.timestamp; uint256 privateKey = 0xBEEF; address owner = hevm.addr(privateKey); @@ -181,12 +182,13 @@ contract ERC20Test is DSTestPlus { abi.encodePacked( "\x19\x01", token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp - 1)) + keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, oldTimestamp)) ) ) ); - token.permit(owner, address(0xCAFE), 1e18, block.timestamp - 1, v, r, s); + hevm.warp(block.timestamp + 1); + token.permit(owner, address(0xCAFE), 1e18, oldTimestamp, v, r, s); } function testFailPermitReplay() public { diff --git a/src/test/ERC4626.t.sol b/src/test/ERC4626.t.sol index 56a17527..816c8e48 100644 --- a/src/test/ERC4626.t.sol +++ b/src/test/ERC4626.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; diff --git a/src/test/ERC721.t.sol b/src/test/ERC721.t.sol index 1f2b5098..81de0ff6 100644 --- a/src/test/ERC721.t.sol +++ b/src/test/ERC721.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; diff --git a/src/test/FixedPointMathLib.t.sol b/src/test/FixedPointMathLib.t.sol index 6e259f7c..789f957a 100644 --- a/src/test/FixedPointMathLib.t.sol +++ b/src/test/FixedPointMathLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; @@ -121,6 +121,11 @@ contract FixedPointMathLibTest is DSTestPlus { assertEq(FixedPointMathLib.sqrt(2704), 52); assertEq(FixedPointMathLib.sqrt(110889), 333); assertEq(FixedPointMathLib.sqrt(32239684), 5678); + assertEq(FixedPointMathLib.sqrt(type(uint256).max), 340282366920938463463374607431768211455); + } + + function testSqrtBackHashedSingle() public { + testSqrtBackHashed(123); } function testMulWadDown(uint256 x, uint256 y) public { @@ -263,6 +268,11 @@ contract FixedPointMathLibTest is DSTestPlus { FixedPointMathLib.mulDivUp(x, y, 0); } + function testDifferentiallyFuzzSqrt(uint256 x) public { + assertEq(FixedPointMathLib.sqrt(x), uniswapSqrt(x)); + assertEq(FixedPointMathLib.sqrt(x), abdkSqrt(x)); + } + function testSqrt(uint256 x) public { uint256 root = FixedPointMathLib.sqrt(x); uint256 next = root + 1; @@ -274,4 +284,77 @@ contract FixedPointMathLibTest is DSTestPlus { assertTrue(root * root <= x && next * next > x); } + + function testSqrtBack(uint256 x) public { + unchecked { + x >>= 128; + while (x != 0) { + assertEq(FixedPointMathLib.sqrt(x * x), x); + x >>= 1; + } + } + } + + function testSqrtBackHashed(uint256 x) public { + testSqrtBack(uint256(keccak256(abi.encode(x)))); + } + + function uniswapSqrt(uint256 y) internal pure returns (uint256 z) { + if (y > 3) { + z = y; + uint256 x = y / 2 + 1; + while (x < z) { + z = x; + x = (y / x + x) / 2; + } + } else if (y != 0) { + z = 1; + } + } + + function abdkSqrt(uint256 x) private pure returns (uint256) { + unchecked { + if (x == 0) return 0; + else { + uint256 xx = x; + uint256 r = 1; + if (xx >= 0x100000000000000000000000000000000) { + xx >>= 128; + r <<= 64; + } + if (xx >= 0x10000000000000000) { + xx >>= 64; + r <<= 32; + } + if (xx >= 0x100000000) { + xx >>= 32; + r <<= 16; + } + if (xx >= 0x10000) { + xx >>= 16; + r <<= 8; + } + if (xx >= 0x100) { + xx >>= 8; + r <<= 4; + } + if (xx >= 0x10) { + xx >>= 4; + r <<= 2; + } + if (xx >= 0x8) { + r <<= 1; + } + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; // Seven iterations should be enough + uint256 r1 = x / r; + return r < r1 ? r : r1; + } + } + } } diff --git a/src/test/LibString.t.sol b/src/test/LibString.t.sol new file mode 100644 index 00000000..36ed435d --- /dev/null +++ b/src/test/LibString.t.sol @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import {DSTestPlus} from "./utils/DSTestPlus.sol"; + +import {LibString} from "../utils/LibString.sol"; + +contract LibStringTest is DSTestPlus { + function testToString() public { + assertEq(LibString.toString(uint256(0)), "0"); + assertEq(LibString.toString(uint256(1)), "1"); + assertEq(LibString.toString(uint256(17)), "17"); + assertEq(LibString.toString(uint256(99999999)), "99999999"); + assertEq(LibString.toString(uint256(99999999999)), "99999999999"); + assertEq(LibString.toString(uint256(2342343923423)), "2342343923423"); + assertEq(LibString.toString(uint256(98765685434567)), "98765685434567"); + } + + function testToStringIntPositive() public { + assertEq(LibString.toString(int256(0)), "0"); + assertEq(LibString.toString(int256(1)), "1"); + assertEq(LibString.toString(int256(17)), "17"); + assertEq(LibString.toString(int256(99999999)), "99999999"); + assertEq(LibString.toString(int256(99999999999)), "99999999999"); + assertEq(LibString.toString(int256(2342343923423)), "2342343923423"); + assertEq(LibString.toString(int256(98765685434567)), "98765685434567"); + } + + function testToStringIntNegative() public { + assertEq(LibString.toString(int256(-0)), "0"); + assertEq(LibString.toString(int256(-17)), "-17"); + assertEq(LibString.toString(int256(-99999999)), "-99999999"); + assertEq(LibString.toString(int256(-99999999999)), "-99999999999"); + assertEq(LibString.toString(int256(-2342343923423)), "-2342343923423"); + assertEq(LibString.toString(int256(-98765685434567)), "-98765685434567"); + } + + function testDifferentiallyFuzzToString(uint256 value, bytes calldata brutalizeWith) + public + brutalizeMemory(brutalizeWith) + { + string memory libString = LibString.toString(value); + string memory oz = toStringOZ(value); + + assertEq(bytes(libString).length, bytes(oz).length); + assertEq(libString, oz); + } + + function testDifferentiallyFuzzToStringInt(int256 value, bytes calldata brutalizeWith) + public + brutalizeMemory(brutalizeWith) + { + string memory libString = LibString.toString(value); + string memory oz = toStringOZ(value); + + assertEq(bytes(libString).length, bytes(oz).length); + assertEq(libString, oz); + } + + function testToStringOverwrite() public { + string memory str = LibString.toString(uint256(1)); + + bytes32 data; + bytes32 expected; + + assembly { + // Imagine a high level allocation writing something to the current free memory. + // Should have sufficient higher order bits for this to be visible + mstore(mload(0x40), not(0)) + // Correctly allocate 32 more bytes, to avoid more interference + mstore(0x40, add(mload(0x40), 32)) + data := mload(add(str, 32)) + + // the expected value should be the uft-8 encoding of 1 (49), + // followed by clean bits. We achieve this by taking the value and + // shifting left to the end of the 32 byte word + expected := shl(248, 49) + } + + assertEq(data, expected); + } + + function testToStringDirty() public { + uint256 freememptr; + // Make the next 4 bytes of the free memory dirty + assembly { + let dirty := not(0) + freememptr := mload(0x40) + mstore(freememptr, dirty) + mstore(add(freememptr, 32), dirty) + mstore(add(freememptr, 64), dirty) + mstore(add(freememptr, 96), dirty) + mstore(add(freememptr, 128), dirty) + } + string memory str = LibString.toString(uint256(1)); + uint256 len; + bytes32 data; + bytes32 expected; + assembly { + freememptr := str + len := mload(str) + data := mload(add(str, 32)) + // the expected value should be the uft-8 encoding of 1 (49), + // followed by clean bits. We achieve this by taking the value and + // shifting left to the end of the 32 byte word + expected := shl(248, 49) + } + emit log_named_uint("str: ", freememptr); + emit log_named_uint("len: ", len); + emit log_named_bytes32("data: ", data); + assembly { + freememptr := mload(0x40) + } + emit log_named_uint("memptr: ", freememptr); + + assertEq(data, expected); + } +} + +function toStringOZ(int256 value) pure returns (string memory) { + return string(abi.encodePacked(value < 0 ? "-" : "", toStringOZ(absOZ(value)))); +} + +function toStringOZ(uint256 value) pure returns (string memory) { + if (value == 0) { + return "0"; + } + uint256 temp = value; + uint256 digits; + while (temp != 0) { + digits++; + temp /= 10; + } + bytes memory buffer = new bytes(digits); + while (value != 0) { + digits -= 1; + buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); + value /= 10; + } + return string(buffer); +} + +function absOZ(int256 n) pure returns (uint256) { + unchecked { + // must be unchecked in order to support `n = type(int256).min` + return uint256(n >= 0 ? n : -n); + } +} diff --git a/src/test/MerkleProofLib.t.sol b/src/test/MerkleProofLib.t.sol new file mode 100644 index 00000000..52796798 --- /dev/null +++ b/src/test/MerkleProofLib.t.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import {DSTestPlus} from "./utils/DSTestPlus.sol"; + +import {MerkleProofLib} from "../utils/MerkleProofLib.sol"; + +contract MerkleProofLibTest is DSTestPlus { + function testVerifyEmptyMerkleProofSuppliedLeafAndRootSame() public { + bytes32[] memory proof; + assertBoolEq(this.verify(proof, 0x00, 0x00), true); + } + + function testVerifyEmptyMerkleProofSuppliedLeafAndRootDifferent() public { + bytes32[] memory proof; + bytes32 leaf = "a"; + assertBoolEq(this.verify(proof, 0x00, leaf), false); + } + + function testValidProofSupplied() public { + // Merkle tree created from leaves ['a', 'b', 'c']. + // Leaf is 'a'. + bytes32[] memory proof = new bytes32[](2); + proof[0] = 0xb5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5510; + proof[1] = 0x0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2; + bytes32 root = 0x5842148bc6ebeb52af882a317c765fccd3ae80589b21a9b8cbf21abb630e46a7; + bytes32 leaf = 0x3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb; + assertBoolEq(this.verify(proof, root, leaf), true); + } + + function testVerifyInvalidProofSupplied() public { + // Merkle tree created from leaves ['a', 'b', 'c']. + // Leaf is 'a'. + // Proof is same as testValidProofSupplied but last byte of first element is modified. + bytes32[] memory proof = new bytes32[](2); + proof[0] = 0xb5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5511; + proof[1] = 0x0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2; + bytes32 root = 0x5842148bc6ebeb52af882a317c765fccd3ae80589b21a9b8cbf21abb630e46a7; + bytes32 leaf = 0x3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb; + assertBoolEq(this.verify(proof, root, leaf), false); + } + + function verify( + bytes32[] calldata proof, + bytes32 root, + bytes32 leaf + ) external pure returns (bool) { + return MerkleProofLib.verify(proof, root, leaf); + } +} diff --git a/src/test/MultiRolesAuthority.t.sol b/src/test/MultiRolesAuthority.t.sol index 85308875..eedf6a08 100644 --- a/src/test/MultiRolesAuthority.t.sol +++ b/src/test/MultiRolesAuthority.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; import {MockAuthority} from "./utils/mocks/MockAuthority.sol"; diff --git a/src/test/Owned.t.sol b/src/test/Owned.t.sol index 6c30c103..08a02392 100644 --- a/src/test/Owned.t.sol +++ b/src/test/Owned.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; import {MockOwned} from "./utils/mocks/MockOwned.sol"; @@ -11,8 +11,8 @@ contract OwnedTest is DSTestPlus { mockOwned = new MockOwned(); } - function testSetOwner() public { - testSetOwner(address(0xBEEF)); + function testTransferOwnership() public { + testTransferOwnership(address(0xBEEF)); } function testCallFunctionAsNonOwner() public { @@ -23,8 +23,8 @@ contract OwnedTest is DSTestPlus { mockOwned.updateFlag(); } - function testSetOwner(address newOwner) public { - mockOwned.setOwner(newOwner); + function testTransferOwnership(address newOwner) public { + mockOwned.transferOwnership(newOwner); assertEq(mockOwned.owner(), newOwner); } @@ -32,7 +32,7 @@ contract OwnedTest is DSTestPlus { function testCallFunctionAsNonOwner(address owner) public { hevm.assume(owner != address(this)); - mockOwned.setOwner(owner); + mockOwned.transferOwnership(owner); hevm.expectRevert("UNAUTHORIZED"); mockOwned.updateFlag(); diff --git a/src/test/ReentrancyGuard.t.sol b/src/test/ReentrancyGuard.t.sol index c382a51f..842e3672 100644 --- a/src/test/ReentrancyGuard.t.sol +++ b/src/test/ReentrancyGuard.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; diff --git a/src/test/RolesAuthority.t.sol b/src/test/RolesAuthority.t.sol index 88c43fcc..e01db7e5 100644 --- a/src/test/RolesAuthority.t.sol +++ b/src/test/RolesAuthority.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; import {MockAuthority} from "./utils/mocks/MockAuthority.sol"; diff --git a/src/test/SSTORE2.t.sol b/src/test/SSTORE2.t.sol index 5dbe1966..5d97ed7f 100644 --- a/src/test/SSTORE2.t.sol +++ b/src/test/SSTORE2.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; diff --git a/src/test/SafeCastLib.t.sol b/src/test/SafeCastLib.t.sol index 48a2a76f..52a6c070 100644 --- a/src/test/SafeCastLib.t.sol +++ b/src/test/SafeCastLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; @@ -11,26 +11,96 @@ contract SafeCastLibTest is DSTestPlus { assertEq(SafeCastLib.safeCastTo248(2.5e27), 2.5e27); } + function testSafeCastTo240() public { + assertEq(SafeCastLib.safeCastTo240(2.5e45), 2.5e45); + assertEq(SafeCastLib.safeCastTo240(2.5e27), 2.5e27); + } + + function testSafeCastTo232() public { + assertEq(SafeCastLib.safeCastTo232(2.5e45), 2.5e45); + assertEq(SafeCastLib.safeCastTo232(2.5e27), 2.5e27); + } + function testSafeCastTo224() public { assertEq(SafeCastLib.safeCastTo224(2.5e36), 2.5e36); assertEq(SafeCastLib.safeCastTo224(2.5e27), 2.5e27); } + function testSafeCastTo216() public { + assertEq(SafeCastLib.safeCastTo216(2.5e36), 2.5e36); + assertEq(SafeCastLib.safeCastTo216(2.5e27), 2.5e27); + } + + function testSafeCastTo208() public { + assertEq(SafeCastLib.safeCastTo208(2.5e36), 2.5e36); + assertEq(SafeCastLib.safeCastTo208(2.5e27), 2.5e27); + } + + function testSafeCastTo200() public { + assertEq(SafeCastLib.safeCastTo200(2.5e36), 2.5e36); + assertEq(SafeCastLib.safeCastTo200(2.5e27), 2.5e27); + } + function testSafeCastTo192() public { assertEq(SafeCastLib.safeCastTo192(2.5e36), 2.5e36); assertEq(SafeCastLib.safeCastTo192(2.5e27), 2.5e27); } + function testSafeCastTo184() public { + assertEq(SafeCastLib.safeCastTo184(2.5e36), 2.5e36); + assertEq(SafeCastLib.safeCastTo184(2.5e27), 2.5e27); + } + + function testSafeCastTo176() public { + assertEq(SafeCastLib.safeCastTo176(2.5e36), 2.5e36); + assertEq(SafeCastLib.safeCastTo176(2.5e27), 2.5e27); + } + + function testSafeCastTo168() public { + assertEq(SafeCastLib.safeCastTo168(2.5e36), 2.5e36); + assertEq(SafeCastLib.safeCastTo168(2.5e27), 2.5e27); + } + function testSafeCastTo160() public { assertEq(SafeCastLib.safeCastTo160(2.5e36), 2.5e36); assertEq(SafeCastLib.safeCastTo160(2.5e27), 2.5e27); } + function testSafeCastTo152() public { + assertEq(SafeCastLib.safeCastTo152(2.5e36), 2.5e36); + assertEq(SafeCastLib.safeCastTo152(2.5e27), 2.5e27); + } + + function testSafeCastTo144() public { + assertEq(SafeCastLib.safeCastTo144(2.5e36), 2.5e36); + assertEq(SafeCastLib.safeCastTo144(2.5e27), 2.5e27); + } + + function testSafeCastTo136() public { + assertEq(SafeCastLib.safeCastTo136(2.5e36), 2.5e36); + assertEq(SafeCastLib.safeCastTo136(2.5e27), 2.5e27); + } + function testSafeCastTo128() public { assertEq(SafeCastLib.safeCastTo128(2.5e27), 2.5e27); assertEq(SafeCastLib.safeCastTo128(2.5e18), 2.5e18); } + function testSafeCastTo120() public { + assertEq(SafeCastLib.safeCastTo120(2.5e27), 2.5e27); + assertEq(SafeCastLib.safeCastTo120(2.5e18), 2.5e18); + } + + function testSafeCastTo112() public { + assertEq(SafeCastLib.safeCastTo112(2.5e27), 2.5e27); + assertEq(SafeCastLib.safeCastTo112(2.5e18), 2.5e18); + } + + function testSafeCastTo104() public { + assertEq(SafeCastLib.safeCastTo104(2.5e27), 2.5e27); + assertEq(SafeCastLib.safeCastTo104(2.5e18), 2.5e18); + } + function testSafeCastTo96() public { assertEq(SafeCastLib.safeCastTo96(2.5e18), 2.5e18); assertEq(SafeCastLib.safeCastTo96(2.5e17), 2.5e17); @@ -41,11 +111,36 @@ contract SafeCastLibTest is DSTestPlus { assertEq(SafeCastLib.safeCastTo64(2.5e17), 2.5e17); } + function testSafeCastTo56() public { + assertEq(SafeCastLib.safeCastTo56(2.5e16), 2.5e16); + assertEq(SafeCastLib.safeCastTo56(2.5e15), 2.5e15); + } + + function testSafeCastTo48() public { + assertEq(SafeCastLib.safeCastTo48(2.5e12), 2.5e12); + assertEq(SafeCastLib.safeCastTo48(2.5e11), 2.5e11); + } + + function testSafeCastTo40() public { + assertEq(SafeCastLib.safeCastTo40(2.5e10), 2.5e10); + assertEq(SafeCastLib.safeCastTo40(2.5e9), 2.5e9); + } + function testSafeCastTo32() public { assertEq(SafeCastLib.safeCastTo32(2.5e8), 2.5e8); assertEq(SafeCastLib.safeCastTo32(2.5e7), 2.5e7); } + function testSafeCastTo24() public { + assertEq(SafeCastLib.safeCastTo24(2.5e4), 2.5e4); + assertEq(SafeCastLib.safeCastTo24(2.5e3), 2.5e3); + } + + function testSafeCastTo16() public { + assertEq(SafeCastLib.safeCastTo16(2.5e3), 2.5e3); + assertEq(SafeCastLib.safeCastTo16(2.5e2), 2.5e2); + } + function testSafeCastTo8() public { assertEq(SafeCastLib.safeCastTo8(100), 100); assertEq(SafeCastLib.safeCastTo8(250), 250); @@ -55,34 +150,122 @@ contract SafeCastLibTest is DSTestPlus { SafeCastLib.safeCastTo248(type(uint248).max + 1); } + function testFailSafeCastTo240() public pure { + SafeCastLib.safeCastTo240(type(uint240).max + 1); + } + + function testFailSafeCastTo232() public pure { + SafeCastLib.safeCastTo232(type(uint232).max + 1); + } + function testFailSafeCastTo224() public pure { SafeCastLib.safeCastTo224(type(uint224).max + 1); } + function testFailSafeCastTo216() public pure { + SafeCastLib.safeCastTo216(type(uint216).max + 1); + } + + function testFailSafeCastTo208() public pure { + SafeCastLib.safeCastTo208(type(uint208).max + 1); + } + + function testFailSafeCastTo200() public pure { + SafeCastLib.safeCastTo200(type(uint200).max + 1); + } + function testFailSafeCastTo192() public pure { SafeCastLib.safeCastTo192(type(uint192).max + 1); } + function testFailSafeCastTo184() public pure { + SafeCastLib.safeCastTo184(type(uint184).max + 1); + } + + function testFailSafeCastTo176() public pure { + SafeCastLib.safeCastTo176(type(uint176).max + 1); + } + + function testFailSafeCastTo168() public pure { + SafeCastLib.safeCastTo168(type(uint168).max + 1); + } + function testFailSafeCastTo160() public pure { SafeCastLib.safeCastTo160(type(uint160).max + 1); } + function testFailSafeCastTo152() public pure { + SafeCastLib.safeCastTo152(type(uint152).max + 1); + } + + function testFailSafeCastTo144() public pure { + SafeCastLib.safeCastTo144(type(uint144).max + 1); + } + + function testFailSafeCastTo136() public pure { + SafeCastLib.safeCastTo136(type(uint136).max + 1); + } + function testFailSafeCastTo128() public pure { SafeCastLib.safeCastTo128(type(uint128).max + 1); } + function testFailSafeCastTo120() public pure { + SafeCastLib.safeCastTo120(type(uint120).max + 1); + } + + function testFailSafeCastTo112() public pure { + SafeCastLib.safeCastTo112(type(uint112).max + 1); + } + + function testFailSafeCastTo104() public pure { + SafeCastLib.safeCastTo104(type(uint104).max + 1); + } + function testFailSafeCastTo96() public pure { SafeCastLib.safeCastTo96(type(uint96).max + 1); } + function testFailSafeCastTo88() public pure { + SafeCastLib.safeCastTo88(type(uint88).max + 1); + } + + function testFailSafeCastTo80() public pure { + SafeCastLib.safeCastTo80(type(uint80).max + 1); + } + + function testFailSafeCastTo72() public pure { + SafeCastLib.safeCastTo72(type(uint72).max + 1); + } + function testFailSafeCastTo64() public pure { SafeCastLib.safeCastTo64(type(uint64).max + 1); } + function testFailSafeCastTo56() public pure { + SafeCastLib.safeCastTo56(type(uint56).max + 1); + } + + function testFailSafeCastTo48() public pure { + SafeCastLib.safeCastTo48(type(uint48).max + 1); + } + + function testFailSafeCastTo40() public pure { + SafeCastLib.safeCastTo40(type(uint40).max + 1); + } + function testFailSafeCastTo32() public pure { SafeCastLib.safeCastTo32(type(uint32).max + 1); } + function testFailSafeCastTo24() public pure { + SafeCastLib.safeCastTo24(type(uint24).max + 1); + } + + function testFailSafeCastTo16() public pure { + SafeCastLib.safeCastTo16(type(uint16).max + 1); + } + function testFailSafeCastTo8() public pure { SafeCastLib.safeCastTo8(type(uint8).max + 1); } @@ -93,48 +276,180 @@ contract SafeCastLibTest is DSTestPlus { assertEq(SafeCastLib.safeCastTo248(x), x); } + function testSafeCastTo240(uint256 x) public { + x = bound(x, 0, type(uint240).max); + + assertEq(SafeCastLib.safeCastTo240(x), x); + } + + function testSafeCastTo232(uint256 x) public { + x = bound(x, 0, type(uint232).max); + + assertEq(SafeCastLib.safeCastTo232(x), x); + } + function testSafeCastTo224(uint256 x) public { x = bound(x, 0, type(uint224).max); assertEq(SafeCastLib.safeCastTo224(x), x); } + function testSafeCastTo216(uint256 x) public { + x = bound(x, 0, type(uint216).max); + + assertEq(SafeCastLib.safeCastTo216(x), x); + } + + function testSafeCastTo208(uint256 x) public { + x = bound(x, 0, type(uint208).max); + + assertEq(SafeCastLib.safeCastTo208(x), x); + } + + function testSafeCastTo200(uint256 x) public { + x = bound(x, 0, type(uint200).max); + + assertEq(SafeCastLib.safeCastTo200(x), x); + } + function testSafeCastTo192(uint256 x) public { x = bound(x, 0, type(uint192).max); assertEq(SafeCastLib.safeCastTo192(x), x); } + function testSafeCastTo184(uint256 x) public { + x = bound(x, 0, type(uint184).max); + + assertEq(SafeCastLib.safeCastTo184(x), x); + } + + function testSafeCastTo176(uint256 x) public { + x = bound(x, 0, type(uint176).max); + + assertEq(SafeCastLib.safeCastTo176(x), x); + } + + function testSafeCastTo168(uint256 x) public { + x = bound(x, 0, type(uint168).max); + + assertEq(SafeCastLib.safeCastTo168(x), x); + } + function testSafeCastTo160(uint256 x) public { x = bound(x, 0, type(uint160).max); assertEq(SafeCastLib.safeCastTo160(x), x); } + function testSafeCastTo152(uint256 x) public { + x = bound(x, 0, type(uint152).max); + + assertEq(SafeCastLib.safeCastTo152(x), x); + } + + function testSafeCastTo144(uint256 x) public { + x = bound(x, 0, type(uint144).max); + + assertEq(SafeCastLib.safeCastTo144(x), x); + } + + function testSafeCastTo136(uint256 x) public { + x = bound(x, 0, type(uint136).max); + + assertEq(SafeCastLib.safeCastTo136(x), x); + } + function testSafeCastTo128(uint256 x) public { x = bound(x, 0, type(uint128).max); assertEq(SafeCastLib.safeCastTo128(x), x); } + function testSafeCastTo120(uint256 x) public { + x = bound(x, 0, type(uint120).max); + + assertEq(SafeCastLib.safeCastTo120(x), x); + } + + function testSafeCastTo112(uint256 x) public { + x = bound(x, 0, type(uint112).max); + + assertEq(SafeCastLib.safeCastTo112(x), x); + } + + function testSafeCastTo104(uint256 x) public { + x = bound(x, 0, type(uint104).max); + + assertEq(SafeCastLib.safeCastTo104(x), x); + } + function testSafeCastTo96(uint256 x) public { x = bound(x, 0, type(uint96).max); assertEq(SafeCastLib.safeCastTo96(x), x); } + function testSafeCastTo88(uint256 x) public { + x = bound(x, 0, type(uint88).max); + + assertEq(SafeCastLib.safeCastTo88(x), x); + } + + function testSafeCastTo80(uint256 x) public { + x = bound(x, 0, type(uint80).max); + + assertEq(SafeCastLib.safeCastTo80(x), x); + } + + function testSafeCastTo72(uint256 x) public { + x = bound(x, 0, type(uint72).max); + + assertEq(SafeCastLib.safeCastTo72(x), x); + } + function testSafeCastTo64(uint256 x) public { x = bound(x, 0, type(uint64).max); assertEq(SafeCastLib.safeCastTo64(x), x); } + function testSafeCastTo56(uint256 x) public { + x = bound(x, 0, type(uint56).max); + + assertEq(SafeCastLib.safeCastTo56(x), x); + } + + function testSafeCastTo48(uint256 x) public { + x = bound(x, 0, type(uint48).max); + + assertEq(SafeCastLib.safeCastTo48(x), x); + } + + function testSafeCastTo40(uint256 x) public { + x = bound(x, 0, type(uint40).max); + + assertEq(SafeCastLib.safeCastTo40(x), x); + } + function testSafeCastTo32(uint256 x) public { x = bound(x, 0, type(uint32).max); assertEq(SafeCastLib.safeCastTo32(x), x); } + function testSafeCastTo24(uint256 x) public { + x = bound(x, 0, type(uint24).max); + + assertEq(SafeCastLib.safeCastTo24(x), x); + } + + function testSafeCastTo16(uint256 x) public { + x = bound(x, 0, type(uint16).max); + + assertEq(SafeCastLib.safeCastTo16(x), x); + } + function testSafeCastTo8(uint256 x) public { x = bound(x, 0, type(uint8).max); @@ -147,48 +462,180 @@ contract SafeCastLibTest is DSTestPlus { SafeCastLib.safeCastTo248(x); } + function testFailSafeCastTo240(uint256 x) public { + x = bound(x, type(uint240).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo240(x); + } + + function testFailSafeCastTo232(uint256 x) public { + x = bound(x, type(uint232).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo232(x); + } + function testFailSafeCastTo224(uint256 x) public { x = bound(x, type(uint224).max + 1, type(uint256).max); SafeCastLib.safeCastTo224(x); } + function testFailSafeCastTo216(uint256 x) public { + x = bound(x, type(uint216).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo216(x); + } + + function testFailSafeCastTo208(uint256 x) public { + x = bound(x, type(uint208).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo208(x); + } + + function testFailSafeCastTo200(uint256 x) public { + x = bound(x, type(uint200).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo200(x); + } + function testFailSafeCastTo192(uint256 x) public { x = bound(x, type(uint192).max + 1, type(uint256).max); SafeCastLib.safeCastTo192(x); } + function testFailSafeCastTo184(uint256 x) public { + x = bound(x, type(uint184).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo184(x); + } + + function testFailSafeCastTo176(uint256 x) public { + x = bound(x, type(uint176).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo176(x); + } + + function testFailSafeCastTo168(uint256 x) public { + x = bound(x, type(uint168).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo168(x); + } + function testFailSafeCastTo160(uint256 x) public { x = bound(x, type(uint160).max + 1, type(uint256).max); SafeCastLib.safeCastTo160(x); } + function testFailSafeCastTo152(uint256 x) public { + x = bound(x, type(uint152).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo152(x); + } + + function testFailSafeCastTo144(uint256 x) public { + x = bound(x, type(uint144).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo144(x); + } + + function testFailSafeCastTo136(uint256 x) public { + x = bound(x, type(uint136).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo136(x); + } + function testFailSafeCastTo128(uint256 x) public { x = bound(x, type(uint128).max + 1, type(uint256).max); SafeCastLib.safeCastTo128(x); } + function testFailSafeCastTo120(uint256 x) public { + x = bound(x, type(uint120).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo120(x); + } + + function testFailSafeCastTo112(uint256 x) public { + x = bound(x, type(uint112).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo112(x); + } + + function testFailSafeCastTo104(uint256 x) public { + x = bound(x, type(uint104).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo104(x); + } + function testFailSafeCastTo96(uint256 x) public { x = bound(x, type(uint96).max + 1, type(uint256).max); SafeCastLib.safeCastTo96(x); } + function testFailSafeCastTo88(uint256 x) public { + x = bound(x, type(uint88).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo88(x); + } + + function testFailSafeCastTo80(uint256 x) public { + x = bound(x, type(uint80).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo80(x); + } + + function testFailSafeCastTo72(uint256 x) public { + x = bound(x, type(uint72).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo72(x); + } + function testFailSafeCastTo64(uint256 x) public { x = bound(x, type(uint64).max + 1, type(uint256).max); SafeCastLib.safeCastTo64(x); } + function testFailSafeCastTo56(uint256 x) public { + x = bound(x, type(uint56).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo56(x); + } + + function testFailSafeCastTo48(uint256 x) public { + x = bound(x, type(uint48).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo48(x); + } + + function testFailSafeCastTo40(uint256 x) public { + x = bound(x, type(uint40).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo40(x); + } + function testFailSafeCastTo32(uint256 x) public { x = bound(x, type(uint32).max + 1, type(uint256).max); SafeCastLib.safeCastTo32(x); } + function testFailSafeCastTo24(uint256 x) public { + x = bound(x, type(uint24).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo24(x); + } + + function testFailSafeCastTo16(uint256 x) public { + x = bound(x, type(uint16).max + 1, type(uint256).max); + + SafeCastLib.safeCastTo16(x); + } + function testFailSafeCastTo8(uint256 x) public { x = bound(x, type(uint8).max + 1, type(uint256).max); diff --git a/src/test/SafeTransferLib.t.sol b/src/test/SafeTransferLib.t.sol index ebae33a3..b976e9f6 100644 --- a/src/test/SafeTransferLib.t.sol +++ b/src/test/SafeTransferLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {MockERC20} from "./utils/mocks/MockERC20.sol"; import {RevertingToken} from "./utils/weird-tokens/RevertingToken.sol"; diff --git a/src/test/SignedWadMath.t.sol b/src/test/SignedWadMath.t.sol new file mode 100644 index 00000000..ec5b6f3b --- /dev/null +++ b/src/test/SignedWadMath.t.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import {DSTestPlus} from "./utils/DSTestPlus.sol"; + +import {wadMul, wadDiv} from "../utils/SignedWadMath.sol"; + +contract SignedWadMathTest is DSTestPlus { + function testWadMul( + uint256 x, + uint256 y, + bool negX, + bool negY + ) public { + x = bound(x, 0, 99999999999999e18); + y = bound(x, 0, 99999999999999e18); + + int256 xPrime = negX ? -int256(x) : int256(x); + int256 yPrime = negY ? -int256(y) : int256(y); + + assertEq(wadMul(xPrime, yPrime), (xPrime * yPrime) / 1e18); + } + + function testFailWadMulOverflow(int256 x, int256 y) public pure { + // Ignore cases where x * y does not overflow. + unchecked { + if ((x * y) / x == y) revert(); + } + + wadMul(x, y); + } + + function testWadDiv( + uint256 x, + uint256 y, + bool negX, + bool negY + ) public { + x = bound(x, 0, 99999999e18); + y = bound(x, 1, 99999999e18); + + int256 xPrime = negX ? -int256(x) : int256(x); + int256 yPrime = negY ? -int256(y) : int256(y); + + assertEq(wadDiv(xPrime, yPrime), (xPrime * 1e18) / yPrime); + } + + function testFailWadDivOverflow(int256 x, int256 y) public pure { + // Ignore cases where x * WAD does not overflow or y is 0. + unchecked { + if (y == 0 || (x * 1e18) / 1e18 == x) revert(); + } + + wadDiv(x, y); + } + + function testFailWadDivZeroDenominator(int256 x) public pure { + wadDiv(x, 0); + } +} diff --git a/src/test/WETH.t.sol b/src/test/WETH.t.sol index f2d8b9e1..a13761ee 100644 --- a/src/test/WETH.t.sol +++ b/src/test/WETH.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.10; +pragma solidity 0.8.15; import {DSTestPlus} from "./utils/DSTestPlus.sol"; import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; @@ -15,7 +15,7 @@ contract WETHTest is DSTestPlus { weth = new WETH(); } - function testDeposit() public { + function testFallbackDeposit() public { assertEq(weth.balanceOf(address(this)), 0); assertEq(weth.totalSupply(), 0); @@ -25,7 +25,7 @@ contract WETHTest is DSTestPlus { assertEq(weth.totalSupply(), 1 ether); } - function testFallbackDeposit() public { + function testDeposit() public { assertEq(weth.balanceOf(address(this)), 0); assertEq(weth.totalSupply(), 0); @@ -63,7 +63,7 @@ contract WETHTest is DSTestPlus { assertEq(weth.totalSupply(), 0.5 ether); } - function testDeposit(uint256 amount) public { + function testFallbackDeposit(uint256 amount) public { amount = bound(amount, 0, address(this).balance); assertEq(weth.balanceOf(address(this)), 0); @@ -75,7 +75,7 @@ contract WETHTest is DSTestPlus { assertEq(weth.totalSupply(), amount); } - function testFallbackDeposit(uint256 amount) public { + function testDeposit(uint256 amount) public { amount = bound(amount, 0, address(this).balance); assertEq(weth.balanceOf(address(this)), 0); diff --git a/src/test/utils/DSTestPlus.sol b/src/test/utils/DSTestPlus.sol index bb1772d4..b56d4c9b 100644 --- a/src/test/utils/DSTestPlus.sol +++ b/src/test/utils/DSTestPlus.sol @@ -6,7 +6,7 @@ import {DSTest} from "ds-test/test.sol"; import {Hevm} from "./Hevm.sol"; /// @notice Extended testing framework for DappTools projects. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/test/utils/DSTestPlus.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/test/utils/DSTestPlus.sol) contract DSTestPlus is DSTest { Hevm internal constant hevm = Hevm(HEVM_ADDRESS); @@ -149,7 +149,7 @@ contract DSTestPlus is DSTest { uint256 x, uint256 min, uint256 max - ) internal returns (uint256 result) { + ) internal virtual returns (uint256 result) { require(max >= min, "MAX_LESS_THAN_MIN"); uint256 size = max - min; diff --git a/src/tokens/ERC1155.sol b/src/tokens/ERC1155.sol index 70c4d2d0..cff0f02d 100644 --- a/src/tokens/ERC1155.sol +++ b/src/tokens/ERC1155.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; /// @notice Minimalist and gas efficient standard ERC1155 implementation. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155 { /*////////////////////////////////////////////////////////////// EVENTS @@ -233,7 +233,7 @@ abstract contract ERC1155 { } /// @notice A generic interface for a contract which properly accepts ERC1155 tokens. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155TokenReceiver { function onERC1155Received( address, diff --git a/src/tokens/ERC20.sol b/src/tokens/ERC20.sol index 110314b5..e3a1d242 100644 --- a/src/tokens/ERC20.sol +++ b/src/tokens/ERC20.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { @@ -38,9 +38,9 @@ abstract contract ERC20 { EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ - uint256 internal immutable INITIAL_CHAIN_ID; + uint256 internal immutable INITIAL_CHAIN_ID = block.chainid; - bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; + bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); mapping(address => uint256) public nonces; @@ -56,9 +56,6 @@ abstract contract ERC20 { name = _name; symbol = _symbol; decimals = _decimals; - - INITIAL_CHAIN_ID = block.chainid; - INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// diff --git a/src/tokens/ERC721.sol b/src/tokens/ERC721.sol index 13309b73..b47f2712 100644 --- a/src/tokens/ERC721.sol +++ b/src/tokens/ERC721.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; /// @notice Modern, minimalist, and gas efficient ERC-721 implementation. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721 { /*////////////////////////////////////////////////////////////// EVENTS @@ -218,7 +218,7 @@ abstract contract ERC721 { } /// @notice A generic interface for a contract which properly accepts ERC721 tokens. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721TokenReceiver { function onERC721Received( address, diff --git a/src/tokens/WETH.sol b/src/tokens/WETH.sol index 5c470e37..ddf9647d 100644 --- a/src/tokens/WETH.sol +++ b/src/tokens/WETH.sol @@ -6,7 +6,7 @@ import {ERC20} from "./ERC20.sol"; import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; /// @notice Minimalist and modern Wrapped Ether implementation. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/WETH.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/WETH.sol) /// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol) contract WETH is ERC20("Wrapped Ether", "WETH", 18) { using SafeTransferLib for address; diff --git a/src/utils/Bytes32AddressLib.sol b/src/utils/Bytes32AddressLib.sol index bc857be1..448fb759 100644 --- a/src/utils/Bytes32AddressLib.sol +++ b/src/utils/Bytes32AddressLib.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; /// @notice Library for converting between addresses and bytes32 values. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Bytes32AddressLib.sol) library Bytes32AddressLib { function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) { return address(uint160(uint256(bytesValue))); diff --git a/src/utils/CREATE3.sol b/src/utils/CREATE3.sol index 04e09155..0d5b341e 100644 --- a/src/utils/CREATE3.sol +++ b/src/utils/CREATE3.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.0; import {Bytes32AddressLib} from "./Bytes32AddressLib.sol"; /// @notice Deploy to deterministic addresses without an initcode factor. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/CREATE3.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/CREATE3.sol) /// @author Modified from 0xSequence (https://github.com/0xSequence/create3/blob/master/contracts/Create3.sol) library CREATE3 { using Bytes32AddressLib for bytes32; @@ -42,6 +42,7 @@ library CREATE3 { bytes memory proxyChildBytecode = PROXY_BYTECODE; address proxy; + /// @solidity memory-safe-assembly assembly { // Deploy a new contract with our pre-made bytecode via CREATE2. // We start 32 bytes into the code to avoid copying the byte length. diff --git a/src/utils/FixedPointMathLib.sol b/src/utils/FixedPointMathLib.sol index b4486907..68877227 100644 --- a/src/utils/FixedPointMathLib.sol +++ b/src/utils/FixedPointMathLib.sol @@ -2,13 +2,15 @@ pragma solidity >=0.8.0; /// @notice Arithmetic library with operations for fixed-point numbers. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol) /// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol) library FixedPointMathLib { /*////////////////////////////////////////////////////////////// SIMPLIFIED FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ + uint256 internal constant MAX_UINT256 = 2**256 - 1; + uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { @@ -36,17 +38,15 @@ library FixedPointMathLib { uint256 y, uint256 denominator ) internal pure returns (uint256 z) { + /// @solidity memory-safe-assembly assembly { - // Store x * y in z for now. - z := mul(x, y) - - // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) - if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { + // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) + if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } - // Divide z by the denominator. - z := div(z, denominator) + // Divide x * y by the denominator. + z := div(mul(x, y), denominator) } } @@ -55,19 +55,16 @@ library FixedPointMathLib { uint256 y, uint256 denominator ) internal pure returns (uint256 z) { + /// @solidity memory-safe-assembly assembly { - // Store x * y in z for now. - z := mul(x, y) - - // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) - if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { + // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) + if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } - // First, divide z - 1 by the denominator and add 1. - // We allow z - 1 to underflow if z is 0, because we multiply the - // end result by 0 if z is zero, ensuring we return 0 if z is zero. - z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1)) + // If x * y modulo the denominator is strictly greater than 0, + // 1 is added to round up the division of x * y by the denominator. + z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator)) } } @@ -76,6 +73,7 @@ library FixedPointMathLib { uint256 n, uint256 scalar ) internal pure returns (uint256 z) { + /// @solidity memory-safe-assembly assembly { switch x case 0 { @@ -164,44 +162,53 @@ library FixedPointMathLib { //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { + /// @solidity memory-safe-assembly assembly { - // Start off with z at 1. - z := 1 + let y := x // We start y at x, which will help us make our initial estimate. - // Used below to help find a nearby power of 2. - let y := x + z := 181 // The "correct" value is 1, but this saves a multiplication later. - // Find the lowest power of 2 that is at least sqrt(x). - if iszero(lt(y, 0x100000000000000000000000000000000)) { - y := shr(128, y) // Like dividing by 2 ** 128. - z := shl(64, z) // Like multiplying by 2 ** 64. - } - if iszero(lt(y, 0x10000000000000000)) { - y := shr(64, y) // Like dividing by 2 ** 64. - z := shl(32, z) // Like multiplying by 2 ** 32. - } - if iszero(lt(y, 0x100000000)) { - y := shr(32, y) // Like dividing by 2 ** 32. - z := shl(16, z) // Like multiplying by 2 ** 16. - } - if iszero(lt(y, 0x10000)) { - y := shr(16, y) // Like dividing by 2 ** 16. - z := shl(8, z) // Like multiplying by 2 ** 8. + // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad + // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically. + + // We check y >= 2^(k + 8) but shift right by k bits + // each branch to ensure that if x >= 256, then y >= 256. + if iszero(lt(y, 0x10000000000000000000000000000000000)) { + y := shr(128, y) + z := shl(64, z) } - if iszero(lt(y, 0x100)) { - y := shr(8, y) // Like dividing by 2 ** 8. - z := shl(4, z) // Like multiplying by 2 ** 4. + if iszero(lt(y, 0x1000000000000000000)) { + y := shr(64, y) + z := shl(32, z) } - if iszero(lt(y, 0x10)) { - y := shr(4, y) // Like dividing by 2 ** 4. - z := shl(2, z) // Like multiplying by 2 ** 2. + if iszero(lt(y, 0x10000000000)) { + y := shr(32, y) + z := shl(16, z) } - if iszero(lt(y, 0x8)) { - // Equivalent to 2 ** z. - z := shl(1, z) + if iszero(lt(y, 0x1000000)) { + y := shr(16, y) + z := shl(8, z) } - // Shifting right by 1 is like dividing by 2. + // Goal was to get z*z*y within a small factor of x. More iterations could + // get y in a tighter range. Currently, we will have y in [256, 256*2^16). + // We ensured y >= 256 so that the relative difference between y and y+1 is small. + // That's not possible if x < 256 but we can just verify those cases exhaustively. + + // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. + // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. + // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. + + // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range + // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. + + // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate + // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. + + // There is no overflow risk here since y < 2^136 after the first branch above. + z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181. + + // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) @@ -210,13 +217,39 @@ library FixedPointMathLib { z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) - // Compute a rounded down version of z. - let zRoundDown := div(x, z) + // If x+1 is a perfect square, the Babylonian method cycles between + // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. + // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division + // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. + // If you don't care whether the floor or ceil square root is returned, you can remove this statement. + z := sub(z, lt(div(x, z), z)) + } + } - // If zRoundDown is smaller, use it. - if lt(zRoundDown, z) { - z := zRoundDown - } + function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { + /// @solidity memory-safe-assembly + assembly { + // Mod x by y. Note this will return + // 0 instead of reverting if y is zero. + z := mod(x, y) + } + } + + function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) { + /// @solidity memory-safe-assembly + assembly { + // Divide x by y. Note this will return + // 0 instead of reverting if y is zero. + r := div(x, y) + } + } + + function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { + /// @solidity memory-safe-assembly + assembly { + // Add 1 to x * y if x % y > 0. Note this will + // return 0 instead of reverting if y is zero. + z := add(gt(mod(x, y), 0), div(x, y)) } } } diff --git a/src/utils/LibString.sol b/src/utils/LibString.sol new file mode 100644 index 00000000..97c89e0b --- /dev/null +++ b/src/utils/LibString.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/// @notice Efficient library for creating string representations of integers. +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) +/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol) +library LibString { + function toString(int256 value) internal pure returns (string memory str) { + if (value >= 0) return toString(uint256(value)); + + unchecked { + str = toString(uint256(-value)); + + /// @solidity memory-safe-assembly + assembly { + // Note: This is only safe because we over-allocate memory + // and write the string from right to left in toString(uint256), + // and thus can be sure that sub(str, 1) is an unused memory location. + + let length := mload(str) // Load the string length. + // Put the - character at the start of the string contents. + mstore(str, 45) // 45 is the ASCII code for the - character. + str := sub(str, 1) // Move back the string pointer by a byte. + mstore(str, add(length, 1)) // Update the string length. + } + } + } + + function toString(uint256 value) internal pure returns (string memory str) { + /// @solidity memory-safe-assembly + assembly { + // The maximum value of a uint256 contains 78 digits (1 byte per digit), but we allocate 160 bytes + // to keep the free memory pointer word aligned. We'll need 1 word for the length, 1 word for the + // trailing zeros padding, and 3 other words for a max of 78 digits. In total: 5 * 32 = 160 bytes. + let newFreeMemoryPointer := add(mload(0x40), 160) + + // Update the free memory pointer to avoid overriding our string. + mstore(0x40, newFreeMemoryPointer) + + // Assign str to the end of the zone of newly allocated memory. + str := sub(newFreeMemoryPointer, 32) + + // Clean the last word of memory it may not be overwritten. + mstore(str, 0) + + // Cache the end of the memory to calculate the length later. + let end := str + + // We write the string from rightmost digit to leftmost digit. + // The following is essentially a do-while loop that also handles the zero case. + // prettier-ignore + for { let temp := value } 1 {} { + // Move the pointer 1 byte to the left. + str := sub(str, 1) + + // Write the character to the pointer. + // The ASCII index of the '0' character is 48. + mstore8(str, add(48, mod(temp, 10))) + + // Keep dividing temp until zero. + temp := div(temp, 10) + + // prettier-ignore + if iszero(temp) { break } + } + + // Compute and cache the final total length of the string. + let length := sub(end, str) + + // Move the pointer 32 bytes leftwards to make room for the length. + str := sub(str, 32) + + // Store the string's length at the start of memory allocated for our string. + mstore(str, length) + } + } +} diff --git a/src/utils/MerkleProofLib.sol b/src/utils/MerkleProofLib.sol new file mode 100644 index 00000000..8fd7cbd7 --- /dev/null +++ b/src/utils/MerkleProofLib.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/// @notice Gas optimized merkle proof verification library. +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol) +/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/MerkleProofLib.sol) +library MerkleProofLib { + function verify( + bytes32[] calldata proof, + bytes32 root, + bytes32 leaf + ) internal pure returns (bool isValid) { + /// @solidity memory-safe-assembly + assembly { + if proof.length { + // Left shifting by 5 is like multiplying by 32. + let end := add(proof.offset, shl(5, proof.length)) + + // Initialize offset to the offset of the proof in calldata. + let offset := proof.offset + + // Iterate over proof elements to compute root hash. + // prettier-ignore + for {} 1 {} { + // Slot where the leaf should be put in scratch space. If + // leaf > calldataload(offset): slot 32, otherwise: slot 0. + let leafSlot := shl(5, gt(leaf, calldataload(offset))) + + // Store elements to hash contiguously in scratch space. + // The xor puts calldataload(offset) in whichever slot leaf + // is not occupying, so 0 if leafSlot is 32, and 32 otherwise. + mstore(leafSlot, leaf) + mstore(xor(leafSlot, 32), calldataload(offset)) + + // Reuse leaf to store the hash to reduce stack operations. + leaf := keccak256(0, 64) // Hash both slots of scratch space. + + offset := add(offset, 32) // Shift 1 word per cycle. + + // prettier-ignore + if iszero(lt(offset, end)) { break } + } + } + + isValid := eq(leaf, root) // The proof is valid if the roots match. + } + } +} diff --git a/src/utils/ReentrancyGuard.sol b/src/utils/ReentrancyGuard.sol index 99aa4624..1453e24c 100644 --- a/src/utils/ReentrancyGuard.sol +++ b/src/utils/ReentrancyGuard.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; /// @notice Gas optimized reentrancy protection for smart contracts. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol) abstract contract ReentrancyGuard { uint256 private locked = 1; diff --git a/src/utils/SSTORE2.sol b/src/utils/SSTORE2.sol index bc10d72f..23d69803 100644 --- a/src/utils/SSTORE2.sol +++ b/src/utils/SSTORE2.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; /// @notice Read and write to persistent storage at a fraction of the cost. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SSTORE2.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol) /// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol) library SSTORE2 { uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called. @@ -34,6 +34,7 @@ library SSTORE2 { runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit. ); + /// @solidity memory-safe-assembly assembly { // Deploy a new contract with the generated creation code. // We start 32 bytes into the code to avoid copying the byte length. @@ -79,6 +80,7 @@ library SSTORE2 { uint256 start, uint256 size ) private view returns (bytes memory data) { + /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. data := mload(0x40) diff --git a/src/utils/SafeCastLib.sol b/src/utils/SafeCastLib.sol index ab4287f7..9e8a2af0 100644 --- a/src/utils/SafeCastLib.sol +++ b/src/utils/SafeCastLib.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; /// @notice Safe unsigned integer casting library that reverts on overflow. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeCastLib.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeCastLib.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol) library SafeCastLib { function safeCastTo248(uint256 x) internal pure returns (uint248 y) { @@ -11,48 +11,180 @@ library SafeCastLib { y = uint248(x); } + function safeCastTo240(uint256 x) internal pure returns (uint240 y) { + require(x < 1 << 240); + + y = uint240(x); + } + + function safeCastTo232(uint256 x) internal pure returns (uint232 y) { + require(x < 1 << 232); + + y = uint232(x); + } + function safeCastTo224(uint256 x) internal pure returns (uint224 y) { require(x < 1 << 224); y = uint224(x); } + function safeCastTo216(uint256 x) internal pure returns (uint216 y) { + require(x < 1 << 216); + + y = uint216(x); + } + + function safeCastTo208(uint256 x) internal pure returns (uint208 y) { + require(x < 1 << 208); + + y = uint208(x); + } + + function safeCastTo200(uint256 x) internal pure returns (uint200 y) { + require(x < 1 << 200); + + y = uint200(x); + } + function safeCastTo192(uint256 x) internal pure returns (uint192 y) { require(x < 1 << 192); y = uint192(x); } + function safeCastTo184(uint256 x) internal pure returns (uint184 y) { + require(x < 1 << 184); + + y = uint184(x); + } + + function safeCastTo176(uint256 x) internal pure returns (uint176 y) { + require(x < 1 << 176); + + y = uint176(x); + } + + function safeCastTo168(uint256 x) internal pure returns (uint168 y) { + require(x < 1 << 168); + + y = uint168(x); + } + function safeCastTo160(uint256 x) internal pure returns (uint160 y) { require(x < 1 << 160); y = uint160(x); } + function safeCastTo152(uint256 x) internal pure returns (uint152 y) { + require(x < 1 << 152); + + y = uint152(x); + } + + function safeCastTo144(uint256 x) internal pure returns (uint144 y) { + require(x < 1 << 144); + + y = uint144(x); + } + + function safeCastTo136(uint256 x) internal pure returns (uint136 y) { + require(x < 1 << 136); + + y = uint136(x); + } + function safeCastTo128(uint256 x) internal pure returns (uint128 y) { require(x < 1 << 128); y = uint128(x); } + function safeCastTo120(uint256 x) internal pure returns (uint120 y) { + require(x < 1 << 120); + + y = uint120(x); + } + + function safeCastTo112(uint256 x) internal pure returns (uint112 y) { + require(x < 1 << 112); + + y = uint112(x); + } + + function safeCastTo104(uint256 x) internal pure returns (uint104 y) { + require(x < 1 << 104); + + y = uint104(x); + } + function safeCastTo96(uint256 x) internal pure returns (uint96 y) { require(x < 1 << 96); y = uint96(x); } + function safeCastTo88(uint256 x) internal pure returns (uint88 y) { + require(x < 1 << 88); + + y = uint88(x); + } + + function safeCastTo80(uint256 x) internal pure returns (uint80 y) { + require(x < 1 << 80); + + y = uint80(x); + } + + function safeCastTo72(uint256 x) internal pure returns (uint72 y) { + require(x < 1 << 72); + + y = uint72(x); + } + function safeCastTo64(uint256 x) internal pure returns (uint64 y) { require(x < 1 << 64); y = uint64(x); } + function safeCastTo56(uint256 x) internal pure returns (uint56 y) { + require(x < 1 << 56); + + y = uint56(x); + } + + function safeCastTo48(uint256 x) internal pure returns (uint48 y) { + require(x < 1 << 48); + + y = uint48(x); + } + + function safeCastTo40(uint256 x) internal pure returns (uint40 y) { + require(x < 1 << 40); + + y = uint40(x); + } + function safeCastTo32(uint256 x) internal pure returns (uint32 y) { require(x < 1 << 32); y = uint32(x); } + function safeCastTo24(uint256 x) internal pure returns (uint24 y) { + require(x < 1 << 24); + + y = uint24(x); + } + + function safeCastTo16(uint256 x) internal pure returns (uint16 y) { + require(x < 1 << 16); + + y = uint16(x); + } + function safeCastTo8(uint256 x) internal pure returns (uint8 y) { require(x < 1 << 8); diff --git a/src/utils/SafeTransferLib.sol b/src/utils/SafeTransferLib.sol index 44770856..93ef5a91 100644 --- a/src/utils/SafeTransferLib.sol +++ b/src/utils/SafeTransferLib.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. -/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol) +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. /// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. library SafeTransferLib { @@ -15,6 +15,7 @@ library SafeTransferLib { function safeTransferETH(address to, uint256 amount) internal { bool success; + /// @solidity memory-safe-assembly assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) @@ -35,15 +36,16 @@ library SafeTransferLib { ) internal { bool success; + /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument. - mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument. - mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. + mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument. + mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. + mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either @@ -67,14 +69,15 @@ library SafeTransferLib { ) internal { bool success; + /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. - mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. + mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. + mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either @@ -98,14 +101,15 @@ library SafeTransferLib { ) internal { bool success; + /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. - mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. + mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. + mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either diff --git a/src/utils/SignedWadMath.sol b/src/utils/SignedWadMath.sol new file mode 100644 index 00000000..4344285c --- /dev/null +++ b/src/utils/SignedWadMath.sol @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/// @notice Signed 18 decimal fixed point (wad) arithmetic library. +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SignedWadMath.sol) +/// @author Modified from Remco Bloemen (https://xn--2-umb.com/22/exp-ln/index.html) + +/// @dev Will not revert on overflow, only use where overflow is not possible. +function toWadUnsafe(uint256 x) pure returns (int256 r) { + /// @solidity memory-safe-assembly + assembly { + // Multiply x by 1e18. + r := mul(x, 1000000000000000000) + } +} + +/// @dev Takes an integer amount of seconds and converts it to a wad amount of days. +/// @dev Will not revert on overflow, only use where overflow is not possible. +/// @dev Not meant for negative second amounts, it assumes x is positive. +function toDaysWadUnsafe(uint256 x) pure returns (int256 r) { + /// @solidity memory-safe-assembly + assembly { + // Multiply x by 1e18 and then divide it by 86400. + r := div(mul(x, 1000000000000000000), 86400) + } +} + +/// @dev Takes a wad amount of days and converts it to an integer amount of seconds. +/// @dev Will not revert on overflow, only use where overflow is not possible. +/// @dev Not meant for negative day amounts, it assumes x is positive. +function fromDaysWadUnsafe(int256 x) pure returns (uint256 r) { + /// @solidity memory-safe-assembly + assembly { + // Multiply x by 86400 and then divide it by 1e18. + r := div(mul(x, 86400), 1000000000000000000) + } +} + +/// @dev Will not revert on overflow, only use where overflow is not possible. +function unsafeWadMul(int256 x, int256 y) pure returns (int256 r) { + /// @solidity memory-safe-assembly + assembly { + // Multiply x by y and divide by 1e18. + r := sdiv(mul(x, y), 1000000000000000000) + } +} + +/// @dev Will return 0 instead of reverting if y is zero and will +/// not revert on overflow, only use where overflow is not possible. +function unsafeWadDiv(int256 x, int256 y) pure returns (int256 r) { + /// @solidity memory-safe-assembly + assembly { + // Multiply x by 1e18 and divide it by y. + r := sdiv(mul(x, 1000000000000000000), y) + } +} + +function wadMul(int256 x, int256 y) pure returns (int256 r) { + /// @solidity memory-safe-assembly + assembly { + // Store x * y in r for now. + r := mul(x, y) + + // Equivalent to require(x == 0 || (x * y) / x == y) + if iszero(or(iszero(x), eq(sdiv(r, x), y))) { + revert(0, 0) + } + + // Scale the result down by 1e18. + r := sdiv(r, 1000000000000000000) + } +} + +function wadDiv(int256 x, int256 y) pure returns (int256 r) { + /// @solidity memory-safe-assembly + assembly { + // Store x * 1e18 in r for now. + r := mul(x, 1000000000000000000) + + // Equivalent to require(y != 0 && ((x * 1e18) / 1e18 == x)) + if iszero(and(iszero(iszero(y)), eq(sdiv(r, 1000000000000000000), x))) { + revert(0, 0) + } + + // Divide r by y. + r := sdiv(r, y) + } +} + +/// @dev Will not work with negative bases, only use when x is positive. +function wadPow(int256 x, int256 y) pure returns (int256) { + // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y) + return wadExp((wadLn(x) * y) / 1e18); // Using ln(x) means x must be greater than 0. +} + +function wadExp(int256 x) pure returns (int256 r) { + unchecked { + // When the result is < 0.5 we return zero. This happens when + // x <= floor(log(0.5e18) * 1e18) ~ -42e18 + if (x <= -42139678854452767551) return 0; + + // When the result is > (2**255 - 1) / 1e18 we can not represent it as an + // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135. + if (x >= 135305999368893231589) revert("EXP_OVERFLOW"); + + // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96 + // for more intermediate precision and a binary basis. This base conversion + // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78. + x = (x << 78) / 5**18; + + // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers + // of two such that exp(x) = exp(x') * 2**k, where k is an integer. + // Solving this gives k = round(x / log(2)) and x' = x - k * log(2). + int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96; + x = x - k * 54916777467707473351141471128; + + // k is in the range [-61, 195]. + + // Evaluate using a (6, 7)-term rational approximation. + // p is made monic, we'll multiply by a scale factor later. + int256 y = x + 1346386616545796478920950773328; + y = ((y * x) >> 96) + 57155421227552351082224309758442; + int256 p = y + x - 94201549194550492254356042504812; + p = ((p * y) >> 96) + 28719021644029726153956944680412240; + p = p * x + (4385272521454847904659076985693276 << 96); + + // We leave p in 2**192 basis so we don't need to scale it back up for the division. + int256 q = x - 2855989394907223263936484059900; + q = ((q * x) >> 96) + 50020603652535783019961831881945; + q = ((q * x) >> 96) - 533845033583426703283633433725380; + q = ((q * x) >> 96) + 3604857256930695427073651918091429; + q = ((q * x) >> 96) - 14423608567350463180887372962807573; + q = ((q * x) >> 96) + 26449188498355588339934803723976023; + + /// @solidity memory-safe-assembly + assembly { + // Div in assembly because solidity adds a zero check despite the unchecked. + // The q polynomial won't have zeros in the domain as all its roots are complex. + // No scaling is necessary because p is already 2**96 too large. + r := sdiv(p, q) + } + + // r should be in the range (0.09, 0.25) * 2**96. + + // We now need to multiply r by: + // * the scale factor s = ~6.031367120. + // * the 2**k factor from the range reduction. + // * the 1e18 / 2**96 factor for base conversion. + // We do this all at once, with an intermediate result in 2**213 + // basis, so the final right shift is always by a positive amount. + r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k)); + } +} + +function wadLn(int256 x) pure returns (int256 r) { + unchecked { + require(x > 0, "UNDEFINED"); + + // We want to convert x from 10**18 fixed point to 2**96 fixed point. + // We do this by multiplying by 2**96 / 10**18. But since + // ln(x * C) = ln(x) + ln(C), we can simply do nothing here + // and add ln(2**96 / 10**18) at the end. + + /// @solidity memory-safe-assembly + assembly { + r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) + r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) + r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) + r := or(r, shl(4, lt(0xffff, shr(r, x)))) + r := or(r, shl(3, lt(0xff, shr(r, x)))) + r := or(r, shl(2, lt(0xf, shr(r, x)))) + r := or(r, shl(1, lt(0x3, shr(r, x)))) + r := or(r, lt(0x1, shr(r, x))) + } + + // Reduce range of x to (1, 2) * 2**96 + // ln(2^k * x) = k * ln(2) + ln(x) + int256 k = r - 96; + x <<= uint256(159 - k); + x = int256(uint256(x) >> 159); + + // Evaluate using a (8, 8)-term rational approximation. + // p is made monic, we will multiply by a scale factor later. + int256 p = x + 3273285459638523848632254066296; + p = ((p * x) >> 96) + 24828157081833163892658089445524; + p = ((p * x) >> 96) + 43456485725739037958740375743393; + p = ((p * x) >> 96) - 11111509109440967052023855526967; + p = ((p * x) >> 96) - 45023709667254063763336534515857; + p = ((p * x) >> 96) - 14706773417378608786704636184526; + p = p * x - (795164235651350426258249787498 << 96); + + // We leave p in 2**192 basis so we don't need to scale it back up for the division. + // q is monic by convention. + int256 q = x + 5573035233440673466300451813936; + q = ((q * x) >> 96) + 71694874799317883764090561454958; + q = ((q * x) >> 96) + 283447036172924575727196451306956; + q = ((q * x) >> 96) + 401686690394027663651624208769553; + q = ((q * x) >> 96) + 204048457590392012362485061816622; + q = ((q * x) >> 96) + 31853899698501571402653359427138; + q = ((q * x) >> 96) + 909429971244387300277376558375; + /// @solidity memory-safe-assembly + assembly { + // Div in assembly because solidity adds a zero check despite the unchecked. + // The q polynomial is known not to have zeros in the domain. + // No scaling required because p is already 2**96 too large. + r := sdiv(p, q) + } + + // r is in the range (0, 0.125) * 2**96 + + // Finalization, we need to: + // * multiply by the scale factor s = 5.549… + // * add ln(2**96 / 10**18) + // * add k * ln(2) + // * multiply by 10**18 / 2**96 = 5**18 >> 78 + + // mul s * 5e18 * 2**96, base is now 5**18 * 2**192 + r *= 1677202110996718588342820967067443963516166; + // add ln(2) * k * 5e18 * 2**192 + r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k; + // add ln(2**96 / 10**18) * 5e18 * 2**192 + r += 600920179829731861736702779321621459595472258049074101567377883020018308; + // base conversion: mul 2**18 / 2**192 + r >>= 174; + } +} + +/// @dev Will return 0 instead of reverting if y is zero. +function unsafeDiv(int256 x, int256 y) pure returns (int256 r) { + /// @solidity memory-safe-assembly + assembly { + // Divide x by y. + r := sdiv(x, y) + } +}