From a2ae683cfe0cd2b7068646a03046d672f4e15686 Mon Sep 17 00:00:00 2001 From: Simone Date: Tue, 15 Mar 2022 14:42:49 +0100 Subject: [PATCH] Support of ERC4626, ERC2612 for slither-check-erc --- slither/core/declarations/contract.py | 24 +++++++++ slither/utils/erc.py | 78 +++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/slither/core/declarations/contract.py b/slither/core/declarations/contract.py index 2a0adbca4..ec0a20c8a 100644 --- a/slither/core/declarations/contract.py +++ b/slither/core/declarations/contract.py @@ -20,6 +20,8 @@ from slither.utils.erc import ( ERC1820_signatures, ERC777_signatures, ERC1155_signatures, + ERC2612_signatures, + ERC4626_signatures, ) from slither.utils.tests_pattern import is_test_contract @@ -900,6 +902,8 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods ("ERC223", self.is_erc223), ("ERC721", self.is_erc721), ("ERC777", self.is_erc777), + ("ERC2612", self.is_erc2612), + ("ERC4626", self.is_erc4626), ] return [erc for erc, is_erc in all_erc if is_erc()] @@ -974,6 +978,26 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods full_names = self.functions_signatures return all(s in full_names for s in ERC1155_signatures) + def is_erc4626(self) -> bool: + """ + Check if the contract is an erc4626 + + Note: it does not check for correct return values + :return: Returns a true if the contract is an erc4626 + """ + full_names = self.functions_signatures + return all(s in full_names for s in ERC4626_signatures) + + def is_erc2612(self) -> bool: + """ + Check if the contract is an erc2612 + + Note: it does not check for correct return values + :return: Returns a true if the contract is an erc2612 + """ + full_names = self.functions_signatures + return all(s in full_names for s in ERC2612_signatures) + @property def is_token(self) -> bool: """ diff --git a/slither/utils/erc.py b/slither/utils/erc.py index efb6dbf9c..af91886fd 100644 --- a/slither/utils/erc.py +++ b/slither/utils/erc.py @@ -320,6 +320,82 @@ ERC1155 = ERC1155 + ERC1155_TOKEN_RECEIVER + ERC1155_METADATA ERC1155_signatures = erc_to_signatures(ERC1155) +# Review +# https://eips.ethereum.org/EIPS/eip-2612 +# Must have ERC20 + +ERC2612_EVENTS = [] +ERC2612 = [ + ERC( + "permit", + ["address", "address", "uint256", "uint256", "uint8", "bytes32", "bytes32"], + "", + False, + True, + [], + ), + ERC("nonces", ["address"], "uint256", True, True, []), + ERC("DOMAIN_SEPARATOR", [], "bytes32", True, True, []), +] + ERC20 + +ERC2612_signatures = erc_to_signatures(ERC2612) + +# Final +# https://eips.ethereum.org/EIPS/eip-4626 +# Must have ERC20 + +ERC4626_deposit_event = ERC_EVENT( + "Deposit", + ["address", "address", "uint256", "uint256"], + [True, True, False, False], +) + +ERC4626_withdraw_event = ERC_EVENT( + "Withdraw", + ["address", "address", "address", "uint256", "uint256"], + [True, True, True, False, False], +) + +ERC4626_EVENTS = [ + ERC4626_deposit_event, + ERC4626_withdraw_event, +] + +ERC4626 = [ + ERC("asset", [], "address", True, True, []), + ERC("totalAssets", [], "uint256", True, True, []), + ERC("convertToShares", ["uint256"], "uint256", True, True, []), + ERC("convertToAssets", ["uint256"], "uint256", True, True, []), + ERC("maxDeposit", ["address"], "uint256", True, True, []), + ERC("previewDeposit", ["uint256"], "uint256", True, True, []), + ERC("deposit", ["uint256", "address"], "uint256", False, True, [ERC4626_deposit_event]), + ERC("maxMint", ["address"], "uint256", True, True, []), + ERC("previewMint", ["uint256"], "uint256", True, True, []), + ERC("mint", ["uint256", "address"], "uint256", False, True, [ERC4626_deposit_event]), + ERC("maxWithdraw", ["address"], "uint256", True, True, []), + ERC("previewWithdraw", ["uint256"], "uint256", True, True, []), + ERC( + "withdraw", + ["uint256", "address", "address"], + "uint256", + False, + True, + [ERC4626_withdraw_event], + ), + ERC("maxRedeem", ["address"], "uint256", True, True, []), + ERC("previewRedeem", ["uint256"], "uint256", True, True, []), + ERC( + "redeem", + ["uint256", "address", "address"], + "uint256", + False, + True, + [ERC4626_withdraw_event], + ), +] + ERC20 + +ERC4626_signatures = erc_to_signatures(ERC4626) + ERCS = { "ERC20": (ERC20, ERC20_EVENTS), "ERC223": (ERC223, ERC223_EVENTS), @@ -328,4 +404,6 @@ ERCS = { "ERC1820": (ERC1820, ERC1820_EVENTS), "ERC777": (ERC777, ERC777_EVENTS), "ERC1155": (ERC1155, ERC1155_EVENTS), + "ERC2612": (ERC2612, ERC2612_EVENTS), + "ERC4626": (ERC4626, ERC4626_EVENTS), }