Repository: pcaversaccio/snekmate (language: python)

Issue:
💥 `ERC-5267` Implementation
We should add support for the [ERC-5267](https://eips.ethereum.org/EIPS/eip-5267), which is a way to describe and retrieve an [EIP-712](https://eips.ethereum.org/EIPS/eip-712) domain to securely integrate EIP-712 signatures.

A reference implementation can be found [here](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol#L117).


Discussion / hints:

Fix patch:
diff --git a/.gas-snapshot b/.gas-snapshot
index 10fcad44..95fabf08 100644
--- a/.gas-snapshot
+++ b/.gas-snapshot
@@ -59,8 +59,8 @@ BatchDistributorTest:testDistributeTokenMultipleAddressesSuccess() (gas: 723372)
 BatchDistributorTest:testDistributeTokenOneAddressSuccess() (gas: 685695)
 BatchDistributorTest:testDistributeTokenRevertWithInsufficientAllowance() (gas: 679169)
 BatchDistributorTest:testDistributeTokenRevertWithInsufficientBalance() (gas: 681955)
-BatchDistributorTest:testFuzzDistributeEtherMultipleAddressesSuccess(((address,uint256)[]),uint256) (runs: 256, μ: 993002, ~: 924837)
-BatchDistributorTest:testFuzzDistributeTokenMultipleAddressesSuccess(((address,uint256)[]),address,uint256) (runs: 256, μ: 1428301, ~: 1392287)
+BatchDistributorTest:testFuzzDistributeEtherMultipleAddressesSuccess(((address,uint256)[]),uint256) (runs: 256, μ: 968476, ~: 896057)
+BatchDistributorTest:testFuzzDistributeTokenMultipleAddressesSuccess(((address,uint256)[]),address,uint256) (runs: 256, μ: 1429837, ~: 1398384)
 Create2AddressTest:testComputeAddress() (gas: 661213)
 Create2AddressTest:testComputeAddressSelf() (gas: 669513)
 Create2AddressTest:testFuzzComputeAddress(bytes32,address) (runs: 256, μ: 661741, ~: 661741)
@@ -86,29 +86,29 @@ CreateAddressTest:testComputeAddressSelfNonceUint56() (gas: 646683)
 CreateAddressTest:testComputeAddressSelfNonceUint64() (gas: 646778)
 CreateAddressTest:testComputeAddressSelfNonceUint8() (gas: 646428)
 CreateAddressTest:testComputeAddressSelfRevertTooHighNonce() (gas: 8799)
-CreateAddressTest:testFuzzComputeAddressNonce0x7f(uint64,address) (runs: 256, μ: 645867, ~: 646028)
-CreateAddressTest:testFuzzComputeAddressNonceUint16(uint64,address) (runs: 256, μ: 645405, ~: 645642)
-CreateAddressTest:testFuzzComputeAddressNonceUint24(uint64,address) (runs: 256, μ: 645488, ~: 645597)
-CreateAddressTest:testFuzzComputeAddressNonceUint32(uint64,address) (runs: 256, μ: 645488, ~: 645626)
-CreateAddressTest:testFuzzComputeAddressNonceUint40(uint64,address) (runs: 256, μ: 645591, ~: 645696)
-CreateAddressTest:testFuzzComputeAddressNonceUint48(uint64,address) (runs: 256, μ: 645605, ~: 645702)
-CreateAddressTest:testFuzzComputeAddressNonceUint56(uint64,address) (runs: 256, μ: 645602, ~: 645709)
-CreateAddressTest:testFuzzComputeAddressNonceUint64(uint64,address) (runs: 256, μ: 645598, ~: 645813)
-CreateAddressTest:testFuzzComputeAddressNonceUint8(uint64,address) (runs: 256, μ: 645364, ~: 645471)
-CreateAddressTest:testFuzzComputeAddressRevertTooHighNonce(uint256,address) (runs: 256, μ: 13326, ~: 13303)
+CreateAddressTest:testFuzzComputeAddressNonce0x7f(uint64,address) (runs: 256, μ: 645860, ~: 646028)
+CreateAddressTest:testFuzzComputeAddressNonceUint16(uint64,address) (runs: 256, μ: 645385, ~: 645567)
+CreateAddressTest:testFuzzComputeAddressNonceUint24(uint64,address) (runs: 256, μ: 645475, ~: 645597)
+CreateAddressTest:testFuzzComputeAddressNonceUint32(uint64,address) (runs: 256, μ: 645497, ~: 645626)
+CreateAddressTest:testFuzzComputeAddressNonceUint40(uint64,address) (runs: 256, μ: 645598, ~: 645696)
+CreateAddressTest:testFuzzComputeAddressNonceUint48(uint64,address) (runs: 256, μ: 645603, ~: 645702)
+CreateAddressTest:testFuzzComputeAddressNonceUint56(uint64,address) (runs: 256, μ: 645603, ~: 645709)
+CreateAddressTest:testFuzzComputeAddressNonceUint64(uint64,address) (runs: 256, μ: 645576, ~: 645813)
+CreateAddressTest:testFuzzComputeAddressNonceUint8(uint64,address) (runs: 256, μ: 645362, ~: 645471)
+CreateAddressTest:testFuzzComputeAddressRevertTooHighNonce(uint256,address) (runs: 256, μ: 13313, ~: 13303)
 CreateAddressTest:testFuzzComputeAddressSelfNonce0x7f(uint64) (runs: 256, μ: 651689, ~: 651822)
-CreateAddressTest:testFuzzComputeAddressSelfNonceUint16(uint64) (runs: 256, μ: 651029, ~: 651155)
-CreateAddressTest:testFuzzComputeAddressSelfNonceUint24(uint64) (runs: 256, μ: 651310, ~: 651422)
-CreateAddressTest:testFuzzComputeAddressSelfNonceUint32(uint64) (runs: 256, μ: 651329, ~: 651430)
-CreateAddressTest:testFuzzComputeAddressSelfNonceUint40(uint64) (runs: 256, μ: 651419, ~: 651501)
-CreateAddressTest:testFuzzComputeAddressSelfNonceUint48(uint64) (runs: 256, μ: 651375, ~: 651488)
-CreateAddressTest:testFuzzComputeAddressSelfNonceUint56(uint64) (runs: 256, μ: 651469, ~: 651558)
-CreateAddressTest:testFuzzComputeAddressSelfNonceUint64(uint64) (runs: 256, μ: 651515, ~: 651688)
-CreateAddressTest:testFuzzComputeAddressSelfNonceUint8(uint64) (runs: 256, μ: 651024, ~: 651125)
-CreateAddressTest:testFuzzComputeAddressSelfRevertTooHighNonce(uint256) (runs: 256, μ: 13155, ~: 13142)
+CreateAddressTest:testFuzzComputeAddressSelfNonceUint16(uint64) (runs: 256, μ: 651002, ~: 650902)
+CreateAddressTest:testFuzzComputeAddressSelfNonceUint24(uint64) (runs: 256, μ: 651317, ~: 651422)
+CreateAddressTest:testFuzzComputeAddressSelfNonceUint32(uint64) (runs: 256, μ: 651324, ~: 651430)
+CreateAddressTest:testFuzzComputeAddressSelfNonceUint40(uint64) (runs: 256, μ: 651417, ~: 651501)
+CreateAddressTest:testFuzzComputeAddressSelfNonceUint48(uint64) (runs: 256, μ: 651373, ~: 651488)
+CreateAddressTest:testFuzzComputeAddressSelfNonceUint56(uint64) (runs: 256, μ: 651464, ~: 651558)
+CreateAddressTest:testFuzzComputeAddressSelfNonceUint64(uint64) (runs: 256, μ: 651480, ~: 651688)
+CreateAddressTest:testFuzzComputeAddressSelfNonceUint8(uint64) (runs: 256, μ: 651033, ~: 651125)
+CreateAddressTest:testFuzzComputeAddressSelfRevertTooHighNonce(uint256) (runs: 256, μ: 13163, ~: 13142)
 ECDSATest:testEthSignedMessageHash() (gas: 5852)
 ECDSATest:testFuzzEthSignedMessageHash(string) (runs: 256, μ: 6442, ~: 6444)
-ECDSATest:testFuzzRecoverWithInvalidSignature(bytes,string) (runs: 256, μ: 15157, ~: 15158)
+ECDSATest:testFuzzRecoverWithInvalidSignature(bytes,string) (runs: 256, μ: 15158, ~: 15158)
 ECDSATest:testFuzzRecoverWithTooLongSignature(bytes,string) (runs: 256, μ: 13118, ~: 13116)
 ECDSATest:testFuzzRecoverWithValidSignature(string,string) (runs: 256, μ: 21724, ~: 21737)
 ECDSATest:testFuzzRecoverWithWrongMessage(string,string,bytes32) (runs: 256, μ: 21720, ~: 21728)
@@ -128,11 +128,13 @@ ECDSATest:testRecoverWithWrongVersion() (gas: 15632)
 ECDSATest:testToDataWithIntendedValidatorHash() (gas: 11660)
 ECDSATest:testToDataWithIntendedValidatorHashSelf() (gas: 9521)
 ECDSATest:testToTypedDataHash() (gas: 5966)
-EIP712DomainSeparatorTest:testCachedDomainSeparatorV4() (gas: 7556)
-EIP712DomainSeparatorTest:testDomainSeparatorV4() (gas: 9339)
-EIP712DomainSeparatorTest:testFuzzDomainSeparatorV4(uint8) (runs: 256, μ: 9450, ~: 9479)
-EIP712DomainSeparatorTest:testFuzzHashTypedDataV4(address,address,uint256,uint256,uint64) (runs: 256, μ: 7716, ~: 7716)
-EIP712DomainSeparatorTest:testHashTypedDataV4() (gas: 13035)
+EIP712DomainSeparatorTest:testCachedDomainSeparatorV4() (gas: 7635)
+EIP712DomainSeparatorTest:testDomainSeparatorV4() (gas: 11278)
+EIP712DomainSeparatorTest:testEIP712Domain() (gas: 13644)
+EIP712DomainSeparatorTest:testFuzzDomainSeparatorV4(uint8) (runs: 256, μ: 11430, ~: 11453)
+EIP712DomainSeparatorTest:testFuzzEIP712Domain(bytes1,uint8,bytes32,uint256[]) (runs: 256, μ: 19180, ~: 19140)
+EIP712DomainSeparatorTest:testFuzzHashTypedDataV4(address,address,uint256,uint256,uint64) (runs: 256, μ: 7701, ~: 7701)
+EIP712DomainSeparatorTest:testHashTypedDataV4() (gas: 13020)
 ERC1155Invariants:invariantOwner() (runs: 256, calls: 3840, reverts: 3479)
 ERC1155Test:testBalanceOfBatchCase1() (gas: 268654)
 ERC1155Test:testBalanceOfBatchCase2() (gas: 223224)
@@ -262,259 +264,265 @@ ERC1155Test:testUriBaseAndTokenUriNotSet() (gas: 2897514)
 ERC1155Test:testUriBaseAndTokenUriSet() (gas: 65806)
 ERC1155Test:testUriNoBaseURI() (gas: 2947766)
 ERC1155Test:testUriNoTokenUri() (gas: 17650)
-ERC20Invariants:invariantOwner() (runs: 256, calls: 3840, reverts: 3133)
-ERC20Invariants:invariantTotalSupply() (runs: 256, calls: 3840, reverts: 3133)
-ERC20Test:testApproveExceedingBalanceCase1() (gas: 40461)
-ERC20Test:testApproveExceedingBalanceCase2() (gas: 47048)
+ERC20Invariants:invariantOwner() (runs: 256, calls: 3840, reverts: 3134)
+ERC20Invariants:invariantTotalSupply() (runs: 256, calls: 3840, reverts: 3134)
+ERC20Test:testApproveExceedingBalanceCase1() (gas: 40439)
+ERC20Test:testApproveExceedingBalanceCase2() (gas: 47026)
 ERC20Test:testApproveFromZeroAddress() (gas: 13455)
 ERC20Test:testApproveSuccessCase1() (gas: 43348)
-ERC20Test:testApproveSuccessCase2() (gas: 49972)
+ERC20Test:testApproveSuccessCase2() (gas: 49950)
 ERC20Test:testApproveToZeroAddress() (gas: 16755)
-ERC20Test:testBalanceOf() (gas: 17938)
-ERC20Test:testBurnFromExceedingBalance() (gas: 31548)
-ERC20Test:testBurnFromFromZeroAddress() (gas: 15842)
-ERC20Test:testBurnFromInsufficientAllowanceCase1() (gas: 42207)
-ERC20Test:testBurnFromInsufficientAllowanceCase2() (gas: 42282)
+ERC20Test:testBalanceOf() (gas: 17983)
+ERC20Test:testBurnFromExceedingBalance() (gas: 31531)
+ERC20Test:testBurnFromFromZeroAddress() (gas: 15865)
+ERC20Test:testBurnFromInsufficientAllowanceCase1() (gas: 42185)
+ERC20Test:testBurnFromInsufficientAllowanceCase2() (gas: 42238)
 ERC20Test:testBurnFromSuccessCase1() (gas: 40056)
-ERC20Test:testBurnFromSuccessCase2() (gas: 65653)
-ERC20Test:testBurnFromUnlimitedAllowance() (gas: 50357)
-ERC20Test:testBurnFromZeroAddress() (gas: 11651)
+ERC20Test:testBurnFromSuccessCase2() (gas: 65631)
+ERC20Test:testBurnFromUnlimitedAllowance() (gas: 50380)
+ERC20Test:testBurnFromZeroAddress() (gas: 11696)
 ERC20Test:testBurnInvalidAmount() (gas: 14941)
-ERC20Test:testBurnSuccessCase1() (gas: 25618)
+ERC20Test:testBurnSuccessCase1() (gas: 25596)
 ERC20Test:testBurnSuccessCase2() (gas: 31183)
-ERC20Test:testCachedDomainSeparator() (gas: 8149)
-ERC20Test:testDecreaseAllowanceExceedingBalanceCase1() (gas: 47594)
-ERC20Test:testDecreaseAllowanceExceedingBalanceCase2() (gas: 33792)
-ERC20Test:testDecreaseAllowanceFromZeroAddress() (gas: 15721)
-ERC20Test:testDecreaseAllowanceInvalidAmountCase1() (gas: 15695)
+ERC20Test:testCachedDomainSeparator() (gas: 8096)
+ERC20Test:testDecreaseAllowanceExceedingBalanceCase1() (gas: 47572)
+ERC20Test:testDecreaseAllowanceExceedingBalanceCase2() (gas: 33811)
+ERC20Test:testDecreaseAllowanceFromZeroAddress() (gas: 15699)
+ERC20Test:testDecreaseAllowanceInvalidAmountCase1() (gas: 15673)
 ERC20Test:testDecreaseAllowanceInvalidAmountCase2() (gas: 46567)
-ERC20Test:testDecreaseAllowanceSuccessCase1() (gas: 50467)
-ERC20Test:testDecreaseAllowanceSuccessCase2() (gas: 36066)
-ERC20Test:testDecreaseAllowanceToZeroAddress() (gas: 18977)
-ERC20Test:testDomainSeparator() (gas: 12006)
-ERC20Test:testFuzzApproveSuccess(address,uint256) (runs: 256, μ: 39804, ~: 40660)
-ERC20Test:testFuzzBurnFromInsufficientAllowance(address,uint256,uint8) (runs: 256, μ: 179402, ~: 179643)
-ERC20Test:testFuzzBurnFromSuccess(address,uint256) (runs: 256, μ: 288300, ~: 289476)
-ERC20Test:testFuzzBurnInvalidAmount(address,uint256) (runs: 256, μ: 16715, ~: 16715)
-ERC20Test:testFuzzBurnSuccessCase(uint256) (runs: 256, μ: 264072, ~: 263857)
-ERC20Test:testFuzzDecreaseAllowanceInvalidAmount(address,uint256,uint256) (runs: 256, μ: 41285, ~: 43073)
-ERC20Test:testFuzzDecreaseAllowanceSuccess(address,uint256,uint256) (runs: 256, μ: 47277, ~: 47794)
-ERC20Test:testFuzzDomainSeparator(uint8) (runs: 256, μ: 12082, ~: 12109)
-ERC20Test:testFuzzIncreaseAllowanceSuccess(address,uint256) (runs: 256, μ: 43977, ~: 44844)
-ERC20Test:testFuzzMintNonMinter(string,uint256) (runs: 256, μ: 13608, ~: 13623)
-ERC20Test:testFuzzMintSuccess(string,uint256) (runs: 256, μ: 54760, ~: 56180)
-ERC20Test:testFuzzPermitInvalid(string,string,uint16) (runs: 256, μ: 46363, ~: 46392)
-ERC20Test:testFuzzPermitSuccess(string,string,uint16) (runs: 256, μ: 71596, ~: 71622)
-ERC20Test:testFuzzRenounceOwnershipNonOwner(address) (runs: 256, μ: 14368, ~: 14368)
-ERC20Test:testFuzzRenounceOwnershipSuccess(address) (runs: 256, μ: 49165, ~: 49152)
-ERC20Test:testFuzzSetMinterNonOwner(address,string) (runs: 256, μ: 16254, ~: 16268)
-ERC20Test:testFuzzSetMinterSuccess(string) (runs: 256, μ: 34234, ~: 34228)
-ERC20Test:testFuzzTransferFromInsufficientAllowance(address,address,uint256,uint8) (runs: 256, μ: 177606, ~: 178061)
-ERC20Test:testFuzzTransferFromSuccess(address,address,uint256) (runs: 256, μ: 205572, ~: 206923)
-ERC20Test:testFuzzTransferInvalidAmount(address,address,uint256) (runs: 256, μ: 17083, ~: 17083)
-ERC20Test:testFuzzTransferOwnershipNonOwner(address,address) (runs: 256, μ: 14489, ~: 14489)
-ERC20Test:testFuzzTransferOwnershipSuccess(address,address) (runs: 256, μ: 75263, ~: 75239)
-ERC20Test:testFuzzTransferSuccess(address,uint256) (runs: 256, μ: 177044, ~: 177729)
-ERC20Test:testHasOwner() (gas: 9847)
-ERC20Test:testIncreaseAllowanceExceedingBalanceCase1() (gas: 40685)
-ERC20Test:testIncreaseAllowanceExceedingBalanceCase2() (gas: 47508)
-ERC20Test:testIncreaseAllowanceFromZeroAddress() (gas: 15711)
+ERC20Test:testDecreaseAllowanceSuccessCase1() (gas: 50445)
+ERC20Test:testDecreaseAllowanceSuccessCase2() (gas: 36084)
+ERC20Test:testDecreaseAllowanceToZeroAddress() (gas: 19065)
+ERC20Test:testDomainSeparator() (gas: 11945)
+ERC20Test:testEIP712Domain() (gas: 14645)
+ERC20Test:testFuzzApproveSuccess(address,uint256) (runs: 256, μ: 39782, ~: 40638)
+ERC20Test:testFuzzBurnFromInsufficientAllowance(address,uint256,uint8) (runs: 256, μ: 179330, ~: 180013)
+ERC20Test:testFuzzBurnFromSuccess(address,uint256) (runs: 256, μ: 288494, ~: 289561)
+ERC20Test:testFuzzBurnInvalidAmount(address,uint256) (runs: 256, μ: 16803, ~: 16803)
+ERC20Test:testFuzzBurnSuccessCase(uint256) (runs: 256, μ: 264152, ~: 263942)
+ERC20Test:testFuzzDecreaseAllowanceInvalidAmount(address,uint256,uint256) (runs: 256, μ: 41241, ~: 43029)
+ERC20Test:testFuzzDecreaseAllowanceSuccess(address,uint256,uint256) (runs: 256, μ: 47365, ~: 47882)
+ERC20Test:testFuzzDomainSeparator(uint8) (runs: 256, μ: 12004, ~: 12026)
+ERC20Test:testFuzzEIP712Domain(bytes1,uint8,bytes32,uint256[]) (runs: 256, μ: 20357, ~: 20317)
+ERC20Test:testFuzzIncreaseAllowanceSuccess(address,uint256) (runs: 256, μ: 44113, ~: 44822)
+ERC20Test:testFuzzMintNonMinter(string,uint256) (runs: 256, μ: 13585, ~: 13601)
+ERC20Test:testFuzzMintSuccess(string,uint256) (runs: 256, μ: 55098, ~: 56231)
+ERC20Test:testFuzzPermitInvalid(string,string,uint16) (runs: 256, μ: 46332, ~: 46361)
+ERC20Test:testFuzzPermitSuccess(string,string,uint16) (runs: 256, μ: 71558, ~: 71591)
+ERC20Test:testFuzzRenounceOwnershipNonOwner(address) (runs: 256, μ: 14391, ~: 14391)
+ERC20Test:testFuzzRenounceOwnershipSuccess(address) (runs: 256, μ: 49185, ~: 49225)
+ERC20Test:testFuzzSetMinterNonOwner(address,string) (runs: 256, μ: 16224, ~: 16246)
+ERC20Test:testFuzzSetMinterSuccess(string) (runs: 256, μ: 34232, ~: 34229)
+ERC20Test:testFuzzTransferFromInsufficientAllowance(address,address,uint256,uint8) (runs: 256, μ: 177392, ~: 178096)
+ERC20Test:testFuzzTransferFromSuccess(address,address,uint256) (runs: 256, μ: 205751, ~: 206974)
+ERC20Test:testFuzzTransferInvalidAmount(address,address,uint256) (runs: 256, μ: 17061, ~: 17061)
+ERC20Test:testFuzzTransferOwnershipNonOwner(address,address) (runs: 256, μ: 14512, ~: 14512)
+ERC20Test:testFuzzTransferOwnershipSuccess(address,address) (runs: 256, μ: 75282, ~: 75258)
+ERC20Test:testFuzzTransferSuccess(address,uint256) (runs: 256, μ: 177075, ~: 177757)
+ERC20Test:testHasOwner() (gas: 9825)
+ERC20Test:testIncreaseAllowanceExceedingBalanceCase1() (gas: 40663)
+ERC20Test:testIncreaseAllowanceExceedingBalanceCase2() (gas: 47486)
+ERC20Test:testIncreaseAllowanceFromZeroAddress() (gas: 15689)
 ERC20Test:testIncreaseAllowanceSuccessCase1() (gas: 43593)
-ERC20Test:testIncreaseAllowanceSuccessCase2() (gas: 50430)
-ERC20Test:testIncreaseAllowanceToZeroAddress() (gas: 19099)
-ERC20Test:testInitialSetup() (gas: 1427169)
+ERC20Test:testIncreaseAllowanceSuccessCase2() (gas: 50408)
+ERC20Test:testIncreaseAllowanceToZeroAddress() (gas: 19055)
+ERC20Test:testInitialSetup() (gas: 1516870)
 ERC20Test:testMintNonMinter() (gas: 13013)
-ERC20Test:testMintOverflow() (gas: 17291)
+ERC20Test:testMintOverflow() (gas: 17379)
 ERC20Test:testMintSuccess() (gas: 51665)
 ERC20Test:testMintToZeroAddress() (gas: 15991)
-ERC20Test:testPermitBadChainId() (gas: 44439)
-ERC20Test:testPermitBadNonce() (gas: 41754)
-ERC20Test:testPermitExpiredDeadline() (gas: 18341)
-ERC20Test:testPermitOtherSignature() (gas: 42804)
-ERC20Test:testPermitReplaySignature() (gas: 75117)
-ERC20Test:testPermitSuccess() (gas: 70512)
-ERC20Test:testRenounceOwnershipNonOwner() (gas: 11289)
-ERC20Test:testRenounceOwnershipSuccess() (gas: 22829)
-ERC20Test:testSetMinterNonOwner() (gas: 13007)
-ERC20Test:testSetMinterRemoveOwnerAddress() (gas: 14184)
-ERC20Test:testSetMinterSuccess() (gas: 33968)
-ERC20Test:testSetMinterToZeroAddress() (gas: 16102)
-ERC20Test:testTotalSupply() (gas: 8650)
-ERC20Test:testTransferFromExceedingBalance() (gas: 32974)
+ERC20Test:testPermitBadChainId() (gas: 44417)
+ERC20Test:testPermitBadNonce() (gas: 41723)
+ERC20Test:testPermitExpiredDeadline() (gas: 18310)
+ERC20Test:testPermitOtherSignature() (gas: 42795)
+ERC20Test:testPermitReplaySignature() (gas: 75086)
+ERC20Test:testPermitSuccess() (gas: 70481)
+ERC20Test:testRenounceOwnershipNonOwner() (gas: 11400)
+ERC20Test:testRenounceOwnershipSuccess() (gas: 22897)
+ERC20Test:testSetMinterNonOwner() (gas: 13095)
+ERC20Test:testSetMinterRemoveOwnerAddress() (gas: 14271)
+ERC20Test:testSetMinterSuccess() (gas: 33950)
+ERC20Test:testSetMinterToZeroAddress() (gas: 16080)
+ERC20Test:testTotalSupply() (gas: 8628)
+ERC20Test:testTransferFromExceedingBalance() (gas: 32956)
 ERC20Test:testTransferFromFromZeroAddress() (gas: 17970)
-ERC20Test:testTransferFromInsufficientAllowanceCase1() (gas: 43908)
-ERC20Test:testTransferFromInsufficientAllowanceCase2() (gas: 43983)
+ERC20Test:testTransferFromInsufficientAllowanceCase1() (gas: 43864)
+ERC20Test:testTransferFromInsufficientAllowanceCase2() (gas: 43961)
 ERC20Test:testTransferFromSuccess() (gas: 61135)
 ERC20Test:testTransferFromToZeroAddress() (gas: 33039)
-ERC20Test:testTransferFromUnlimitedAllowance() (gas: 71230)
-ERC20Test:testTransferFromZeroAddress() (gas: 20171)
-ERC20Test:testTransferInvalidAmount() (gas: 15641)
-ERC20Test:testTransferOwnershipNonOwner() (gas: 13076)
-ERC20Test:testTransferOwnershipSuccess() (gas: 53793)
-ERC20Test:testTransferOwnershipToZeroAddress() (gas: 16029)
+ERC20Test:testTransferFromUnlimitedAllowance() (gas: 71208)
+ERC20Test:testTransferFromZeroAddress() (gas: 20258)
+ERC20Test:testTransferInvalidAmount() (gas: 15729)
+ERC20Test:testTransferOwnershipNonOwner() (gas: 13077)
+ERC20Test:testTransferOwnershipSuccess() (gas: 53794)
+ERC20Test:testTransferOwnershipToZeroAddress() (gas: 16052)
 ERC20Test:testTransferSuccess() (gas: 42469)
-ERC20Test:testTransferToZeroAddress() (gas: 16699)
-ERC20Test:testTransferZeroTokens() (gas: 24576)
-ERC4626VaultInvariants:invariantTotalAssets() (runs: 256, calls: 3840, reverts: 2981)
-ERC4626VaultInvariants:invariantTotalSupply() (runs: 256, calls: 3840, reverts: 2981)
-ERC4626VaultTest:testCachedDomainSeparator() (gas: 7990)
-ERC4626VaultTest:testDepositInsufficientAllowance() (gas: 82198)
-ERC4626VaultTest:testDepositWithNoApproval() (gas: 22604)
-ERC4626VaultTest:testDepositZero() (gas: 40355)
-ERC4626VaultTest:testDomainSeparator() (gas: 11915)
-ERC4626VaultTest:testEmptyVaultDeposit() (gas: 565362)
-ERC4626VaultTest:testEmptyVaultMint() (gas: 566765)
-ERC4626VaultTest:testEmptyVaultRedeem() (gas: 202948)
-ERC4626VaultTest:testEmptyVaultwithdraw() (gas: 214894)
-ERC4626VaultTest:testFail_redeem((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 566227, ~: 568327)
-ERC4626VaultTest:testFail_withdraw((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 568090, ~: 570111)
-ERC4626VaultTest:testFuzzDomainSeparator(uint8) (runs: 256, μ: 11924, ~: 11953)
-ERC4626VaultTest:testFuzzPermitInvalid(string,string,uint16) (runs: 256, μ: 46015, ~: 45982)
-ERC4626VaultTest:testFuzzPermitSuccess(string,string,uint16) (runs: 256, μ: 71237, ~: 71266)
-ERC4626VaultTest:testInitialSetup() (gas: 5572042)
-ERC4626VaultTest:testMintWithNoApproval() (gas: 22721)
-ERC4626VaultTest:testMintZero() (gas: 40492)
-ERC4626VaultTest:testMultipleMintDepositRedeemWithdraw() (gas: 378464)
+ERC20Test:testTransferToZeroAddress() (gas: 16677)
+ERC20Test:testTransferZeroTokens() (gas: 24664)
+ERC4626VaultInvariants:invariantTotalAssets() (runs: 256, calls: 3840, reverts: 2978)
+ERC4626VaultInvariants:invariantTotalSupply() (runs: 256, calls: 3840, reverts: 2978)
+ERC4626VaultTest:testCachedDomainSeparator() (gas: 7981)
+ERC4626VaultTest:testDepositInsufficientAllowance() (gas: 82221)
+ERC4626VaultTest:testDepositWithNoApproval() (gas: 22737)
+ERC4626VaultTest:testDepositZero() (gas: 40402)
+ERC4626VaultTest:testDomainSeparator() (gas: 11854)
+ERC4626VaultTest:testEIP712Domain() (gas: 14391)
+ERC4626VaultTest:testEmptyVaultDeposit() (gas: 565800)
+ERC4626VaultTest:testEmptyVaultMint() (gas: 567225)
+ERC4626VaultTest:testEmptyVaultRedeem() (gas: 203519)
+ERC4626VaultTest:testEmptyVaultwithdraw() (gas: 215354)
+ERC4626VaultTest:testFail_redeem((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 566851, ~: 568420)
+ERC4626VaultTest:testFail_withdraw((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 568785, ~: 570226)
+ERC4626VaultTest:testFuzzDomainSeparator(uint8) (runs: 256, μ: 11868, ~: 11892)
+ERC4626VaultTest:testFuzzEIP712Domain(bytes1,uint8,bytes32,uint256[]) (runs: 256, μ: 20046, ~: 20005)
+ERC4626VaultTest:testFuzzPermitInvalid(string,string,uint16) (runs: 256, μ: 45987, ~: 46020)
+ERC4626VaultTest:testFuzzPermitSuccess(string,string,uint16) (runs: 256, μ: 71206, ~: 71235)
+ERC4626VaultTest:testInitialSetup() (gas: 5842913)
+ERC4626VaultTest:testMintWithNoApproval() (gas: 22855)
+ERC4626VaultTest:testMintZero() (gas: 40561)
+ERC4626VaultTest:testMultipleMintDepositRedeemWithdraw() (gas: 379362)
 ERC4626VaultTest:testPermitBadChainId() (gas: 44246)
-ERC4626VaultTest:testPermitBadNonce() (gas: 41490)
-ERC4626VaultTest:testPermitExpiredDeadline() (gas: 18075)
-ERC4626VaultTest:testPermitOtherSignature() (gas: 42561)
-ERC4626VaultTest:testPermitReplaySignature() (gas: 74683)
-ERC4626VaultTest:testPermitSuccess() (gas: 70171)
-ERC4626VaultTest:testRedeemInsufficientShares() (gas: 133913)
-ERC4626VaultTest:testRedeemWithNoShares() (gas: 13993)
-ERC4626VaultTest:testSingleDepositWithdraw() (gas: 178616)
-ERC4626VaultTest:testSingleMintRedeem() (gas: 177551)
-ERC4626VaultTest:testVaultInteractionsForSomeoneElse() (gas: 225889)
-ERC4626VaultTest:testWithdrawInsufficientAllowance() (gas: 124744)
-ERC4626VaultTest:testWithdrawInsufficientAssets() (gas: 120038)
-ERC4626VaultTest:testWithdrawWithNoAssets() (gas: 21914)
-ERC4626VaultTest:test_RT_deposit_redeem((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 480082, ~: 484458)
-ERC4626VaultTest:test_RT_deposit_withdraw((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 482113, ~: 486130)
-ERC4626VaultTest:test_RT_mint_redeem((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 480937, ~: 484627)
-ERC4626VaultTest:test_RT_mint_withdraw((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 482586, ~: 486248)
-ERC4626VaultTest:test_RT_redeem_deposit((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 480358, ~: 484640)
-ERC4626VaultTest:test_RT_redeem_mint((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 480684, ~: 484842)
-ERC4626VaultTest:test_RT_withdraw_deposit((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 482525, ~: 486213)
-ERC4626VaultTest:test_RT_withdraw_mint((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 483168, ~: 486620)
-ERC4626VaultTest:test_asset((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 428383, ~: 434906)
-ERC4626VaultTest:test_convertToAssets((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 435804, ~: 440308)
-ERC4626VaultTest:test_convertToShares((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 435645, ~: 440503)
-ERC4626VaultTest:test_deposit((address[4],uint256[4],uint256[4],int256),uint256,uint256) (runs: 256, μ: 478526, ~: 481821)
-ERC4626VaultTest:test_maxDeposit((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 428690, ~: 435213)
-ERC4626VaultTest:test_maxMint((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 428770, ~: 435293)
-ERC4626VaultTest:test_maxRedeem((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 428978, ~: 435500)
-ERC4626VaultTest:test_maxWithdraw((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 430518, ~: 437113)
-ERC4626VaultTest:test_mint((address[4],uint256[4],uint256[4],int256),uint256,uint256) (runs: 256, μ: 478251, ~: 481899)
-ERC4626VaultTest:test_previewDeposit((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 472958, ~: 476864)
-ERC4626VaultTest:test_previewMint((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 473909, ~: 477137)
-ERC4626VaultTest:test_previewRedeem((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 475247, ~: 479139)
-ERC4626VaultTest:test_previewWithdraw((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 477196, ~: 480926)
-ERC4626VaultTest:test_redeem((address[4],uint256[4],uint256[4],int256),uint256,uint256) (runs: 256, μ: 479408, ~: 483461)
-ERC4626VaultTest:test_totalAssets((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 429129, ~: 435650)
-ERC4626VaultTest:test_withdraw((address[4],uint256[4],uint256[4],int256),uint256,uint256) (runs: 256, μ: 482147, ~: 485034)
+ERC4626VaultTest:testPermitBadNonce() (gas: 41459)
+ERC4626VaultTest:testPermitExpiredDeadline() (gas: 18044)
+ERC4626VaultTest:testPermitOtherSignature() (gas: 42552)
+ERC4626VaultTest:testPermitReplaySignature() (gas: 74652)
+ERC4626VaultTest:testPermitSuccess() (gas: 70162)
+ERC4626VaultTest:testRedeemInsufficientShares() (gas: 133959)
+ERC4626VaultTest:testRedeemWithNoShares() (gas: 14016)
+ERC4626VaultTest:testSingleDepositWithdraw() (gas: 178763)
+ERC4626VaultTest:testSingleMintRedeem() (gas: 177680)
+ERC4626VaultTest:testVaultInteractionsForSomeoneElse() (gas: 225963)
+ERC4626VaultTest:testWithdrawInsufficientAllowance() (gas: 124763)
+ERC4626VaultTest:testWithdrawInsufficientAssets() (gas: 120057)
+ERC4626VaultTest:testWithdrawWithNoAssets() (gas: 21937)
+ERC4626VaultTest:test_RT_deposit_redeem((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 480260, ~: 484573)
+ERC4626VaultTest:test_RT_deposit_withdraw((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 482693, ~: 486294)
+ERC4626VaultTest:test_RT_mint_redeem((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 481032, ~: 484735)
+ERC4626VaultTest:test_RT_mint_withdraw((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 482640, ~: 486297)
+ERC4626VaultTest:test_RT_redeem_deposit((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 481584, ~: 484714)
+ERC4626VaultTest:test_RT_redeem_mint((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 481488, ~: 484929)
+ERC4626VaultTest:test_RT_withdraw_deposit((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 483035, ~: 486356)
+ERC4626VaultTest:test_RT_withdraw_mint((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 483654, ~: 486835)
+ERC4626VaultTest:test_asset((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 428500, ~: 434956)
+ERC4626VaultTest:test_convertToAssets((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 436530, ~: 440652)
+ERC4626VaultTest:test_convertToShares((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 435944, ~: 440575)
+ERC4626VaultTest:test_deposit((address[4],uint256[4],uint256[4],int256),uint256,uint256) (runs: 256, μ: 477674, ~: 481923)
+ERC4626VaultTest:test_maxDeposit((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 428826, ~: 435281)
+ERC4626VaultTest:test_maxMint((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 428888, ~: 435343)
+ERC4626VaultTest:test_maxRedeem((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 429114, ~: 435568)
+ERC4626VaultTest:test_maxWithdraw((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 430642, ~: 437069)
+ERC4626VaultTest:test_mint((address[4],uint256[4],uint256[4],int256),uint256,uint256) (runs: 256, μ: 477921, ~: 482079)
+ERC4626VaultTest:test_previewDeposit((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 473292, ~: 476965)
+ERC4626VaultTest:test_previewMint((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 473819, ~: 477298)
+ERC4626VaultTest:test_previewRedeem((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 475006, ~: 479221)
+ERC4626VaultTest:test_previewWithdraw((address[4],uint256[4],uint256[4],int256),uint256) (runs: 256, μ: 477155, ~: 480881)
+ERC4626VaultTest:test_redeem((address[4],uint256[4],uint256[4],int256),uint256,uint256) (runs: 256, μ: 479515, ~: 483527)
+ERC4626VaultTest:test_totalAssets((address[4],uint256[4],uint256[4],int256)) (runs: 256, μ: 429354, ~: 435807)
+ERC4626VaultTest:test_withdraw((address[4],uint256[4],uint256[4],int256),uint256,uint256) (runs: 256, μ: 482538, ~: 485112)
 ERC721Invariants:invariantOwner() (runs: 256, calls: 3840, reverts: 3449)
 ERC721Invariants:invariantTotalSupply() (runs: 256, calls: 3840, reverts: 3449)
 ERC721Test:testApproveClearingApprovalWithNoPriorApproval() (gas: 178025)
-ERC721Test:testApproveClearingApprovalWithPriorApproval() (gas: 186993)
+ERC721Test:testApproveClearingApprovalWithPriorApproval() (gas: 186971)
 ERC721Test:testApproveFromApprovedAddress() (gas: 200126)
-ERC721Test:testApproveFromNonOwner() (gas: 173927)
+ERC721Test:testApproveFromNonOwner() (gas: 173972)
 ERC721Test:testApproveFromOperatorAddress() (gas: 225291)
-ERC721Test:testApproveInvalidTokenId() (gas: 171923)
+ERC721Test:testApproveInvalidTokenId() (gas: 171901)
 ERC721Test:testApproveToOwner() (gas: 168331)
 ERC721Test:testApproveToZeroAddress() (gas: 186992)
-ERC721Test:testApproveWithNoPriorApproval() (gas: 197477)
+ERC721Test:testApproveWithNoPriorApproval() (gas: 197455)
 ERC721Test:testApproveWithPriorApprovalToDifferentAddress() (gas: 206472)
-ERC721Test:testApproveWithPriorApprovalToSameAddress() (gas: 204856)
-ERC721Test:testBalanceOfCase1() (gas: 330065)
+ERC721Test:testApproveWithPriorApprovalToSameAddress() (gas: 204834)
+ERC721Test:testBalanceOfCase1() (gas: 330043)
 ERC721Test:testBalanceOfCase2() (gas: 12153)
 ERC721Test:testBalanceOfZeroAddress() (gas: 11251)
 ERC721Test:testBurnSuccess() (gas: 307420)
 ERC721Test:testBurnSuccessViaApproveAndSetApprovalForAll() (gas: 373143)
-ERC721Test:testCachedDomainSeparator() (gas: 8175)
-ERC721Test:testDomainSeparator() (gas: 12076)
-ERC721Test:testFuzzApproveClearingApprovalWithNoPriorApproval(address,address) (runs: 256, μ: 197530, ~: 197530)
-ERC721Test:testFuzzApproveClearingApprovalWithPriorApproval(address,address) (runs: 256, μ: 185055, ~: 185055)
+ERC721Test:testCachedDomainSeparator() (gas: 8144)
+ERC721Test:testDomainSeparator() (gas: 12015)
+ERC721Test:testEIP712Domain() (gas: 14900)
+ERC721Test:testFuzzApproveClearingApprovalWithNoPriorApproval(address,address) (runs: 256, μ: 197498, ~: 197508)
+ERC721Test:testFuzzApproveClearingApprovalWithPriorApproval(address,address) (runs: 256, μ: 185045, ~: 185055)
 ERC721Test:testFuzzApproveFromNonOwner(address) (runs: 256, μ: 173322, ~: 173322)
 ERC721Test:testFuzzApproveFromOperatorAddress(address,address,address) (runs: 256, μ: 223971, ~: 223971)
-ERC721Test:testFuzzApproveWithNoPriorApproval(address,address) (runs: 256, μ: 197530, ~: 197530)
-ERC721Test:testFuzzApproveWithPriorApproval(address,address) (runs: 256, μ: 204912, ~: 204912)
-ERC721Test:testFuzzBurnSuccess(address) (runs: 256, μ: 306751, ~: 306747)
-ERC721Test:testFuzzDomainSeparator(uint8) (runs: 256, μ: 10171, ~: 10201)
-ERC721Test:testFuzzGetApprovedApprovedTokenId(address,address) (runs: 256, μ: 195094, ~: 195094)
-ERC721Test:testFuzzPermitInvalid(string,string,uint16) (runs: 256, μ: 203375, ~: 203402)
-ERC721Test:testFuzzPermitSuccess(string,string,uint16) (runs: 256, μ: 229317, ~: 229345)
-ERC721Test:testFuzzRenounceOwnershipNonOwner(address) (runs: 256, μ: 14504, ~: 14504)
-ERC721Test:testFuzzRenounceOwnershipSuccess(address) (runs: 256, μ: 49333, ~: 49319)
+ERC721Test:testFuzzApproveWithNoPriorApproval(address,address) (runs: 256, μ: 197520, ~: 197530)
+ERC721Test:testFuzzApproveWithPriorApproval(address,address) (runs: 256, μ: 204880, ~: 204890)
+ERC721Test:testFuzzBurnSuccess(address) (runs: 256, μ: 306744, ~: 306747)
+ERC721Test:testFuzzDomainSeparator(uint8) (runs: 256, μ: 12093, ~: 12118)
+ERC721Test:testFuzzEIP712Domain(bytes1,uint8,bytes32,uint256[]) (runs: 256, μ: 20556, ~: 20522)
+ERC721Test:testFuzzGetApprovedApprovedTokenId(address,address) (runs: 256, μ: 195062, ~: 195072)
+ERC721Test:testFuzzPermitInvalid(string,string,uint16) (runs: 256, μ: 203398, ~: 203432)
+ERC721Test:testFuzzPermitSuccess(string,string,uint16) (runs: 256, μ: 229331, ~: 229372)
+ERC721Test:testFuzzRenounceOwnershipNonOwner(address) (runs: 256, μ: 14527, ~: 14527)
+ERC721Test:testFuzzRenounceOwnershipSuccess(address) (runs: 256, μ: 49369, ~: 49356)
 ERC721Test:testFuzzSafeMintNonMinter(address) (runs: 256, μ: 16303, ~: 16303)
-ERC721Test:testFuzzSafeMintSuccess(address[]) (runs: 256, μ: 21476044, ~: 20888520)
-ERC721Test:testFuzzSafeTransferFromWithData(address,address,address,bytes) (runs: 256, μ: 1419529, ~: 1418514)
-ERC721Test:testFuzzSetApprovalForAllSuccess(address,address) (runs: 256, μ: 190146, ~: 190146)
-ERC721Test:testFuzzSetMinterNonOwner(address,string) (runs: 256, μ: 16290, ~: 16314)
-ERC721Test:testFuzzSetMinterSuccess(string) (runs: 256, μ: 34359, ~: 34356)
-ERC721Test:testFuzzTokenByIndex(address,string[]) (runs: 256, μ: 24505737, ~: 25212715)
-ERC721Test:testFuzzTotalSupply(address,string[]) (runs: 256, μ: 24318205, ~: 25020753)
-ERC721Test:testFuzzTransferFrom(address,address,address) (runs: 256, μ: 561631, ~: 561619)
-ERC721Test:testFuzzTransferOwnershipNonOwner(address,address) (runs: 256, μ: 14603, ~: 14603)
-ERC721Test:testFuzzTransferOwnershipSuccess(address,address) (runs: 256, μ: 75504, ~: 75481)
-ERC721Test:testGetApprovedApprovedTokenId() (gas: 194996)
+ERC721Test:testFuzzSafeMintSuccess(address[]) (runs: 256, μ: 21537798, ~: 21412946)
+ERC721Test:testFuzzSafeTransferFromWithData(address,address,address,bytes) (runs: 256, μ: 1419700, ~: 1420734)
+ERC721Test:testFuzzSetApprovalForAllSuccess(address,address) (runs: 256, μ: 190169, ~: 190169)
+ERC721Test:testFuzzSetMinterNonOwner(address,string) (runs: 256, μ: 16316, ~: 16338)
+ERC721Test:testFuzzSetMinterSuccess(string) (runs: 256, μ: 34416, ~: 34412)
+ERC721Test:testFuzzTokenByIndex(address,string[]) (runs: 256, μ: 24648475, ~: 25408685)
+ERC721Test:testFuzzTotalSupply(address,string[]) (runs: 256, μ: 24459897, ~: 25216053)
+ERC721Test:testFuzzTransferFrom(address,address,address) (runs: 256, μ: 561636, ~: 561619)
+ERC721Test:testFuzzTransferOwnershipNonOwner(address,address) (runs: 256, μ: 14626, ~: 14626)
+ERC721Test:testFuzzTransferOwnershipSuccess(address,address) (runs: 256, μ: 75542, ~: 75517)
+ERC721Test:testGetApprovedApprovedTokenId() (gas: 195041)
 ERC721Test:testGetApprovedInvalidTokenId() (gas: 11379)
-ERC721Test:testGetApprovedNotApprovedTokenId() (gas: 171352)
-ERC721Test:testHasOwner() (gas: 9893)
-ERC721Test:testInitialSetup() (gas: 2309452)
+ERC721Test:testGetApprovedNotApprovedTokenId() (gas: 171330)
+ERC721Test:testHasOwner() (gas: 9871)
+ERC721Test:testInitialSetup() (gas: 2399334)
 ERC721Test:testOwnerOf() (gas: 166927)
 ERC721Test:testOwnerOfInvalidTokenId() (gas: 11289)
-ERC721Test:testPermitBadChainId() (gas: 201270)
-ERC721Test:testPermitBadNonce() (gas: 198836)
-ERC721Test:testPermitExpiredDeadline() (gas: 172135)
-ERC721Test:testPermitOtherSignature() (gas: 199837)
-ERC721Test:testPermitReplaySignature() (gas: 232644)
-ERC721Test:testPermitSuccess() (gas: 228249)
-ERC721Test:testRenounceOwnershipNonOwner() (gas: 11447)
-ERC721Test:testRenounceOwnershipSuccess() (gas: 22969)
-ERC721Test:testSafeMintNonMinter() (gas: 13700)
+ERC721Test:testPermitBadChainId() (gas: 201336)
+ERC721Test:testPermitBadNonce() (gas: 198805)
+ERC721Test:testPermitExpiredDeadline() (gas: 172126)
+ERC721Test:testPermitOtherSignature() (gas: 199828)
+ERC721Test:testPermitReplaySignature() (gas: 232635)
+ERC721Test:testPermitSuccess() (gas: 228218)
+ERC721Test:testRenounceOwnershipNonOwner() (gas: 11470)
+ERC721Test:testRenounceOwnershipSuccess() (gas: 22992)
+ERC721Test:testSafeMintNonMinter() (gas: 13678)
 ERC721Test:testSafeMintOverflow() (gas: 15919)
-ERC721Test:testSafeMintReceiverContract() (gas: 389332)
+ERC721Test:testSafeMintReceiverContract() (gas: 389396)
 ERC721Test:testSafeMintReceiverContractFunctionNotImplemented() (gas: 116597)
-ERC721Test:testSafeMintReceiverContractInvalidReturnIdentifier() (gas: 340700)
-ERC721Test:testSafeMintReceiverContractRevertsWithMessage() (gas: 337971)
-ERC721Test:testSafeMintReceiverContractRevertsWithPanic() (gas: 338192)
+ERC721Test:testSafeMintReceiverContractInvalidReturnIdentifier() (gas: 340678)
+ERC721Test:testSafeMintReceiverContractRevertsWithMessage() (gas: 338016)
+ERC721Test:testSafeMintReceiverContractRevertsWithPanic() (gas: 338237)
 ERC721Test:testSafeMintReceiverContractRevertsWithoutMessage() (gas: 337579)
 ERC721Test:testSafeMintSuccess() (gas: 527860)
 ERC721Test:testSafeMintToZeroAddress() (gas: 38886)
-ERC721Test:testSafeMintTokenAlreadyMinted() (gas: 364764)
+ERC721Test:testSafeMintTokenAlreadyMinted() (gas: 364742)
 ERC721Test:testSafeTransferFromNoData() (gas: 1420584)
-ERC721Test:testSafeTransferFromReceiverFunctionNotImplemented() (gas: 181686)
-ERC721Test:testSafeTransferFromReceiverInvalidReturnIdentifier() (gas: 405782)
-ERC721Test:testSafeTransferFromReceiverRevertsWithMessage() (gas: 403100)
-ERC721Test:testSafeTransferFromReceiverRevertsWithPanic() (gas: 403366)
+ERC721Test:testSafeTransferFromReceiverFunctionNotImplemented() (gas: 181664)
+ERC721Test:testSafeTransferFromReceiverInvalidReturnIdentifier() (gas: 405760)
+ERC721Test:testSafeTransferFromReceiverRevertsWithMessage() (gas: 403056)
+ERC721Test:testSafeTransferFromReceiverRevertsWithPanic() (gas: 403322)
 ERC721Test:testSafeTransferFromReceiverRevertsWithoutMessage() (gas: 402664)
-ERC721Test:testSafeTransferFromWithData() (gas: 1193300)
+ERC721Test:testSafeTransferFromWithData() (gas: 1193282)
 ERC721Test:testSetApprovalForAllOperatorIsOwner() (gas: 168402)
 ERC721Test:testSetApprovalForAllSuccessCase1() (gas: 196725)
 ERC721Test:testSetApprovalForAllSuccessCase2() (gas: 190078)
 ERC721Test:testSetApprovalForAllSuccessCase3() (gas: 203418)
 ERC721Test:testSetMinterNonOwner() (gas: 13143)
 ERC721Test:testSetMinterRemoveOwnerAddress() (gas: 14342)
-ERC721Test:testSetMinterSuccess() (gas: 34174)
+ERC721Test:testSetMinterSuccess() (gas: 34156)
 ERC721Test:testSetMinterToZeroAddress() (gas: 16195)
 ERC721Test:testSupportsInterfaceGasCost() (gas: 5892)
-ERC721Test:testSupportsInterfaceInvalidInterfaceId() (gas: 5823)
-ERC721Test:testSupportsInterfaceSuccess() (gas: 11262)
-ERC721Test:testTokenByIndex() (gas: 558679)
-ERC721Test:testTokenByIndexOutOfBounds() (gas: 332075)
-ERC721Test:testTokenOfOwnerByIndex() (gas: 578577)
+ERC721Test:testSupportsInterfaceInvalidInterfaceId() (gas: 5888)
+ERC721Test:testSupportsInterfaceSuccess() (gas: 11240)
+ERC721Test:testTokenByIndex() (gas: 558724)
+ERC721Test:testTokenByIndexOutOfBounds() (gas: 332053)
+ERC721Test:testTokenOfOwnerByIndex() (gas: 578555)
 ERC721Test:testTokenOfOwnerByIndexReverts() (gas: 548169)
-ERC721Test:testTokenURIAfterBurning() (gas: 138594)
-ERC721Test:testTokenURIDefault() (gas: 169934)
-ERC721Test:testTokenURIInvalidTokenId() (gas: 11823)
-ERC721Test:testTokenURINoBaseURI() (gas: 2430930)
-ERC721Test:testTokenURINoTokenUri() (gas: 127014)
+ERC721Test:testTokenURIAfterBurning() (gas: 138711)
+ERC721Test:testTokenURIDefault() (gas: 170014)
+ERC721Test:testTokenURIInvalidTokenId() (gas: 11881)
+ERC721Test:testTokenURINoBaseURI() (gas: 2520572)
+ERC721Test:testTokenURINoTokenUri() (gas: 127117)
 ERC721Test:testTotalSupply() (gas: 330029)
-ERC721Test:testTransferFrom() (gas: 571108)
-ERC721Test:testTransferOwnershipNonOwner() (gas: 13125)
-ERC721Test:testTransferOwnershipSuccess() (gas: 53981)
-ERC721Test:testTransferOwnershipToZeroAddress() (gas: 16187)
+ERC721Test:testTransferFrom() (gas: 571161)
+ERC721Test:testTransferOwnershipNonOwner() (gas: 13214)
+ERC721Test:testTransferOwnershipSuccess() (gas: 54004)
+ERC721Test:testTransferOwnershipToZeroAddress() (gas: 16166)
 MathTest:testCbrtRoundDown() (gas: 44669)
 MathTest:testCbrtRoundUp() (gas: 45449)
 MathTest:testCeilDiv() (gas: 12699)
@@ -551,8 +559,8 @@ MathTest:testWadExp() (gas: 26657)
 MathTest:testWadExpOverflow() (gas: 10670)
 MathTest:testWadLn() (gas: 25780)
 MathTest:testWadLnNegativeValues() (gas: 10559)
-MerkleProofVerificationTest:testFuzzMultiProofVerifySingleLeaf(bytes32[],uint256) (runs: 256, μ: 1649976908, ~: 1649973601)
-MerkleProofVerificationTest:testFuzzVerify(bytes32[],uint256) (runs: 256, μ: 135975589, ~: 135972253)
+MerkleProofVerificationTest:testFuzzMultiProofVerifySingleLeaf(bytes32[],uint256) (runs: 256, μ: 1649976905, ~: 1649973611)
+MerkleProofVerificationTest:testFuzzVerify(bytes32[],uint256) (runs: 256, μ: 135975586, ~: 135972263)
 MerkleProofVerificationTest:testFuzzVerifyMultiProofMultipleLeaves(bool,bool,bool) (runs: 256, μ: 412472434, ~: 412472367)
 MerkleProofVerificationTest:testInvalidMerkleMultiProof() (gas: 412478445)
 MerkleProofVerificationTest:testInvalidMerkleProof() (gas: 33970386)
@@ -579,10 +587,10 @@ Ownable2StepInvariants:invariantPendingOwner() (runs: 256, calls: 3840, reverts:
 Ownable2StepTest:testAcceptOwnershipNonPendingOwner() (gas: 46640)
 Ownable2StepTest:testAcceptOwnershipSuccess() (gas: 39408)
 Ownable2StepTest:testFuzzAcceptOwnershipNonPendingOwner(address) (runs: 256, μ: 45872, ~: 45872)
-Ownable2StepTest:testFuzzAcceptOwnershipSuccess(address,address) (runs: 256, μ: 65120, ~: 65097)
-Ownable2StepTest:testFuzzPendingOwnerResetAfterRenounceOwnership(address) (runs: 256, μ: 38768, ~: 38754)
+Ownable2StepTest:testFuzzAcceptOwnershipSuccess(address,address) (runs: 256, μ: 65122, ~: 65097)
+Ownable2StepTest:testFuzzPendingOwnerResetAfterRenounceOwnership(address) (runs: 256, μ: 38769, ~: 38754)
 Ownable2StepTest:testFuzzRenounceOwnershipNonOwner(address) (runs: 256, μ: 13996, ~: 13996)
-Ownable2StepTest:testFuzzRenounceOwnershipSuccess(address) (runs: 256, μ: 43698, ~: 43684)
+Ownable2StepTest:testFuzzRenounceOwnershipSuccess(address) (runs: 256, μ: 43699, ~: 43684)
 Ownable2StepTest:testFuzzTransferOwnershipNonOwner(address,address) (runs: 256, μ: 14135, ~: 14135)
 Ownable2StepTest:testFuzzTransferOwnershipSuccess(address,address) (runs: 256, μ: 50445, ~: 50445)
 Ownable2StepTest:testHasOwner() (gas: 9641)
@@ -605,7 +613,7 @@ OwnableTest:testTransferOwnershipNonOwner() (gas: 12545)
 OwnableTest:testTransferOwnershipSuccess() (gas: 22005)
 OwnableTest:testTransferOwnershipToZeroAddress() (gas: 15519)
 SignatureCheckerTest:testEIP1271NoIsValidSignatureFunction() (gas: 22863)
-SignatureCheckerTest:testEIP1271WithInvalidSignature(bytes,string) (runs: 256, μ: 23606, ~: 23599)
+SignatureCheckerTest:testEIP1271WithInvalidSignature(bytes,string) (runs: 256, μ: 23607, ~: 23599)
 SignatureCheckerTest:testEIP1271WithInvalidSignature1() (gas: 33835)
 SignatureCheckerTest:testEIP1271WithInvalidSignature2() (gas: 29009)
 SignatureCheckerTest:testEIP1271WithInvalidSigner() (gas: 33913)
@@ -616,8 +624,8 @@ SignatureCheckerTest:testEOAWithInvalidSignature2() (gas: 20265)
 SignatureCheckerTest:testEOAWithInvalidSigner() (gas: 20498)
 SignatureCheckerTest:testEOAWithTooHighSValue() (gas: 17254)
 SignatureCheckerTest:testEOAWithValidSignature() (gas: 19597)
-SignatureCheckerTest:testFuzzEIP1271WithInvalidSigner(string,string) (runs: 256, μ: 35856, ~: 35869)
-SignatureCheckerTest:testFuzzEIP1271WithValidSignature(string) (runs: 256, μ: 34404, ~: 34407)
+SignatureCheckerTest:testFuzzEIP1271WithInvalidSigner(string,string) (runs: 256, μ: 35864, ~: 35869)
+SignatureCheckerTest:testFuzzEIP1271WithValidSignature(string) (runs: 256, μ: 34405, ~: 34407)
 SignatureCheckerTest:testFuzzEOAWithInvalidSignature(bytes,string) (runs: 256, μ: 16905, ~: 16900)
-SignatureCheckerTest:testFuzzEOAWithInvalidSigner(string,string) (runs: 256, μ: 21580, ~: 21590)
-SignatureCheckerTest:testFuzzEOAWithValidSignature(string,string) (runs: 256, μ: 20695, ~: 20705)
\ No newline at end of file
+SignatureCheckerTest:testFuzzEOAWithInvalidSigner(string,string) (runs: 256, μ: 21577, ~: 21590)
+SignatureCheckerTest:testFuzzEOAWithValidSignature(string,string) (runs: 256, μ: 20692, ~: 20705)
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6cdbb9e0..8aa5d9c3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,12 +1,18 @@
 # 🕓 Changelog
 
-## `0.0.2` (Unreleased)
+## `0.0.2` (07-06-2023)
 
 ### 💥 New Features
 
 - **General**
   - All 🐍 snekmate contracts now contain an _Ethereum Natural Language Specification Format_ (NatSpec) `custom` field `@custom:contract-name`. The underlying rationale is that the block explorers plan to use `@custom:contract-name` as contract name and `@title` as fallback. ([#124](https://github.com/pcaversaccio/snekmate/pull/124))
+- **Extensions**
+  - [`ERC4626`](https://github.com/pcaversaccio/snekmate/blob/v0.0.2/src/extensions/ERC4626.vy): Implements additionally the interface [`IERC5267`](https://github.com/pcaversaccio/snekmate/blob/v0.0.2/src/utils/interfaces/IERC5267.vy). ([#129](https://github.com/pcaversaccio/snekmate/pull/129))
+- **Tokens**
+  - [`ERC20`](https://github.com/pcaversaccio/snekmate/blob/v0.0.2/src/tokens/ERC20.vy): Implements additionally the interface [`IERC5267`](https://github.com/pcaversaccio/snekmate/blob/v0.0.2/src/utils/interfaces/IERC5267.vy). ([#129](https://github.com/pcaversaccio/snekmate/pull/129))
+  - [`ERC721`](https://github.com/pcaversaccio/snekmate/blob/v0.0.2/src/tokens/ERC721.vy): Implements additionally the interface [`IERC5267`](https://github.com/pcaversaccio/snekmate/blob/v0.0.2/src/utils/interfaces/IERC5267.vy). ([#129](https://github.com/pcaversaccio/snekmate/pull/129))
 - **Utility Functions**
+  - [`EIP712DomainSeparator`](https://github.com/pcaversaccio/snekmate/blob/v0.0.2/src/utils/EIP712DomainSeparator.vy): Implements additionally the interface [`IERC5267`](https://github.com/pcaversaccio/snekmate/blob/v0.0.2/src/utils/interfaces/IERC5267.vy). ([#129](https://github.com/pcaversaccio/snekmate/pull/129))
   - [`Math`](https://github.com/pcaversaccio/snekmate/blob/v0.0.2/src/utils/Math.vy): Add `wad_ln` and `wad_exp` to the standard mathematical utility functions. ([#91](https://github.com/pcaversaccio/snekmate/pull/91))
 
 ### ♻️ Refactoring
diff --git a/lib/create-util b/lib/create-util
index 7b57a5f2..3e16b8ac 160000
--- a/lib/create-util
+++ b/lib/create-util
@@ -1,1 +1,1 @@
-Subproject commit 7b57a5f23d016e0c7bab2490c15611d716bb18fe
+Subproject commit 3e16b8acaa3f0a47186ca387bc662fd7c3060ea1
diff --git a/lib/forge-std b/lib/forge-std
index e8a047e3..b00f504d 160000
--- a/lib/forge-std
+++ b/lib/forge-std
@@ -1,1 +1,1 @@
-Subproject commit e8a047e3f40f13fa37af6fe14e6e06283d9a060e
+Subproject commit b00f504daf0bdd8cf2e67973e2c86bd213cda400
diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts
index ffceb3cd..253bfa68 160000
--- a/lib/openzeppelin-contracts
+++ b/lib/openzeppelin-contracts
@@ -1,1 +1,1 @@
-Subproject commit ffceb3cd988874369806139ae9e59d2e2a93daec
+Subproject commit 253bfa68c27785536d58afcc95ebeb4af6f9aa7a
diff --git a/lib/solady b/lib/solady
index bc408fd5..a6227dc3 160000
--- a/lib/solady
+++ b/lib/solady
@@ -1,1 +1,1 @@
-Subproject commit bc408fd5f67db9e71fde18b997fb8ed28a8dd3de
+Subproject commit a6227dc30ce3898aa0b25df733597a97f0eaec49
diff --git a/package.json b/package.json
index 6e795c6a..88db041c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "snekmate",
-  "version": "0.0.1",
+  "version": "0.0.2-rc.1",
   "description": "State-of-the-art, highly opinionated, hyper-optimised, and secure Vyper smart contract building blocks.",
   "author": "Pascal Marco Caversaccio <pascal.caversaccio@hotmail.ch>",
   "license": "AGPL-3.0",
@@ -39,7 +39,7 @@
     "@openzeppelin/merkle-tree": "^1.0.4",
     "eslint": "^8.42.0",
     "eslint-config-prettier": "^8.8.0",
-    "ethers": "^6.4.1",
+    "ethers": "^6.4.2",
     "keccak256": "^1.0.6",
     "merkletreejs": "^0.3.10",
     "prettier": "^2.8.8",
diff --git a/pyproject.toml b/pyproject.toml
index db5b30dd..bcaf978b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [project]
 name = "snekmate"
-version = "0.0.1"
+version = "0.0.2rc1"
 description = "State-of-the-art, highly opinionated, hyper-optimised, and secure Vyper smart contract building blocks."
 readme = {file = "README.md", content-type = "text/markdown"}
 requires-python = ">=3.6"
diff --git a/src/extensions/ERC4626.vy b/src/extensions/ERC4626.vy
index 3da88b7b..dc1aefaa 100644
--- a/src/extensions/ERC4626.vy
+++ b/src/extensions/ERC4626.vy
@@ -11,10 +11,14 @@
         been added for convenience:
         - `permit` (`external` function),
         - `nonces` (`external` `view` function),
-        - `DOMAIN_SEPARATOR` (`external` `view` function).
+        - `DOMAIN_SEPARATOR` (`external` `view` function),
+        - `eip712Domain` (`external` `view` function).
         The `permit` function implements approvals via
         EIP-712 secp256k1 signatures:
         https://eips.ethereum.org/EIPS/eip-2612.
+        In addition, this contract also implements the EIP-5267
+        function `eip712Domain`:
+        https://eips.ethereum.org/EIPS/eip-5267.
         The implementation is inspired by OpenZeppelin's
         implementation here:
         https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC4626.sol,
@@ -74,10 +78,20 @@ from vyper.interfaces import ERC4626
 implements: ERC4626
 
 
+# @dev We import and implement the `IERC5267` interface,
+# which is written using standard Vyper syntax.
+from ..utils.interfaces.IERC5267 import IERC5267
+implements: IERC5267
+
+
 # @dev Constant used as part of the ECDSA recovery function.
 _MALLEABILITY_THRESHOLD: constant(bytes32) = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0
 
 
+# @dev The 32-byte type hash for the EIP-712 domain separator.
+_TYPE_HASH: constant(bytes32) = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
+
+
 # @dev The 32-byte type hash of the `permit` function.
 _PERMIT_TYPE_HASH: constant(bytes32) = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")
 
@@ -117,19 +131,25 @@ asset: public(immutable(ERC20))
 
 
 # @dev Caches the domain separator as an `immutable`
-# value, but also stores the corresponding chain id
+# value, but also stores the corresponding chain ID
 # to invalidate the cached domain separator if the
-# chain id changes.
+# chain ID changes.
+_CACHED_DOMAIN_SEPARATOR: immutable(bytes32)
 _CACHED_CHAIN_ID: immutable(uint256)
+
+
+# @dev Caches `self` to `immutable` storage to avoid
+# potential issues if a vanilla contract is used in
+# a `delegatecall` context.
 _CACHED_SELF: immutable(address)
-_CACHED_DOMAIN_SEPARATOR: immutable(bytes32)
 
 
-# @dev `immutable` variables to store the name,
-# version, and type hash during contract creation.
+# @dev `immutable` variables to store the (hashed)
+# name and (hashed) version during contract creation.
+_NAME: immutable(String[50])
 _HASHED_NAME: immutable(bytes32)
+_VERSION: immutable(String[20])
 _HASHED_VERSION: immutable(bytes32)
-_TYPE_HASH: immutable(bytes32)
 
 
 # @dev An offset in the decimal representation between
@@ -206,6 +226,12 @@ event Withdraw:
     shares: uint256
 
 
+# @dev May be emitted to signal that the domain could
+# have changed.
+event EIP712DomainChanged:
+    pass
+
+
 @external
 @payable
 def __init__(name_: String[25], symbol_: String[5], asset_: ERC20, decimals_offset_: uint8, name_eip712_: String[50], version_eip712_: String[20]):
@@ -247,15 +273,13 @@ def __init__(name_: String[25], symbol_: String[5], asset_: ERC20, decimals_offs
     # to prevent a theoretically possible overflow.
     decimals = _UNDERLYING_DECIMALS + _DECIMALS_OFFSET
 
-    hashed_name: bytes32 = keccak256(convert(name_eip712_, Bytes[50]))
-    hashed_version: bytes32 = keccak256(convert(version_eip712_, Bytes[20]))
-    type_hash: bytes32 = keccak256(convert("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)", Bytes[82]))
-    _HASHED_NAME = hashed_name
-    _HASHED_VERSION = hashed_version
-    _TYPE_HASH = type_hash
+    _NAME = name_eip712_
+    _VERSION = version_eip712_
+    _HASHED_NAME = keccak256(name_eip712_)
+    _HASHED_VERSION = keccak256(version_eip712_)
+    _CACHED_DOMAIN_SEPARATOR = self._build_domain_separator()
     _CACHED_CHAIN_ID = chain.id
     _CACHED_SELF = self
-    _CACHED_DOMAIN_SEPARATOR = self._build_domain_separator(type_hash, hashed_name, hashed_version)
 
 
 @external
@@ -348,6 +372,32 @@ def DOMAIN_SEPARATOR() -> bytes32:
     return self._domain_separator_v4()
 
 
+@external
+@view
+def eip712Domain() -> (bytes1, String[50], String[20], uint256, address, bytes32, DynArray[uint256, 128]):
+    """
+    @dev Returns the fields and values that describe the domain
+         separator used by this contract for EIP-712 signatures.
+    @notice The bits in the 1-byte bit map are read from the least
+            significant to the most significant, and fields are indexed
+            in the order that is specified by EIP-712, identical to the
+            order in which they are listed in the function type.
+    @return bytes1 The 1-byte bit map where bit `i` is set to 1
+            if and only if domain field `i` is present (`0 ≤ i ≤ 4`).
+    @return String The maximum 50-character user-readable string name
+            of the signing domain, i.e. the name of the dApp or protocol.
+    @return String The maximum 20-character current main version of
+            the signing domain. Signatures from different versions are
+            not compatible.
+    @return uint256 The 32-byte EIP-155 chain ID.
+    @return address The 20-byte address of the verifying contract.
+    @return bytes32 The 32-byte disambiguation salt for the protocol.
+    @return DynArray The 32-byte array of EIP-712 extensions.
+    """
+    # Note that `\x0f` equals `01111`.
+    return (convert(b"\x0f", bytes1), _NAME, _VERSION, chain.id, self, empty(bytes32), empty(DynArray[uint256, 128]))
+
+
 @external
 @view
 def totalAssets() -> uint256:
@@ -704,18 +754,18 @@ def _domain_separator_v4() -> bytes32:
     if (self == _CACHED_SELF and chain.id == _CACHED_CHAIN_ID):
         return _CACHED_DOMAIN_SEPARATOR
     else:
-        return self._build_domain_separator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION)
+        return self._build_domain_separator()
 
 
 @internal
 @view
-def _build_domain_separator(type_hash: bytes32, name_hash: bytes32, version_hash: bytes32) -> bytes32:
+def _build_domain_separator() -> bytes32:
     """
     @dev Sourced from {EIP712DomainSeparator-_build_domain_separator}.
     @notice See {EIP712DomainSeparator-_build_domain_separator}
             for the function docstring.
     """
-    return keccak256(_abi_encode(type_hash, name_hash, version_hash, chain.id, self))
+    return keccak256(_abi_encode(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION, chain.id, self))
 
 
 @internal
diff --git a/src/tokens/ERC20.vy b/src/tokens/ERC20.vy
index c10fdf84..5d85d339 100644
--- a/src/tokens/ERC20.vy
+++ b/src/tokens/ERC20.vy
@@ -22,6 +22,7 @@
         - `permit` (`external` function),
         - `nonces` (`external` `view` function),
         - `DOMAIN_SEPARATOR` (`external` `view` function),
+        - `eip712Domain` (`external` `view` function),
         - `owner` (`external` `view` function),
         - `transfer_ownership` (`external` function),
         - `renounce_ownership` (`external` function),
@@ -30,6 +31,9 @@
         The `permit` function implements approvals via
         EIP-712 secp256k1 signatures:
         https://eips.ethereum.org/EIPS/eip-2612.
+        In addition, this contract also implements the EIP-5267
+        function `eip712Domain`:
+        https://eips.ethereum.org/EIPS/eip-5267.
         The implementation is inspired by OpenZeppelin's
         implementation here:
         https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol,
@@ -68,6 +72,12 @@ import interfaces.IERC20Permit as IERC20Permit
 implements: IERC20Permit
 
 
+# @dev We import and implement the `IERC5267` interface,
+# which is written using standard Vyper syntax.
+from ..utils.interfaces.IERC5267 import IERC5267
+implements: IERC5267
+
+
 # @dev Returns the decimals places of the token.
 # The default value is 18.
 # @notice If you declare a variable as `public`,
@@ -85,6 +95,10 @@ decimals: public(constant(uint8)) = 18
 _MALLEABILITY_THRESHOLD: constant(bytes32) = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0
 
 
+# @dev The 32-byte type hash for the EIP-712 domain separator.
+_TYPE_HASH: constant(bytes32) = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
+
+
 # @dev The 32-byte type hash of the `permit` function.
 _PERMIT_TYPE_HASH: constant(bytes32) = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")
 
@@ -102,19 +116,25 @@ symbol: public(immutable(String[5]))
 
 
 # @dev Caches the domain separator as an `immutable`
-# value, but also stores the corresponding chain id
+# value, but also stores the corresponding chain ID
 # to invalidate the cached domain separator if the
-# chain id changes.
+# chain ID changes.
+_CACHED_DOMAIN_SEPARATOR: immutable(bytes32)
 _CACHED_CHAIN_ID: immutable(uint256)
+
+
+# @dev Caches `self` to `immutable` storage to avoid
+# potential issues if a vanilla contract is used in
+# a `delegatecall` context.
 _CACHED_SELF: immutable(address)
-_CACHED_DOMAIN_SEPARATOR: immutable(bytes32)
 
 
-# @dev `immutable` variables to store the name,
-# version, and type hash during contract creation.
+# @dev `immutable` variables to store the (hashed)
+# name and (hashed) version during contract creation.
+_NAME: immutable(String[50])
 _HASHED_NAME: immutable(bytes32)
+_VERSION: immutable(String[20])
 _HASHED_VERSION: immutable(bytes32)
-_TYPE_HASH: immutable(bytes32)
 
 
 # @dev Returns the amount of tokens owned by an `address`.
@@ -166,6 +186,12 @@ event Approval:
     amount: uint256
 
 
+# @dev May be emitted to signal that the domain could
+# have changed.
+event EIP712DomainChanged:
+    pass
+
+
 # @dev Emitted when the ownership is transferred
 # from `previous_owner` to `new_owner`.
 event OwnershipTransferred:
@@ -217,15 +243,13 @@ def __init__(name_: String[25], symbol_: String[5], initial_supply_: uint256, na
         log Transfer(empty(address), msg.sender, initial_supply)
         self._after_token_transfer(empty(address), msg.sender, initial_supply)
 
-    hashed_name: bytes32 = keccak256(convert(name_eip712_, Bytes[50]))
-    hashed_version: bytes32 = keccak256(convert(version_eip712_, Bytes[20]))
-    type_hash: bytes32 = keccak256(convert("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)", Bytes[82]))
-    _HASHED_NAME = hashed_name
-    _HASHED_VERSION = hashed_version
-    _TYPE_HASH = type_hash
+    _NAME = name_eip712_
+    _VERSION = version_eip712_
+    _HASHED_NAME = keccak256(name_eip712_)
+    _HASHED_VERSION = keccak256(version_eip712_)
+    _CACHED_DOMAIN_SEPARATOR = self._build_domain_separator()
     _CACHED_CHAIN_ID = chain.id
     _CACHED_SELF = self
-    _CACHED_DOMAIN_SEPARATOR = self._build_domain_separator(type_hash, hashed_name, hashed_version)
 
 
 @external
@@ -450,6 +474,32 @@ def DOMAIN_SEPARATOR() -> bytes32:
     return self._domain_separator_v4()
 
 
+@external
+@view
+def eip712Domain() -> (bytes1, String[50], String[20], uint256, address, bytes32, DynArray[uint256, 128]):
+    """
+    @dev Returns the fields and values that describe the domain
+         separator used by this contract for EIP-712 signatures.
+    @notice The bits in the 1-byte bit map are read from the least
+            significant to the most significant, and fields are indexed
+            in the order that is specified by EIP-712, identical to the
+            order in which they are listed in the function type.
+    @return bytes1 The 1-byte bit map where bit `i` is set to 1
+            if and only if domain field `i` is present (`0 ≤ i ≤ 4`).
+    @return String The maximum 50-character user-readable string name
+            of the signing domain, i.e. the name of the dApp or protocol.
+    @return String The maximum 20-character current main version of
+            the signing domain. Signatures from different versions are
+            not compatible.
+    @return uint256 The 32-byte EIP-155 chain ID.
+    @return address The 20-byte address of the verifying contract.
+    @return bytes32 The 32-byte disambiguation salt for the protocol.
+    @return DynArray The 32-byte array of EIP-712 extensions.
+    """
+    # Note that `\x0f` equals `01111`.
+    return (convert(b"\x0f", bytes1), _NAME, _VERSION, chain.id, self, empty(bytes32), empty(DynArray[uint256, 128]))
+
+
 @external
 def transfer_ownership(new_owner: address):
     """
@@ -692,18 +742,18 @@ def _domain_separator_v4() -> bytes32:
     if (self == _CACHED_SELF and chain.id == _CACHED_CHAIN_ID):
         return _CACHED_DOMAIN_SEPARATOR
     else:
-        return self._build_domain_separator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION)
+        return self._build_domain_separator()
 
 
 @internal
 @view
-def _build_domain_separator(type_hash: bytes32, name_hash: bytes32, version_hash: bytes32) -> bytes32:
+def _build_domain_separator() -> bytes32:
     """
     @dev Sourced from {EIP712DomainSeparator-_build_domain_separator}.
     @notice See {EIP712DomainSeparator-_build_domain_separator}
             for the function docstring.
     """
-    return keccak256(_abi_encode(type_hash, name_hash, version_hash, chain.id, self))
+    return keccak256(_abi_encode(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION, chain.id, self))
 
 
 @internal
diff --git a/src/tokens/ERC721.vy b/src/tokens/ERC721.vy
index 9d81d2b5..ee67681f 100644
--- a/src/tokens/ERC721.vy
+++ b/src/tokens/ERC721.vy
@@ -22,6 +22,7 @@
         - `permit` (`external` function),
         - `nonces` (`external` `view` function),
         - `DOMAIN_SEPARATOR` (`external` `view` function),
+        - `eip712Domain` (`external` `view` function),
         - `owner` (`external` `view` function),
         - `transfer_ownership` (`external` function),
         - `renounce_ownership` (`external` function),
@@ -31,6 +32,12 @@
         The `permit` function implements approvals via
         EIP-712 secp256k1 signatures for ERC-721 tokens:
         https://eips.ethereum.org/EIPS/eip-4494.
+        In addition, this contract also implements the EIP-5267
+        function `eip712Domain`:
+        https://eips.ethereum.org/EIPS/eip-5267.
+        Eventually, this contract also implements the EIP-4906
+        metadata update extension:
+        https://eips.ethereum.org/EIPS/eip-4906.
         The implementation is inspired by OpenZeppelin's
         implementation here:
         https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol,
@@ -78,6 +85,12 @@ import interfaces.IERC4906 as IERC4906
 implements: IERC4906
 
 
+# @dev We import and implement the `IERC5267` interface,
+# which is written using standard Vyper syntax.
+from ..utils.interfaces.IERC5267 import IERC5267
+implements: IERC5267
+
+
 # @dev We import the `IERC721Receiver` interface, which
 # is written using standard Vyper syntax.
 import interfaces.IERC721Receiver as IERC721Receiver
@@ -101,6 +114,10 @@ _SUPPORTED_INTERFACES: constant(bytes4[6]) = [
 _MALLEABILITY_THRESHOLD: constant(bytes32) = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0
 
 
+# @dev The 32-byte type hash for the EIP-712 domain separator.
+_TYPE_HASH: constant(bytes32) = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
+
+
 # @dev The 32-byte type hash of the `permit` function.
 _PERMIT_TYPE_HASH: constant(bytes32) = keccak256("Permit(address spender,uint256 tokenId,uint256 nonce,uint256 deadline)")
 
@@ -127,19 +144,25 @@ _BASE_URI: immutable(String[80])
 
 
 # @dev Caches the domain separator as an `immutable`
-# value, but also stores the corresponding chain id
+# value, but also stores the corresponding chain ID
 # to invalidate the cached domain separator if the
-# chain id changes.
+# chain ID changes.
+_CACHED_DOMAIN_SEPARATOR: immutable(bytes32)
 _CACHED_CHAIN_ID: immutable(uint256)
+
+
+# @dev Caches `self` to `immutable` storage to avoid
+# potential issues if a vanilla contract is used in
+# a `delegatecall` context.
 _CACHED_SELF: immutable(address)
-_CACHED_DOMAIN_SEPARATOR: immutable(bytes32)
 
 
-# @dev `immutable` variables to store the name,
-# version, and type hash during contract creation.
+# @dev `immutable` variables to store the (hashed)
+# name and (hashed) version during contract creation.
+_NAME: immutable(String[50])
 _HASHED_NAME: immutable(bytes32)
+_VERSION: immutable(String[20])
 _HASHED_VERSION: immutable(bytes32)
-_TYPE_HASH: immutable(bytes32)
 
 
 # @dev Mapping from owner to operator approvals.
@@ -245,6 +268,12 @@ event BatchMetadataUpdate:
     token_id: uint256
 
 
+# @dev May be emitted to signal that the domain could
+# have changed.
+event EIP712DomainChanged:
+    pass
+
+
 # @dev Emitted when the ownership is transferred
 # from `previous_owner` to `new_owner`.
 event OwnershipTransferred:
@@ -291,15 +320,13 @@ def __init__(name_: String[25], symbol_: String[5], base_uri_: String[80], name_
     self.is_minter[msg.sender] = True
     log RoleMinterChanged(msg.sender, True)
 
-    hashed_name: bytes32 = keccak256(convert(name_eip712_, Bytes[50]))
-    hashed_version: bytes32 = keccak256(convert(version_eip712_, Bytes[20]))
-    type_hash: bytes32 = keccak256(convert("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)", Bytes[82]))
-    _HASHED_NAME = hashed_name
-    _HASHED_VERSION = hashed_version
-    _TYPE_HASH = type_hash
+    _NAME = name_eip712_
+    _VERSION = version_eip712_
+    _HASHED_NAME = keccak256(name_eip712_)
+    _HASHED_VERSION = keccak256(version_eip712_)
+    _CACHED_DOMAIN_SEPARATOR = self._build_domain_separator()
     _CACHED_CHAIN_ID = chain.id
     _CACHED_SELF = self
-    _CACHED_DOMAIN_SEPARATOR = self._build_domain_separator(type_hash, hashed_name, hashed_version)
 
 
 @external
@@ -647,6 +674,32 @@ def DOMAIN_SEPARATOR() -> bytes32:
     return self._domain_separator_v4()
 
 
+@external
+@view
+def eip712Domain() -> (bytes1, String[50], String[20], uint256, address, bytes32, DynArray[uint256, 128]):
+    """
+    @dev Returns the fields and values that describe the domain
+         separator used by this contract for EIP-712 signatures.
+    @notice The bits in the 1-byte bit map are read from the least
+            significant to the most significant, and fields are indexed
+            in the order that is specified by EIP-712, identical to the
+            order in which they are listed in the function type.
+    @return bytes1 The 1-byte bit map where bit `i` is set to 1
+            if and only if domain field `i` is present (`0 ≤ i ≤ 4`).
+    @return String The maximum 50-character user-readable string name
+            of the signing domain, i.e. the name of the dApp or protocol.
+    @return String The maximum 20-character current main version of
+            the signing domain. Signatures from different versions are
+            not compatible.
+    @return uint256 The 32-byte EIP-155 chain ID.
+    @return address The 20-byte address of the verifying contract.
+    @return bytes32 The 32-byte disambiguation salt for the protocol.
+    @return DynArray The 32-byte array of EIP-712 extensions.
+    """
+    # Note that `\x0f` equals `01111`.
+    return (convert(b"\x0f", bytes1), _NAME, _VERSION, chain.id, self, empty(bytes32), empty(DynArray[uint256, 128]))
+
+
 @external
 def transfer_ownership(new_owner: address):
     """
@@ -1173,18 +1226,18 @@ def _domain_separator_v4() -> bytes32:
     if (self == _CACHED_SELF and chain.id == _CACHED_CHAIN_ID):
         return _CACHED_DOMAIN_SEPARATOR
     else:
-        return self._build_domain_separator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION)
+        return self._build_domain_separator()
 
 
 @internal
 @view
-def _build_domain_separator(type_hash: bytes32, name_hash: bytes32, version_hash: bytes32) -> bytes32:
+def _build_domain_separator() -> bytes32:
     """
     @dev Sourced from {EIP712DomainSeparator-_build_domain_separator}.
     @notice See {EIP712DomainSeparator-_build_domain_separator}
             for the function docstring.
     """
-    return keccak256(_abi_encode(type_hash, name_hash, version_hash, chain.id, self))
+    return keccak256(_abi_encode(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION, chain.id, self))
 
 
 @internal
diff --git a/src/tokens/interfaces/IERC4906.vy b/src/tokens/interfaces/IERC4906.vy
index f379d135..21d8e80c 100644
--- a/src/tokens/interfaces/IERC4906.vy
+++ b/src/tokens/interfaces/IERC4906.vy
@@ -6,7 +6,7 @@
 @author pcaversaccio
 @notice The ERC-4906 standard is an extension of EIP-721.
         It adds a `MetadataUpdate` event to EIP-721 tokens.
-        The ERC-165 identifier for this interface is 0x49064906.
+        The ERC-165 identifier for this interface is `0x49064906`.
         For more details, please refer to:
         https://eips.ethereum.org/EIPS/eip-4906.
 
diff --git a/src/tokens/interfaces/IERC721Permit.vy b/src/tokens/interfaces/IERC721Permit.vy
index ca5c34a2..e59264bc 100644
--- a/src/tokens/interfaces/IERC721Permit.vy
+++ b/src/tokens/interfaces/IERC721Permit.vy
@@ -21,7 +21,7 @@
         implement the `permit` function via the secp256k1 signature
         parameters `v`, `r`, and `s` and do not support EIP-2098
         signatures (64-byte length, see https://eips.ethereum.org/EIPS/eip-2098).
-        The ERC-165 identifier for this interface is 0x589C5CE2.
+        The ERC-165 identifier for this interface is `0x589C5CE2`.
 
         On how to use interfaces in Vyper, please visit:
         https://vyper.readthedocs.io/en/latest/interfaces.html#interfaces.
diff --git a/src/utils/EIP712DomainSeparator.vy b/src/utils/EIP712DomainSeparator.vy
index 4160666e..a5555cb3 100644
--- a/src/utils/EIP712DomainSeparator.vy
+++ b/src/utils/EIP712DomainSeparator.vy
@@ -8,25 +8,49 @@
         These functions implement the version of encoding known
         as "v4" as implemented by the JSON-RPC method:
         https://docs.metamask.io/guide/signing-data.html#sign-typed-data-v4.
+        In addition, this contract also implements EIP-5267:
+        https://eips.ethereum.org/EIPS/eip-5267.
         The implementation is inspired by OpenZeppelin's implementation here:
         https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/draft-EIP712.sol.
 """
 
 
+# @dev We import and implement the `IERC5267` interface,
+# which is written using standard Vyper syntax.
+import interfaces.IERC5267 as IERC5267
+implements: IERC5267
+
+
+# @dev The 32-byte type hash for the EIP-712 domain separator.
+_TYPE_HASH: constant(bytes32) = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
+
+
 # @dev Caches the domain separator as an `immutable`
-# value, but also stores the corresponding chain id
+# value, but also stores the corresponding chain ID
 # to invalidate the cached domain separator if the
-# chain id changes.
+# chain ID changes.
+_CACHED_DOMAIN_SEPARATOR: immutable(bytes32)
 _CACHED_CHAIN_ID: immutable(uint256)
+
+
+# @dev Caches `self` to `immutable` storage to avoid
+# potential issues if a vanilla contract is used in
+# a `delegatecall` context.
 _CACHED_SELF: immutable(address)
-_CACHED_DOMAIN_SEPARATOR: immutable(bytes32)
 
 
-# @dev `immutable` variables to store the name,
-# version, and type hash during contract creation.
+# @dev `immutable` variables to store the (hashed)
+# name and (hashed) version during contract creation.
+_NAME: immutable(String[50])
 _HASHED_NAME: immutable(bytes32)
+_VERSION: immutable(String[20])
 _HASHED_VERSION: immutable(bytes32)
-_TYPE_HASH: immutable(bytes32)
+
+
+# @dev May be emitted to signal that the domain could
+# have changed.
+event EIP712DomainChanged:
+    pass
 
 
 @external
@@ -48,15 +72,13 @@ def __init__(name_: String[50], version_: String[20]):
            the signing domain. Signatures from different versions are
            not compatible.
     """
-    hashed_name: bytes32 = keccak256(convert(name_, Bytes[50]))
-    hashed_version: bytes32 = keccak256(convert(version_, Bytes[20]))
-    type_hash: bytes32 = keccak256(convert("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)", Bytes[82]))
-    _HASHED_NAME = hashed_name
-    _HASHED_VERSION = hashed_version
-    _TYPE_HASH = type_hash
+    _NAME = name_
+    _VERSION = version_
+    _HASHED_NAME = keccak256(name_)
+    _HASHED_VERSION = keccak256(version_)
+    _CACHED_DOMAIN_SEPARATOR = self._build_domain_separator()
     _CACHED_CHAIN_ID = chain.id
     _CACHED_SELF = self
-    _CACHED_DOMAIN_SEPARATOR = self._build_domain_separator(type_hash, hashed_name, hashed_version)
 
 
 @external
@@ -84,6 +106,32 @@ def hash_typed_data_v4(struct_hash: bytes32) -> bytes32:
     return self._to_typed_data_hash(self._domain_separator_v4(), struct_hash)
 
 
+@external
+@view
+def eip712Domain() -> (bytes1, String[50], String[20], uint256, address, bytes32, DynArray[uint256, 128]):
+    """
+    @dev Returns the fields and values that describe the domain
+         separator used by this contract for EIP-712 signatures.
+    @notice The bits in the 1-byte bit map are read from the least
+            significant to the most significant, and fields are indexed
+            in the order that is specified by EIP-712, identical to the
+            order in which they are listed in the function type.
+    @return bytes1 The 1-byte bit map where bit `i` is set to 1
+            if and only if domain field `i` is present (`0 ≤ i ≤ 4`).
+    @return String The maximum 50-character user-readable string name
+            of the signing domain, i.e. the name of the dApp or protocol.
+    @return String The maximum 20-character current main version of
+            the signing domain. Signatures from different versions are
+            not compatible.
+    @return uint256 The 32-byte EIP-155 chain ID.
+    @return address The 20-byte address of the verifying contract.
+    @return bytes32 The 32-byte disambiguation salt for the protocol.
+    @return DynArray The 32-byte array of EIP-712 extensions.
+    """
+    # Note that `\x0f` equals `01111`.
+    return (convert(b"\x0f", bytes1), _NAME, _VERSION, chain.id, self, empty(bytes32), empty(DynArray[uint256, 128]))
+
+
 @internal
 @view
 def _domain_separator_v4() -> bytes32:
@@ -95,20 +143,17 @@ def _domain_separator_v4() -> bytes32:
     if (self == _CACHED_SELF and chain.id == _CACHED_CHAIN_ID):
         return _CACHED_DOMAIN_SEPARATOR
     else:
-        return self._build_domain_separator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION)
+        return self._build_domain_separator()
 
 
 @internal
 @view
-def _build_domain_separator(type_hash: bytes32, name_hash: bytes32, version_hash: bytes32) -> bytes32:
+def _build_domain_separator() -> bytes32:
     """
     @dev Builds the domain separator for the current chain.
-    @param type_hash The 32-byte hashed type.
-    @param name_hash The 32-byte hashed name.
-    @param version_hash The 32-byte hashed version.
     @return bytes32 The 32-byte domain separator.
     """
-    return keccak256(_abi_encode(type_hash, name_hash, version_hash, chain.id, self))
+    return keccak256(_abi_encode(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION, chain.id, self))
 
 
 @internal
diff --git a/src/utils/Multicall.vy b/src/utils/Multicall.vy
index 7bea3ce1..c88dcaa5 100644
--- a/src/utils/Multicall.vy
+++ b/src/utils/Multicall.vy
@@ -5,7 +5,11 @@
 @license GNU Affero General Public License v3.0
 @author pcaversaccio
 @notice These functions can be used to batch together multiple external
-        function calls into one single external function call.
+        function calls into one single external function call. Please note
+        that this contract is written in the most agnostic way possible and
+        users should adjust statically allocatable memory to their specific
+        needs before deploying it:
+        https://github.com/pcaversaccio/snekmate/discussions/82.
         The implementation is inspired by Matt Solomon's implementation here:
         https://github.com/mds1/multicall/blob/master/src/Multicall3.sol.
 @custom:security Make sure you understand how `msg.sender` works in `CALL` vs
diff --git a/src/utils/interfaces/IERC5267.vy b/src/utils/interfaces/IERC5267.vy
new file mode 100644
index 00000000..29bf88f8
--- /dev/null
+++ b/src/utils/interfaces/IERC5267.vy
@@ -0,0 +1,56 @@
+# @version ^0.3.9
+"""
+@title EIP-5267 Interface Definition
+@custom:contract-name IERC5267
+@license GNU Affero General Public License v3.0
+@author pcaversaccio
+@notice The ERC-5267 standard complements the EIP-712 standard
+        by standardising how contracts should publish the fields
+        and values that describe their domain. This enables
+        applications to retrieve this description and generate
+        appropriate domain separators in a general way, and thus
+        integrate EIP-712 signatures securely and scalably. For
+        more details, please refer to:
+        https://eips.ethereum.org/EIPS/eip-5267.
+
+        Note that Vyper interfaces that implement functions
+        with return values that require an upper bound (e.g.
+        `Bytes`, `DynArray`, or `String`), the upper bound
+        defined in the interface represents the lower bound
+        of the implementation:
+        https://github.com/vyperlang/vyper/pull/3205.
+
+        On how to use interfaces in Vyper, please visit:
+        https://vyper.readthedocs.io/en/latest/interfaces.html#interfaces.
+"""
+
+
+# @dev May be emitted to signal that the domain could
+# have changed.
+event EIP712DomainChanged:
+    pass
+
+
+@external
+@view
+def eip712Domain() -> (bytes1, String[50], String[20], uint256, address, bytes32, DynArray[uint256, 128]):
+    """
+    @dev Returns the fields and values that describe the domain
+         separator used by this contract for EIP-712 signatures.
+    @notice The bits in the 1-byte bit map are read from the least
+            significant to the most significant, and fields are indexed
+            in the order that is specified by EIP-712, identical to the
+            order in which they are listed in the function type.
+    @return bytes1 The 1-byte bit map where bit `i` is set to 1
+            if and only if domain field `i` is present (`0 ≤ i ≤ 4`).
+    @return String The maximum 50-character user-readable string name
+            of the signing domain, i.e. the name of the dApp or protocol.
+    @return String The maximum 20-character current main version of
+            the signing domain. Signatures from different versions are
+            not compatible.
+    @return uint256 The 32-byte EIP-155 chain ID.
+    @return address The 20-byte address of the verifying contract.
+    @return bytes32 The 32-byte disambiguation salt for the protocol.
+    @return DynArray The 32-byte array of EIP-712 extensions.
+    """
+    return (empty(bytes1), empty(String[50]), empty(String[20]), empty(uint256), empty(address), empty(bytes32), empty(DynArray[uint256, 128]))
diff --git a/yarn.lock b/yarn.lock
index f9cda4fe..a9e8fe29 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,9 +2,10 @@
 # yarn lockfile v1
 
 
-"@adraffy/ens-normalize@git+https://github.com/ricmoo/ens-normalize.js.git":
-  version "1.9.0"
-  resolved "git+https://github.com/ricmoo/ens-normalize.js.git#2d040533e57e4f25f9a7cc4715e219658ad454b5"
+"@adraffy/ens-normalize@1.9.2":
+  version "1.9.2"
+  resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.9.2.tgz#60111a5d9db45b2e5cbb6231b0bb8d97e8659316"
+  integrity sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg==
 
 "@eslint-community/eslint-utils@^4.2.0":
   version "4.4.0"
@@ -743,12 +744,12 @@ ethereumjs-util@^7.1.0:
     ethereum-cryptography "^0.1.3"
     rlp "^2.2.4"
 
-ethers@^6.4.1:
-  version "6.4.1"
-  resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.4.1.tgz#fdfb5b987f239980a416879930e89d1817ff22ca"
-  integrity sha512-dBY7rBmoqI7ndCOsaafWEk1Snh2ilSRrLcRghb1FwY51Jze0NKGgn4ZjYAqDcji1lvUzFPEG0/u6w/nH6xJ6pw==
+ethers@^6.4.2:
+  version "6.4.2"
+  resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.4.2.tgz#8304660278ef7d43959ad5c73ccf14d0e32e0a3f"
+  integrity sha512-c+vcTycVHp1bN6msgs9iscZKQgEqdzFh6omyvil2musktHJkPtWOKMuiGVBlBqMV100At5AAZBzG9HUBcUWKQA==
   dependencies:
-    "@adraffy/ens-normalize" "https://github.com/ricmoo/ens-normalize.js"
+    "@adraffy/ens-normalize" "1.9.2"
     "@noble/hashes" "1.1.2"
     "@noble/secp256k1" "1.7.1"
     "@types/node" "18.15.13"


Test patch:
diff --git a/test/extensions/ERC4626.t.sol b/test/extensions/ERC4626.t.sol
index 01770ac3..083fd0d6 100644
--- a/test/extensions/ERC4626.t.sol
+++ b/test/extensions/ERC4626.t.sol
@@ -1841,6 +1841,36 @@ contract ERC4626VaultTest is ERC4626Test {
         assertEq(ERC4626ExtendedDecimalsOffset0.DOMAIN_SEPARATOR(), digest);
     }
 
+    function testEIP712Domain() public {
+        (
+            bytes1 fields,
+            string memory name,
+            string memory version,
+            uint256 chainId,
+            address verifyingContract,
+            bytes32 salt,
+            uint256[] memory extensions
+        ) = ERC4626ExtendedDecimalsOffset0.eip712Domain();
+        assertEq(fields, hex"0f");
+        assertEq(name, _NAME_EIP712);
+        assertEq(version, _VERSION_EIP712);
+        assertEq(chainId, block.chainid);
+        assertEq(verifyingContract, ERC4626ExtendedDecimalsOffset0Addr);
+        assertEq(salt, bytes32(0));
+        assertEq(extensions, new uint256[](0));
+
+        bytes32 digest = keccak256(
+            abi.encode(
+                _TYPE_HASH,
+                keccak256(bytes(name)),
+                keccak256(bytes(version)),
+                chainId,
+                verifyingContract
+            )
+        );
+        assertEq(ERC4626ExtendedDecimalsOffset0.DOMAIN_SEPARATOR(), digest);
+    }
+
     function testFuzzPermitSuccess(
         string calldata owner,
         string calldata spender,
@@ -1952,6 +1982,50 @@ contract ERC4626VaultTest is ERC4626Test {
         );
         assertEq(ERC4626ExtendedDecimalsOffset0.DOMAIN_SEPARATOR(), digest);
     }
+
+    function testFuzzEIP712Domain(
+        bytes1 randomHex,
+        uint8 increment,
+        bytes32 randomSalt,
+        uint256[] calldata randomExtensions
+    ) public {
+        vm.assume(
+            randomHex != hex"0f" &&
+                randomSalt != bytes32(0) &&
+                randomExtensions.length != 0
+        );
+        vm.chainId(block.chainid + increment);
+        (
+            bytes1 fields,
+            string memory name,
+            string memory version,
+            uint256 chainId,
+            address verifyingContract,
+            bytes32 salt,
+            uint256[] memory extensions
+        ) = ERC4626ExtendedDecimalsOffset0.eip712Domain();
+        assertTrue(fields != randomHex);
+        assertEq(name, _NAME_EIP712);
+        assertEq(version, _VERSION_EIP712);
+        assertEq(chainId, block.chainid);
+        assertEq(verifyingContract, ERC4626ExtendedDecimalsOffset0Addr);
+        assertTrue(salt != randomSalt);
+        assertTrue(
+            keccak256(abi.encode(extensions)) !=
+                keccak256(abi.encode(randomExtensions))
+        );
+
+        bytes32 digest = keccak256(
+            abi.encode(
+                _TYPE_HASH,
+                keccak256(bytes(name)),
+                keccak256(bytes(version)),
+                chainId,
+                verifyingContract
+            )
+        );
+        assertEq(ERC4626ExtendedDecimalsOffset0.DOMAIN_SEPARATOR(), digest);
+    }
 }
 
 contract ERC4626VaultInvariants is Test {
diff --git a/test/extensions/interfaces/IERC4626Extended.sol b/test/extensions/interfaces/IERC4626Extended.sol
index 3a380a1b..9feaa859 100644
--- a/test/extensions/interfaces/IERC4626Extended.sol
+++ b/test/extensions/interfaces/IERC4626Extended.sol
@@ -4,8 +4,9 @@ pragma solidity ^0.8.20;
 import {IERC20Metadata} from "openzeppelin/token/ERC20/extensions/IERC20Metadata.sol";
 import {IERC20Permit} from "openzeppelin/token/ERC20/extensions/IERC20Permit.sol";
 import {IERC4626} from "openzeppelin/interfaces/IERC4626.sol";
+import {IERC5267} from "openzeppelin/interfaces/IERC5267.sol";
 
-interface IERC4626Extended is IERC20Metadata, IERC20Permit, IERC4626 {
+interface IERC4626Extended is IERC20Metadata, IERC20Permit, IERC4626, IERC5267 {
     function increase_allowance(
         address spender,
         uint256 addedAmount
diff --git a/test/tokens/ERC20.t.sol b/test/tokens/ERC20.t.sol
index 1cc80d1b..e0117dd1 100644
--- a/test/tokens/ERC20.t.sol
+++ b/test/tokens/ERC20.t.sol
@@ -1036,6 +1036,36 @@ contract ERC20Test is Test {
         assertEq(ERC20Extended.DOMAIN_SEPARATOR(), digest);
     }
 
+    function testEIP712Domain() public {
+        (
+            bytes1 fields,
+            string memory name,
+            string memory version,
+            uint256 chainId,
+            address verifyingContract,
+            bytes32 salt,
+            uint256[] memory extensions
+        ) = ERC20Extended.eip712Domain();
+        assertEq(fields, hex"0f");
+        assertEq(name, _NAME_EIP712);
+        assertEq(version, _VERSION_EIP712);
+        assertEq(chainId, block.chainid);
+        assertEq(verifyingContract, ERC20ExtendedAddr);
+        assertEq(salt, bytes32(0));
+        assertEq(extensions, new uint256[](0));
+
+        bytes32 digest = keccak256(
+            abi.encode(
+                _TYPE_HASH,
+                keccak256(bytes(name)),
+                keccak256(bytes(version)),
+                chainId,
+                verifyingContract
+            )
+        );
+        assertEq(ERC20Extended.DOMAIN_SEPARATOR(), digest);
+    }
+
     function testHasOwner() public {
         assertEq(ERC20Extended.owner(), deployer);
     }
@@ -1436,6 +1466,50 @@ contract ERC20Test is Test {
         assertEq(ERC20Extended.DOMAIN_SEPARATOR(), digest);
     }
 
+    function testFuzzEIP712Domain(
+        bytes1 randomHex,
+        uint8 increment,
+        bytes32 randomSalt,
+        uint256[] calldata randomExtensions
+    ) public {
+        vm.assume(
+            randomHex != hex"0f" &&
+                randomSalt != bytes32(0) &&
+                randomExtensions.length != 0
+        );
+        vm.chainId(block.chainid + increment);
+        (
+            bytes1 fields,
+            string memory name,
+            string memory version,
+            uint256 chainId,
+            address verifyingContract,
+            bytes32 salt,
+            uint256[] memory extensions
+        ) = ERC20Extended.eip712Domain();
+        assertTrue(fields != randomHex);
+        assertEq(name, _NAME_EIP712);
+        assertEq(version, _VERSION_EIP712);
+        assertEq(chainId, block.chainid);
+        assertEq(verifyingContract, ERC20ExtendedAddr);
+        assertTrue(salt != randomSalt);
+        assertTrue(
+            keccak256(abi.encode(extensions)) !=
+                keccak256(abi.encode(randomExtensions))
+        );
+
+        bytes32 digest = keccak256(
+            abi.encode(
+                _TYPE_HASH,
+                keccak256(bytes(name)),
+                keccak256(bytes(version)),
+                chainId,
+                verifyingContract
+            )
+        );
+        assertEq(ERC20Extended.DOMAIN_SEPARATOR(), digest);
+    }
+
     function testFuzzTransferOwnershipSuccess(
         address newOwner1,
         address newOwner2
diff --git a/test/tokens/ERC721.t.sol b/test/tokens/ERC721.t.sol
index f1398bba..f7eeabc1 100644
--- a/test/tokens/ERC721.t.sol
+++ b/test/tokens/ERC721.t.sol
@@ -1877,6 +1877,36 @@ contract ERC721Test is Test {
         assertEq(ERC721Extended.DOMAIN_SEPARATOR(), digest);
     }
 
+    function testEIP712Domain() public {
+        (
+            bytes1 fields,
+            string memory name,
+            string memory version,
+            uint256 chainId,
+            address verifyingContract,
+            bytes32 salt,
+            uint256[] memory extensions
+        ) = ERC721Extended.eip712Domain();
+        assertEq(fields, hex"0f");
+        assertEq(name, _NAME_EIP712);
+        assertEq(version, _VERSION_EIP712);
+        assertEq(chainId, block.chainid);
+        assertEq(verifyingContract, ERC721ExtendedAddr);
+        assertEq(salt, bytes32(0));
+        assertEq(extensions, new uint256[](0));
+
+        bytes32 digest = keccak256(
+            abi.encode(
+                _TYPE_HASH,
+                keccak256(bytes(name)),
+                keccak256(bytes(version)),
+                chainId,
+                verifyingContract
+            )
+        );
+        assertEq(ERC721Extended.DOMAIN_SEPARATOR(), digest);
+    }
+
     function testHasOwner() public {
         assertEq(ERC721Extended.owner(), deployer);
     }
@@ -2418,7 +2448,51 @@ contract ERC721Test is Test {
                 keccak256(bytes(_NAME_EIP712)),
                 keccak256(bytes(_VERSION_EIP712)),
                 block.chainid,
-                ERC721Extended
+                ERC721ExtendedAddr
+            )
+        );
+        assertEq(ERC721Extended.DOMAIN_SEPARATOR(), digest);
+    }
+
+    function testFuzzEIP712Domain(
+        bytes1 randomHex,
+        uint8 increment,
+        bytes32 randomSalt,
+        uint256[] calldata randomExtensions
+    ) public {
+        vm.assume(
+            randomHex != hex"0f" &&
+                randomSalt != bytes32(0) &&
+                randomExtensions.length != 0
+        );
+        vm.chainId(block.chainid + increment);
+        (
+            bytes1 fields,
+            string memory name,
+            string memory version,
+            uint256 chainId,
+            address verifyingContract,
+            bytes32 salt,
+            uint256[] memory extensions
+        ) = ERC721Extended.eip712Domain();
+        assertTrue(fields != randomHex);
+        assertEq(name, _NAME_EIP712);
+        assertEq(version, _VERSION_EIP712);
+        assertEq(chainId, block.chainid);
+        assertEq(verifyingContract, ERC721ExtendedAddr);
+        assertTrue(salt != randomSalt);
+        assertTrue(
+            keccak256(abi.encode(extensions)) !=
+                keccak256(abi.encode(randomExtensions))
+        );
+
+        bytes32 digest = keccak256(
+            abi.encode(
+                _TYPE_HASH,
+                keccak256(bytes(name)),
+                keccak256(bytes(version)),
+                chainId,
+                verifyingContract
             )
         );
         assertEq(ERC721Extended.DOMAIN_SEPARATOR(), digest);
diff --git a/test/tokens/interfaces/IERC20Extended.sol b/test/tokens/interfaces/IERC20Extended.sol
index bbe862e7..d604a9f8 100644
--- a/test/tokens/interfaces/IERC20Extended.sol
+++ b/test/tokens/interfaces/IERC20Extended.sol
@@ -3,8 +3,9 @@ pragma solidity ^0.8.20;
 
 import {IERC20Metadata} from "openzeppelin/token/ERC20/extensions/IERC20Metadata.sol";
 import {IERC20Permit} from "openzeppelin/token/ERC20/extensions/IERC20Permit.sol";
+import {IERC5267} from "openzeppelin/interfaces/IERC5267.sol";
 
-interface IERC20Extended is IERC20Metadata, IERC20Permit {
+interface IERC20Extended is IERC20Metadata, IERC20Permit, IERC5267 {
     function increase_allowance(
         address spender,
         uint256 addedAmount
diff --git a/test/tokens/interfaces/IERC721Extended.sol b/test/tokens/interfaces/IERC721Extended.sol
index b80ea116..c3dd4f95 100644
--- a/test/tokens/interfaces/IERC721Extended.sol
+++ b/test/tokens/interfaces/IERC721Extended.sol
@@ -3,9 +3,15 @@ pragma solidity ^0.8.20;
 
 import {IERC721Metadata} from "openzeppelin/token/ERC721/extensions/IERC721Metadata.sol";
 import {IERC721Enumerable} from "openzeppelin/token/ERC721/extensions/IERC721Enumerable.sol";
+import {IERC5267} from "openzeppelin/interfaces/IERC5267.sol";
 import {IERC4494} from "./IERC4494.sol";
 
-interface IERC721Extended is IERC721Metadata, IERC721Enumerable, IERC4494 {
+interface IERC721Extended is
+    IERC721Metadata,
+    IERC721Enumerable,
+    IERC4494,
+    IERC5267
+{
     function burn(uint256 tokenId) external;
 
     function is_minter(address minter) external view returns (bool);
diff --git a/test/utils/EIP712DomainSeparator.t.sol b/test/utils/EIP712DomainSeparator.t.sol
index a152fcd7..39a96a77 100644
--- a/test/utils/EIP712DomainSeparator.t.sol
+++ b/test/utils/EIP712DomainSeparator.t.sol
@@ -29,6 +29,9 @@ contract EIP712DomainSeparatorTest is Test {
     // solhint-disable-next-line var-name-mixedcase
     bytes32 private _CACHED_DOMAIN_SEPARATOR;
 
+    // solhint-disable-next-line var-name-mixedcase
+    address private EIP712domainSeparatorAddr;
+
     function setUp() public {
         bytes memory args = abi.encode(_NAME, _VERSION);
         EIP712domainSeparator = IEIP712DomainSeparator(
@@ -38,13 +41,14 @@ contract EIP712DomainSeparatorTest is Test {
                 args
             )
         );
+        EIP712domainSeparatorAddr = address(EIP712domainSeparator);
         _CACHED_DOMAIN_SEPARATOR = keccak256(
             abi.encode(
                 _TYPE_HASH,
                 keccak256(bytes(_NAME)),
                 keccak256(bytes(_VERSION)),
                 block.chainid,
-                address(EIP712domainSeparator)
+                EIP712domainSeparatorAddr
             )
         );
     }
@@ -58,7 +62,7 @@ contract EIP712DomainSeparatorTest is Test {
 
     function testDomainSeparatorV4() public {
         /**
-         * @dev We change the chain id here to access the "else" branch
+         * @dev We change the chain ID here to access the "else" branch
          * in the function `domain_separator_v4`.
          */
         vm.chainId(block.chainid + 1);
@@ -68,7 +72,7 @@ contract EIP712DomainSeparatorTest is Test {
                 keccak256(bytes(_NAME)),
                 keccak256(bytes(_VERSION)),
                 block.chainid,
-                address(EIP712domainSeparator)
+                EIP712domainSeparatorAddr
             )
         );
         assertEq(EIP712domainSeparator.domain_separator_v4(), digest);
@@ -102,9 +106,39 @@ contract EIP712DomainSeparatorTest is Test {
         assertEq(digest1, digest2);
     }
 
+    function testEIP712Domain() public {
+        (
+            bytes1 fields,
+            string memory name,
+            string memory version,
+            uint256 chainId,
+            address verifyingContract,
+            bytes32 salt,
+            uint256[] memory extensions
+        ) = EIP712domainSeparator.eip712Domain();
+        assertEq(fields, hex"0f");
+        assertEq(name, _NAME);
+        assertEq(version, _VERSION);
+        assertEq(chainId, block.chainid);
+        assertEq(verifyingContract, EIP712domainSeparatorAddr);
+        assertEq(salt, bytes32(0));
+        assertEq(extensions, new uint256[](0));
+
+        bytes32 digest = keccak256(
+            abi.encode(
+                _TYPE_HASH,
+                keccak256(bytes(name)),
+                keccak256(bytes(version)),
+                chainId,
+                verifyingContract
+            )
+        );
+        assertEq(EIP712domainSeparator.domain_separator_v4(), digest);
+    }
+
     function testFuzzDomainSeparatorV4(uint8 increment) public {
         /**
-         * @dev We change the chain id here to access the "else" branch
+         * @dev We change the chain ID here to access the "else" branch
          * in the function `domain_separator_v4`.
          */
         vm.chainId(block.chainid + increment);
@@ -114,7 +148,7 @@ contract EIP712DomainSeparatorTest is Test {
                 keccak256(bytes(_NAME)),
                 keccak256(bytes(_VERSION)),
                 block.chainid,
-                address(EIP712domainSeparator)
+                EIP712domainSeparatorAddr
             )
         );
         assertEq(EIP712domainSeparator.domain_separator_v4(), digest);
@@ -149,4 +183,48 @@ contract EIP712DomainSeparatorTest is Test {
         );
         assertEq(digest1, digest2);
     }
+
+    function testFuzzEIP712Domain(
+        bytes1 randomHex,
+        uint8 increment,
+        bytes32 randomSalt,
+        uint256[] calldata randomExtensions
+    ) public {
+        vm.assume(
+            randomHex != hex"0f" &&
+                randomSalt != bytes32(0) &&
+                randomExtensions.length != 0
+        );
+        vm.chainId(block.chainid + increment);
+        (
+            bytes1 fields,
+            string memory name,
+            string memory version,
+            uint256 chainId,
+            address verifyingContract,
+            bytes32 salt,
+            uint256[] memory extensions
+        ) = EIP712domainSeparator.eip712Domain();
+        assertTrue(fields != randomHex);
+        assertEq(name, _NAME);
+        assertEq(version, _VERSION);
+        assertEq(chainId, block.chainid);
+        assertEq(verifyingContract, EIP712domainSeparatorAddr);
+        assertTrue(salt != randomSalt);
+        assertTrue(
+            keccak256(abi.encode(extensions)) !=
+                keccak256(abi.encode(randomExtensions))
+        );
+
+        bytes32 digest = keccak256(
+            abi.encode(
+                _TYPE_HASH,
+                keccak256(bytes(name)),
+                keccak256(bytes(version)),
+                chainId,
+                verifyingContract
+            )
+        );
+        assertEq(EIP712domainSeparator.domain_separator_v4(), digest);
+    }
 }
diff --git a/test/utils/interfaces/IEIP712DomainSeparator.sol b/test/utils/interfaces/IEIP712DomainSeparator.sol
index 61f21361..e0650ba4 100644
--- a/test/utils/interfaces/IEIP712DomainSeparator.sol
+++ b/test/utils/interfaces/IEIP712DomainSeparator.sol
@@ -1,7 +1,9 @@
 // SPDX-License-Identifier: WTFPL
 pragma solidity ^0.8.20;
 
-interface IEIP712DomainSeparator {
+import {IERC5267} from "openzeppelin/interfaces/IERC5267.sol";
+
+interface IEIP712DomainSeparator is IERC5267 {
     function domain_separator_v4() external view returns (bytes32);
 
     function hash_typed_data_v4(
diff --git a/test/utils/mocks/ERC20Mock.sol b/test/utils/mocks/ERC20Mock.sol
index 156592af..87fce60a 100644
--- a/test/utils/mocks/ERC20Mock.sol
+++ b/test/utils/mocks/ERC20Mock.sol
@@ -7,7 +7,7 @@ import {ERC20} from "openzeppelin/token/ERC20/ERC20.sol";
  * @title ERC20Mock
  * @author pcaversaccio
  * @notice Forked and adjusted accordingly from here:
- * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/mocks/ERC20Mock.sol.
+ * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/mocks/token/ERC20Mock.sol.
  * @dev Allows to mock a simple ERC-20 implementation.
  */
 contract ERC20Mock is ERC20 {
diff --git a/test/utils/mocks/EtherReceiver.sol b/test/utils/mocks/EtherReceiver.sol
index c3f724c8..70ee948a 100644
--- a/test/utils/mocks/EtherReceiver.sol
+++ b/test/utils/mocks/EtherReceiver.sol
@@ -5,7 +5,7 @@ pragma solidity ^0.8.20;
  * @title EtherReceiver
  * @author pcaversaccio
  * @notice Forked and adjusted accordingly from here:
- * https://github.com/mds1/multicall/blob/master/src/test/mocks/EtherSink.sol.
+ * https://github.com/mds1/multicall/blob/main/src/test/mocks/EtherSink.sol.
  * @dev Allows to test receiving ether via low-level calls.
  */
 contract EtherReceiver {
diff --git a/test/utils/mocks/MockCallee.sol b/test/utils/mocks/MockCallee.sol
index c7daffd6..cd5fddda 100644
--- a/test/utils/mocks/MockCallee.sol
+++ b/test/utils/mocks/MockCallee.sol
@@ -11,7 +11,7 @@ error Reverted(address emitter);
  * @title MockCallee
  * @author pcaversaccio
  * @notice Forked and adjusted accordingly from here:
- * https://github.com/mds1/multicall/blob/master/src/test/mocks/MockCallee.sol.
+ * https://github.com/mds1/multicall/blob/main/src/test/mocks/MockCallee.sol.
  * @dev Receives calls from the multicaller.
  */
 contract MockCallee {