slither.utils.standard_libraries

  1from pathlib import Path
  2from typing import Optional, TYPE_CHECKING
  3from hashlib import sha1
  4from slither.utils.oz_hashes import oz_hashes
  5
  6if TYPE_CHECKING:
  7    from slither.core.declarations import Contract
  8
  9libraries = {
 10    "Openzeppelin-SafeMath": lambda x: is_openzeppelin_safemath(x),
 11    "Openzeppelin-ECRecovery": lambda x: is_openzeppelin_ecrecovery(x),
 12    "Openzeppelin-Ownable": lambda x: is_openzeppelin_ownable(x),
 13    "Openzeppelin-ERC20": lambda x: is_openzeppelin_erc20(x),
 14    "Openzeppelin-ERC721": lambda x: is_openzeppelin_erc721(x),
 15    "Zos-Upgrade": lambda x: is_zos_initializable(x),
 16    "Dapphub-DSAuth": lambda x: is_dapphub_ds_auth(x),
 17    "Dapphub-DSMath": lambda x: is_dapphub_ds_math(x),
 18    "Dapphub-DSToken": lambda x: is_dapphub_ds_token(x),
 19    "Dapphub-DSProxy": lambda x: is_dapphub_ds_proxy(x),
 20    "Dapphub-DSGroup": lambda x: is_dapphub_ds_group(x),
 21    "AragonOS-SafeMath": lambda x: is_aragonos_safemath(x),
 22    "AragonOS-ERC20": lambda x: is_aragonos_erc20(x),
 23    "AragonOS-AppProxyBase": lambda x: is_aragonos_app_proxy_base(x),
 24    "AragonOS-AppProxyPinned": lambda x: is_aragonos_app_proxy_pinned(x),
 25    "AragonOS-AppProxyUpgradeable": lambda x: is_aragonos_app_proxy_upgradeable(x),
 26    "AragonOS-AppStorage": lambda x: is_aragonos_app_storage(x),
 27    "AragonOS-AragonApp": lambda x: is_aragonos_aragon_app(x),
 28    "AragonOS-UnsafeAragonApp": lambda x: is_aragonos_unsafe_aragon_app(x),
 29    "AragonOS-Autopetrified": lambda x: is_aragonos_autopetrified(x),
 30    "AragonOS-DelegateProxy": lambda x: is_aragonos_delegate_proxy(x),
 31    "AragonOS-DepositableDelegateProxy": lambda x: is_aragonos_depositable_delegate_proxy(x),
 32    "AragonOS-DepositableStorage": lambda x: is_aragonos_delegate_proxy(x),
 33    "AragonOS-Initializable": lambda x: is_aragonos_initializable(x),
 34    "AragonOS-IsContract": lambda x: is_aragonos_is_contract(x),
 35    "AragonOS-Petrifiable": lambda x: is_aragonos_petrifiable(x),
 36    "AragonOS-ReentrancyGuard": lambda x: is_aragonos_reentrancy_guard(x),
 37    "AragonOS-TimeHelpers": lambda x: is_aragonos_time_helpers(x),
 38    "AragonOS-VaultRecoverable": lambda x: is_aragonos_vault_recoverable(x),
 39}
 40
 41
 42def is_standard_library(contract: "Contract") -> Optional[str]:
 43    for name, is_lib in libraries.items():
 44        if is_lib(contract):
 45            return name
 46    return None
 47
 48
 49###################################################################################
 50###################################################################################
 51# region General libraries
 52###################################################################################
 53###################################################################################
 54
 55
 56def is_openzeppelin(contract: "Contract") -> bool:
 57    if not contract.is_from_dependency():
 58        return False
 59    path = Path(contract.source_mapping.filename.absolute).parts
 60    is_zep = "openzeppelin-solidity" in Path(contract.source_mapping.filename.absolute).parts
 61    try:
 62        is_zep |= path[path.index("@openzeppelin") + 1] == "contracts"
 63    except IndexError:
 64        pass
 65    except ValueError:
 66        pass
 67    return is_zep
 68
 69
 70def is_openzeppelin_strict(contract: "Contract") -> bool:
 71    source_hash = sha1(contract.source_mapping.content.encode("utf-8")).hexdigest()
 72    return source_hash in oz_hashes
 73
 74
 75def is_zos(contract: "Contract") -> bool:
 76    if not contract.is_from_dependency():
 77        return False
 78    return "zos-lib" in Path(contract.source_mapping.filename.absolute).parts
 79
 80
 81def is_aragonos(contract: "Contract") -> bool:
 82    if not contract.is_from_dependency():
 83        return False
 84    return "@aragon/os" in Path(contract.source_mapping.filename.absolute).parts
 85
 86
 87# endregion
 88###################################################################################
 89###################################################################################
 90# region SafeMath
 91###################################################################################
 92###################################################################################
 93
 94
 95def is_safemath(contract: "Contract") -> bool:
 96    return contract.name == "SafeMath"
 97
 98
 99def is_openzeppelin_safemath(contract: "Contract") -> bool:
100    return is_safemath(contract) and is_openzeppelin(contract)
101
102
103def is_aragonos_safemath(contract: "Contract") -> bool:
104    return is_safemath(contract) and is_aragonos(contract)
105
106
107# endregion
108###################################################################################
109###################################################################################
110# region ECRecovery
111###################################################################################
112###################################################################################
113
114
115def is_ecrecovery(contract: "Contract") -> bool:
116    return contract.name == "ECRecovery"
117
118
119def is_openzeppelin_ecrecovery(contract: "Contract") -> bool:
120    return is_ecrecovery(contract) and is_openzeppelin(contract)
121
122
123# endregion
124###################################################################################
125###################################################################################
126# region Ownable
127###################################################################################
128###################################################################################
129
130
131def is_ownable(contract: "Contract") -> bool:
132    return contract.name == "Ownable"
133
134
135def is_openzeppelin_ownable(contract: "Contract") -> bool:
136    return is_ownable(contract) and is_openzeppelin(contract)
137
138
139# endregion
140###################################################################################
141###################################################################################
142# region ERC20
143###################################################################################
144###################################################################################
145
146
147def is_erc20(contract: "Contract") -> bool:
148    return contract.name == "ERC20"
149
150
151def is_openzeppelin_erc20(contract: "Contract") -> bool:
152    return is_erc20(contract) and is_openzeppelin(contract)
153
154
155def is_aragonos_erc20(contract: "Contract") -> bool:
156    return is_erc20(contract) and is_aragonos(contract)
157
158
159# endregion
160###################################################################################
161###################################################################################
162# region ERC721
163###################################################################################
164###################################################################################
165
166
167def is_erc721(contract: "Contract") -> bool:
168    return contract.name == "ERC721"
169
170
171def is_openzeppelin_erc721(contract: "Contract") -> bool:
172    return is_erc721(contract) and is_openzeppelin(contract)
173
174
175# endregion
176###################################################################################
177###################################################################################
178# region Zos Initializable
179###################################################################################
180###################################################################################
181
182
183def is_initializable(contract: "Contract") -> bool:
184    return contract.name == "Initializable"
185
186
187def is_zos_initializable(contract: "Contract") -> bool:
188    return is_initializable(contract) and is_zos(contract)
189
190
191# endregion
192###################################################################################
193###################################################################################
194# region DappHub
195###################################################################################
196###################################################################################
197
198dapphubs = {
199    "DSAuth": "ds-auth",
200    "DSMath": "ds-math",
201    "DSToken": "ds-token",
202    "DSProxy": "ds-proxy",
203    "DSGroup": "ds-group",
204}
205
206
207def _is_ds(contract: "Contract", name: str) -> bool:
208    return contract.name == name
209
210
211def _is_dappdhub_ds(contract: "Contract", name: str) -> bool:
212    if not contract.is_from_dependency():
213        return False
214    if not dapphubs[name] in Path(contract.source_mapping.filename.absolute).parts:
215        return False
216    return _is_ds(contract, name)
217
218
219def is_ds_auth(contract: "Contract") -> bool:
220    return _is_ds(contract, "DSAuth")
221
222
223def is_dapphub_ds_auth(contract: "Contract") -> bool:
224    return _is_dappdhub_ds(contract, "DSAuth")
225
226
227def is_ds_math(contract: "Contract") -> bool:
228    return _is_ds(contract, "DSMath")
229
230
231def is_dapphub_ds_math(contract: "Contract") -> bool:
232    return _is_dappdhub_ds(contract, "DSMath")
233
234
235def is_ds_token(contract: "Contract") -> bool:
236    return _is_ds(contract, "DSToken")
237
238
239def is_dapphub_ds_token(contract: "Contract") -> bool:
240    return _is_dappdhub_ds(contract, "DSToken")
241
242
243def is_ds_proxy(contract: "Contract") -> bool:
244    return _is_ds(contract, "DSProxy")
245
246
247def is_dapphub_ds_proxy(contract: "Contract") -> bool:
248    return _is_dappdhub_ds(contract, "DSProxy")
249
250
251def is_ds_group(contract: "Contract") -> bool:
252    return _is_ds(contract, "DSGroup")
253
254
255def is_dapphub_ds_group(contract: "Contract") -> bool:
256    return _is_dappdhub_ds(contract, "DSGroup")
257
258
259# endregion
260###################################################################################
261###################################################################################
262# region Aragon
263###################################################################################
264###################################################################################
265
266
267def is_aragonos_app_proxy_base(contract: "Contract") -> bool:
268    return contract.name == "AppProxyBase" and is_aragonos(contract)
269
270
271def is_aragonos_app_proxy_pinned(contract: "Contract") -> bool:
272    return contract.name == "AppProxyPinned" and is_aragonos(contract)
273
274
275def is_aragonos_app_proxy_upgradeable(contract: "Contract") -> bool:
276    return contract.name == "AppProxyUpgradeable" and is_aragonos(contract)
277
278
279def is_aragonos_app_storage(contract: "Contract") -> bool:
280    return contract.name == "AppStorage" and is_aragonos(contract)
281
282
283def is_aragonos_aragon_app(contract: "Contract") -> bool:
284    return contract.name == "AragonApp" and is_aragonos(contract)
285
286
287def is_aragonos_unsafe_aragon_app(contract: "Contract") -> bool:
288    return contract.name == "UnsafeAragonApp" and is_aragonos(contract)
289
290
291def is_aragonos_autopetrified(contract: "Contract") -> bool:
292    return contract.name == "Autopetrified" and is_aragonos(contract)
293
294
295def is_aragonos_delegate_proxy(contract: "Contract") -> bool:
296    return contract.name == "DelegateProxy" and is_aragonos(contract)
297
298
299def is_aragonos_depositable_delegate_proxy(contract: "Contract") -> bool:
300    return contract.name == "DepositableDelegateProxy" and is_aragonos(contract)
301
302
303def is_aragonos_depositable_storage(contract: "Contract") -> bool:
304    return contract.name == "DepositableStorage" and is_aragonos(contract)
305
306
307def is_aragonos_ether_token_contract(contract: "Contract") -> bool:
308    return contract.name == "EtherTokenConstant" and is_aragonos(contract)
309
310
311def is_aragonos_initializable(contract: "Contract") -> bool:
312    return contract.name == "Initializable" and is_aragonos(contract)
313
314
315def is_aragonos_is_contract(contract: "Contract") -> bool:
316    return contract.name == "IsContract" and is_aragonos(contract)
317
318
319def is_aragonos_petrifiable(contract: "Contract") -> bool:
320    return contract.name == "Petrifiable" and is_aragonos(contract)
321
322
323def is_aragonos_reentrancy_guard(contract: "Contract") -> bool:
324    return contract.name == "ReentrancyGuard" and is_aragonos(contract)
325
326
327def is_aragonos_time_helpers(contract: "Contract") -> bool:
328    return contract.name == "TimeHelpers" and is_aragonos(contract)
329
330
331def is_aragonos_vault_recoverable(contract: "Contract") -> bool:
332    return contract.name == "VaultRecoverable" and is_aragonos(contract)
libraries = {'Openzeppelin-SafeMath': <function <lambda>>, 'Openzeppelin-ECRecovery': <function <lambda>>, 'Openzeppelin-Ownable': <function <lambda>>, 'Openzeppelin-ERC20': <function <lambda>>, 'Openzeppelin-ERC721': <function <lambda>>, 'Zos-Upgrade': <function <lambda>>, 'Dapphub-DSAuth': <function <lambda>>, 'Dapphub-DSMath': <function <lambda>>, 'Dapphub-DSToken': <function <lambda>>, 'Dapphub-DSProxy': <function <lambda>>, 'Dapphub-DSGroup': <function <lambda>>, 'AragonOS-SafeMath': <function <lambda>>, 'AragonOS-ERC20': <function <lambda>>, 'AragonOS-AppProxyBase': <function <lambda>>, 'AragonOS-AppProxyPinned': <function <lambda>>, 'AragonOS-AppProxyUpgradeable': <function <lambda>>, 'AragonOS-AppStorage': <function <lambda>>, 'AragonOS-AragonApp': <function <lambda>>, 'AragonOS-UnsafeAragonApp': <function <lambda>>, 'AragonOS-Autopetrified': <function <lambda>>, 'AragonOS-DelegateProxy': <function <lambda>>, 'AragonOS-DepositableDelegateProxy': <function <lambda>>, 'AragonOS-DepositableStorage': <function <lambda>>, 'AragonOS-Initializable': <function <lambda>>, 'AragonOS-IsContract': <function <lambda>>, 'AragonOS-Petrifiable': <function <lambda>>, 'AragonOS-ReentrancyGuard': <function <lambda>>, 'AragonOS-TimeHelpers': <function <lambda>>, 'AragonOS-VaultRecoverable': <function <lambda>>}
def is_standard_library( contract: slither.core.declarations.contract.Contract) -> Union[str, NoneType]:
43def is_standard_library(contract: "Contract") -> Optional[str]:
44    for name, is_lib in libraries.items():
45        if is_lib(contract):
46            return name
47    return None
def is_openzeppelin(contract: slither.core.declarations.contract.Contract) -> bool:
57def is_openzeppelin(contract: "Contract") -> bool:
58    if not contract.is_from_dependency():
59        return False
60    path = Path(contract.source_mapping.filename.absolute).parts
61    is_zep = "openzeppelin-solidity" in Path(contract.source_mapping.filename.absolute).parts
62    try:
63        is_zep |= path[path.index("@openzeppelin") + 1] == "contracts"
64    except IndexError:
65        pass
66    except ValueError:
67        pass
68    return is_zep
def is_openzeppelin_strict(contract: slither.core.declarations.contract.Contract) -> bool:
71def is_openzeppelin_strict(contract: "Contract") -> bool:
72    source_hash = sha1(contract.source_mapping.content.encode("utf-8")).hexdigest()
73    return source_hash in oz_hashes
def is_zos(contract: slither.core.declarations.contract.Contract) -> bool:
76def is_zos(contract: "Contract") -> bool:
77    if not contract.is_from_dependency():
78        return False
79    return "zos-lib" in Path(contract.source_mapping.filename.absolute).parts
def is_aragonos(contract: slither.core.declarations.contract.Contract) -> bool:
82def is_aragonos(contract: "Contract") -> bool:
83    if not contract.is_from_dependency():
84        return False
85    return "@aragon/os" in Path(contract.source_mapping.filename.absolute).parts
def is_safemath(contract: slither.core.declarations.contract.Contract) -> bool:
96def is_safemath(contract: "Contract") -> bool:
97    return contract.name == "SafeMath"
def is_openzeppelin_safemath(contract: slither.core.declarations.contract.Contract) -> bool:
100def is_openzeppelin_safemath(contract: "Contract") -> bool:
101    return is_safemath(contract) and is_openzeppelin(contract)
def is_aragonos_safemath(contract: slither.core.declarations.contract.Contract) -> bool:
104def is_aragonos_safemath(contract: "Contract") -> bool:
105    return is_safemath(contract) and is_aragonos(contract)
def is_ecrecovery(contract: slither.core.declarations.contract.Contract) -> bool:
116def is_ecrecovery(contract: "Contract") -> bool:
117    return contract.name == "ECRecovery"
def is_openzeppelin_ecrecovery(contract: slither.core.declarations.contract.Contract) -> bool:
120def is_openzeppelin_ecrecovery(contract: "Contract") -> bool:
121    return is_ecrecovery(contract) and is_openzeppelin(contract)
def is_ownable(contract: slither.core.declarations.contract.Contract) -> bool:
132def is_ownable(contract: "Contract") -> bool:
133    return contract.name == "Ownable"
def is_openzeppelin_ownable(contract: slither.core.declarations.contract.Contract) -> bool:
136def is_openzeppelin_ownable(contract: "Contract") -> bool:
137    return is_ownable(contract) and is_openzeppelin(contract)
def is_erc20(contract: slither.core.declarations.contract.Contract) -> bool:
148def is_erc20(contract: "Contract") -> bool:
149    return contract.name == "ERC20"
def is_openzeppelin_erc20(contract: slither.core.declarations.contract.Contract) -> bool:
152def is_openzeppelin_erc20(contract: "Contract") -> bool:
153    return is_erc20(contract) and is_openzeppelin(contract)
def is_aragonos_erc20(contract: slither.core.declarations.contract.Contract) -> bool:
156def is_aragonos_erc20(contract: "Contract") -> bool:
157    return is_erc20(contract) and is_aragonos(contract)
def is_erc721(contract: slither.core.declarations.contract.Contract) -> bool:
168def is_erc721(contract: "Contract") -> bool:
169    return contract.name == "ERC721"
def is_openzeppelin_erc721(contract: slither.core.declarations.contract.Contract) -> bool:
172def is_openzeppelin_erc721(contract: "Contract") -> bool:
173    return is_erc721(contract) and is_openzeppelin(contract)
def is_initializable(contract: slither.core.declarations.contract.Contract) -> bool:
184def is_initializable(contract: "Contract") -> bool:
185    return contract.name == "Initializable"
def is_zos_initializable(contract: slither.core.declarations.contract.Contract) -> bool:
188def is_zos_initializable(contract: "Contract") -> bool:
189    return is_initializable(contract) and is_zos(contract)
dapphubs = {'DSAuth': 'ds-auth', 'DSMath': 'ds-math', 'DSToken': 'ds-token', 'DSProxy': 'ds-proxy', 'DSGroup': 'ds-group'}
def is_ds_auth(contract: slither.core.declarations.contract.Contract) -> bool:
220def is_ds_auth(contract: "Contract") -> bool:
221    return _is_ds(contract, "DSAuth")
def is_dapphub_ds_auth(contract: slither.core.declarations.contract.Contract) -> bool:
224def is_dapphub_ds_auth(contract: "Contract") -> bool:
225    return _is_dappdhub_ds(contract, "DSAuth")
def is_ds_math(contract: slither.core.declarations.contract.Contract) -> bool:
228def is_ds_math(contract: "Contract") -> bool:
229    return _is_ds(contract, "DSMath")
def is_dapphub_ds_math(contract: slither.core.declarations.contract.Contract) -> bool:
232def is_dapphub_ds_math(contract: "Contract") -> bool:
233    return _is_dappdhub_ds(contract, "DSMath")
def is_ds_token(contract: slither.core.declarations.contract.Contract) -> bool:
236def is_ds_token(contract: "Contract") -> bool:
237    return _is_ds(contract, "DSToken")
def is_dapphub_ds_token(contract: slither.core.declarations.contract.Contract) -> bool:
240def is_dapphub_ds_token(contract: "Contract") -> bool:
241    return _is_dappdhub_ds(contract, "DSToken")
def is_ds_proxy(contract: slither.core.declarations.contract.Contract) -> bool:
244def is_ds_proxy(contract: "Contract") -> bool:
245    return _is_ds(contract, "DSProxy")
def is_dapphub_ds_proxy(contract: slither.core.declarations.contract.Contract) -> bool:
248def is_dapphub_ds_proxy(contract: "Contract") -> bool:
249    return _is_dappdhub_ds(contract, "DSProxy")
def is_ds_group(contract: slither.core.declarations.contract.Contract) -> bool:
252def is_ds_group(contract: "Contract") -> bool:
253    return _is_ds(contract, "DSGroup")
def is_dapphub_ds_group(contract: slither.core.declarations.contract.Contract) -> bool:
256def is_dapphub_ds_group(contract: "Contract") -> bool:
257    return _is_dappdhub_ds(contract, "DSGroup")
def is_aragonos_app_proxy_base(contract: slither.core.declarations.contract.Contract) -> bool:
268def is_aragonos_app_proxy_base(contract: "Contract") -> bool:
269    return contract.name == "AppProxyBase" and is_aragonos(contract)
def is_aragonos_app_proxy_pinned(contract: slither.core.declarations.contract.Contract) -> bool:
272def is_aragonos_app_proxy_pinned(contract: "Contract") -> bool:
273    return contract.name == "AppProxyPinned" and is_aragonos(contract)
def is_aragonos_app_proxy_upgradeable(contract: slither.core.declarations.contract.Contract) -> bool:
276def is_aragonos_app_proxy_upgradeable(contract: "Contract") -> bool:
277    return contract.name == "AppProxyUpgradeable" and is_aragonos(contract)
def is_aragonos_app_storage(contract: slither.core.declarations.contract.Contract) -> bool:
280def is_aragonos_app_storage(contract: "Contract") -> bool:
281    return contract.name == "AppStorage" and is_aragonos(contract)
def is_aragonos_aragon_app(contract: slither.core.declarations.contract.Contract) -> bool:
284def is_aragonos_aragon_app(contract: "Contract") -> bool:
285    return contract.name == "AragonApp" and is_aragonos(contract)
def is_aragonos_unsafe_aragon_app(contract: slither.core.declarations.contract.Contract) -> bool:
288def is_aragonos_unsafe_aragon_app(contract: "Contract") -> bool:
289    return contract.name == "UnsafeAragonApp" and is_aragonos(contract)
def is_aragonos_autopetrified(contract: slither.core.declarations.contract.Contract) -> bool:
292def is_aragonos_autopetrified(contract: "Contract") -> bool:
293    return contract.name == "Autopetrified" and is_aragonos(contract)
def is_aragonos_delegate_proxy(contract: slither.core.declarations.contract.Contract) -> bool:
296def is_aragonos_delegate_proxy(contract: "Contract") -> bool:
297    return contract.name == "DelegateProxy" and is_aragonos(contract)
def is_aragonos_depositable_delegate_proxy(contract: slither.core.declarations.contract.Contract) -> bool:
300def is_aragonos_depositable_delegate_proxy(contract: "Contract") -> bool:
301    return contract.name == "DepositableDelegateProxy" and is_aragonos(contract)
def is_aragonos_depositable_storage(contract: slither.core.declarations.contract.Contract) -> bool:
304def is_aragonos_depositable_storage(contract: "Contract") -> bool:
305    return contract.name == "DepositableStorage" and is_aragonos(contract)
def is_aragonos_ether_token_contract(contract: slither.core.declarations.contract.Contract) -> bool:
308def is_aragonos_ether_token_contract(contract: "Contract") -> bool:
309    return contract.name == "EtherTokenConstant" and is_aragonos(contract)
def is_aragonos_initializable(contract: slither.core.declarations.contract.Contract) -> bool:
312def is_aragonos_initializable(contract: "Contract") -> bool:
313    return contract.name == "Initializable" and is_aragonos(contract)
def is_aragonos_is_contract(contract: slither.core.declarations.contract.Contract) -> bool:
316def is_aragonos_is_contract(contract: "Contract") -> bool:
317    return contract.name == "IsContract" and is_aragonos(contract)
def is_aragonos_petrifiable(contract: slither.core.declarations.contract.Contract) -> bool:
320def is_aragonos_petrifiable(contract: "Contract") -> bool:
321    return contract.name == "Petrifiable" and is_aragonos(contract)
def is_aragonos_reentrancy_guard(contract: slither.core.declarations.contract.Contract) -> bool:
324def is_aragonos_reentrancy_guard(contract: "Contract") -> bool:
325    return contract.name == "ReentrancyGuard" and is_aragonos(contract)
def is_aragonos_time_helpers(contract: slither.core.declarations.contract.Contract) -> bool:
328def is_aragonos_time_helpers(contract: "Contract") -> bool:
329    return contract.name == "TimeHelpers" and is_aragonos(contract)
def is_aragonos_vault_recoverable(contract: slither.core.declarations.contract.Contract) -> bool:
332def is_aragonos_vault_recoverable(contract: "Contract") -> bool:
333    return contract.name == "VaultRecoverable" and is_aragonos(contract)