Auditor’s Notes: Tokens, EIP-712 & Meta-Transactions

We continue our series of instructive posts with some special recommendations for developers integrating tokens & using meta-transactions!

Photo by Josué AS on Unsplash

Greetings dear readers!

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?

  • Firstly, we might construct our metaphysical defense wall in such a way that it already responds to the ongoing attack. This concept is firmly associated with Threat Modeling;

  • 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:

By the way, there are some vacant slots now so if your project needs an audit — feel free to write to us, visit our public reports page here!

I — Interactions with Tokens

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;

  • To perform an Airdrop using a Merkle tree as leaf node data, we need to take a hash not only of the user’s wallet address, but also at least the number of tokens the user is entitled to;

  • 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.

II — EIP-712 & Replay Attack

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!


Replay Attack

  • If user nonce is used, it should be included in the message being signed. Nonce also usually leads to a strict ordering of meta-transactions, this is not always necessary;

Source: Replay Attack Vulnerability in Ethereum Smart Contracts Introduced by transferProxy()

Source: Signature Replay | Hack Solidity #13

  • For complex signatures it is better to use OZ EIP-712 implementation;

  • After the hard-fork, the chain id value stored in the contract will not change, so a replay attack on the protocol in two different chains will be possible. Example.

To prevent Signature Replay attacks, consider the following recommendations from independent researcher and auditor KKat7531:

  1. Store every message hash processed by the contract, then check messages hashes against the existing ones before executing the function;

  2. Include the address of the contract in the hash to ensure that the message is only used in a single contract;

  3. Under no circumstances generate the message hash including the signature. The ‘ecrecover’ function is susceptible to signature malleability (SWC-117).

It’s best for you to investigate these tips from yet another perspective because they are exactly the same as our own checklists*

General Auditing Tips

  • Relayer may try to change some of the data. It is necessary to check that the user signs all data correctly;

  • When working with meta-transactions, it is necessary to check that each transaction is unique and cannot be repeated. For this purpose you can use hash check, nonce, etc.;

  • It is recommended to use deadline for meta-transactions. It is typically formalized in the Note section.

III — Leap Seconds & Time in Solidity

Sometimes concepts we took for granted are challenged. Did this happen to time recently?

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 days or 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!

Stay safe!

By the way, there 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:

Stay safe!

Subscribe to Officer's Blog
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
This entry has been permanently stored onchain and signed by its creator.