We continue our series of instructive posts with some special recommendations for developers integrating tokens & using meta-transactions!
Looking at this month’s never-ending hacks, one wonders why they happen so frequently. Have audit firms actually gotten worse at what they do? This, in my opinion, is not the case; yet, the topic is rather tricky because you can, in certain ways, reduce the risks to yourself and your project!
When confronted with such an issue, the only thing left to do is address it logically — in other words, how can we affect this unfavorable situation?
Secondly, we can strive to construct a line of defense that will function even before the possible events, that is, create the code first and conduct all activities appropriately and safely. This is what we’ll cover in this post!
Additionally, keep in mind that Solidity is a high-level programming language! While Solidity offers powerful functionalities, it also brings a unique set of risks and challenges. So, by reviewing the code, auditors can suggest optimizations and improvements that can reduce the gas usage and make the contract more cost-effective. Efficient code not only saves costs for users but also contributes to the overall sustainability and scalability of the project.
By investing time and resources into a thorough assessment, developers can identify and rectify potential issues, thereby minimizing the chance of financial loss, reputation damage, or legal non-compliance. Auditing not only protects the project and its users but also contributes to the overall growth and adoption of the Web3 ecosystem.
Since 2016, our team has accumulated a considerable number of observations, which we will provide here, along with numerous security advice. We can confidently say that such tips can be read publicly in a few places, and our blog is one of those places. The following will be our observations — only dry facts for auditors, tricks and the best life-hacks shared by our best auditors, but first, be sure to check out:
Going back to our primary topic, this article will be focused only on those aspects that can be really useful for auditing and bug bounty hacking and that are not described anywhere. We can confidently say that such tips can be read publicly in a few places, and our blog is one of those places. We also hope you find today’s article informative and helpful!
We finished our own research a few months ago; please read it if you haven’t already:
Following the tips below can significantly improve the security of your integration:
You must remember that there are double-entry tokens (the proxy contract redirects calls to the token contract). Interaction with a single state can occur through two addresses. [Article link]. [Example of a vulnerable contract]. Examples of such tokens: SNX, sBTC;
When transferring tokens that allow the use of callback functions, it should be taken into account that the value of these tokens or their derivatives (such as LP-tokens) may change during callback calls. Examples: Tokens supporting the ERC-677 and ERC-777 standards, or tokens paired with ETH (when ETH is used for token exchange, and when ETH is transferred, a fallback function with malicious code can be executed);
When minting NFT tokens, selling them or airdropping, it is necessary to set a limit on the maximum number of tokens that can be minted by a user at one time. Otherwise, the first user will become the owner of all tokens;
If the source code of a token contains a fallback()-function without revert, it will be possible for the token to call any function for which there is no implementation in the contract code. Examples of such tokens are WETH, PERI, OMT, WBNB, MATIC, AVAX, etc.;
Using permit() in the contract code is not safe for users who have given unlimited approve() to the address of this contract for some tokens (WETH, PERI, OMT, WBNB, MATIC, AVAX, etc.), since the contract code of these tokens contains a fallback()-function without revert and permit() will always execute;
Corrections should be updated in the functions mint, burn, transfer;
Charging of commissions should be done only once and automatically, when performing an action for which a commission is paid.
Since 2016, our team has accumulated a considerable number of observations, which we will provide here, along with numerous security advice. The techniques listed below can help you considerably increase the security of your project’s integration!
`uint256` not `uint` (same for `int`).
Store every message hash processed by the contract, then check messages hashes against the existing ones before executing the function;
Include the address of the contract in the hash to ensure that the message is only used in a single contract;
It’s best for you to investigate these tips from yet another perspective because they are exactly the same as our own checklists*
Relayer may try to change some of the data. It is necessary to check that the user signs all data correctly;
Dealing with dates and time is always tricky, and in Solidity there is no difference. Although there are some keywords that help us like
now and units like
hours there are a few things we have to keep in mind. You should also keep in mind that the EVM counts time in seconds. Everything is a Unix timestamp!
In general, there are two options to include a time factor into a Solidity contract: relating to the current block number or relating to the current timestamp. There are also two interesting points, much thanks Roman Sivakov & Banteg for spotting and bringing them up in a dev-chat:
First, did you know that the future behavior of the Earth’s rotation is unknown, so the UT1-UTC difference is unpredictable and can only be derived from observations?
Second, with very small changes in the angular velocity of the Earth’s rotation, leap seconds can run up quite quickly, because a small change in angular velocity is multiplied by time, i.e., there is a cumulative effect. In Paris, by the way, there is a separate department that keeps an eye on the leap seconds issue!
Therefore, we strongly encourage you to explore all of the resources in this article and read more about the issue of time and its manipulation in smart contracts. We promise to cover this topic in more detail in future articles, stay tuned!
We at pessimistic sincerely hope you find our work useful and appreciate any feedback, so please do not hesitate to contact us! The best answers and questions may be included in the next blog post. We hope that this article was informative and useful for you!
By the way, several audits have been completed successfully! By the way, here are some vacant slots now so if your project needs an audit — feel free to write to us, visit our public reports page here!
Support is very important to me, with it I can do what I love — educating users!
If you want to support my work, you can send me a donation to the address:
4AhpUrDtfVSWZMJcRMJkZoPwDSdVG6puYBE3ajQABQo6T533cVvx5vJRc5fX7sktJe67mXu1CcDmr7orn1CrGrqsT3ptfds — Monero XMR