bytes032 Profile picture
Feb 21 25 tweets 6 min read
During my experience with DamnVulnerableDefi v3, I discovered the usage of several Solmate contracts.

Since I've compiled extensive study notes on some of these contracts, I'm sharing them to help you in your endeavors.

Today, we'll begin with Soulmate's ERC20 👇
First, if you are interested in my previously published content - you can find it easily here.

bytes032.xyz

DISCLAIMER: Everything provided in this thread is subject to my own interpretation of how things work.
Solmate's ERC20 implementation touts itself as a modern, gas-efficient ERC20 with integrated support for EIP-2612. Today, I will only touch the "stuff that caught my interest", so I don't bloat the thread.

github.com/transmissions1…
The first thing we note is that its an abstract contract. Unlike OZ's implementation, this means that it cannot be deployed on its own; it must be inherited by your own implementation.
One variable that caught my attention in Solmate's ERC20 is `decimals`, which specifies the number of decimal places the token should have. It caught my interest because it was uint8 and immutable.
Why uint8?
Using uint8 as a data type is preferable when the value stored in a variable falls between 0 and 255. This is because smaller data types are more gas efficient. Decimals have a maximum value of 18, which is well within the `uint8` range.
Why immutable?
Upon first inspection of the contract, I believed that the decimals were defined as immutable since they could be frequently accessed by token consumers. This is more cost-effective than using regular state variables as immutables are not stored in storage.
However, I had some doubts and reached out to the Secureum #solidity channel for clarification.
@patrickd_de made a valid argument regarding the decimals of a token. Changing them would be similar to having the ability to arbitrarily multiply or divide the token value by 10. This could lead to issues with other protocols that depend on a fixed decimal precision.
But .. doesn't that apply to name/symbol as well? Then, another member chimed in with an excellent point - many contracts use a constant or a hardcoded fn for name/symbol (seaport), so state var is probably used to make the implementation reusable & strings cant be immutable yet.
Before we go further, we need to clarify one thing. What does "unchecked" mean in Solidity?
The "unchecked" keyword in Solidity disables runtime checks for specific operations, which can optimize performance and reduce gas costs. However, it also introduces risks as it permits operations to be executed without proper validation.
When "unchecked" is utilized, Solidity omits various checks that are normally performed at runtime to guarantee safe and correct code execution. For instance, integer overflow and underflow checks are skipped, which can lead to faster code execution with lower gas costs.
Lets check this fn transfer(address to, uint256 amount)

You might be YELLING atm - THERE'S NO ZERO ADDRESS CHECK!!11!!!11, IT DOESNT CHECK IF THE USER HAS BALANCE AT ALL, but hold on for a second.
Now, if you try subtracting 1 from 0 in Solidity >= 8.0.0 we know what happens, right?

That's a super smart way to do two checks (underflow and zero address) at once without having to spend additional gas. Smart, right?
Remember totalSupply is uint256? This means all the user balances < totalSupply. Now that we know this, you probably understand why the snippet of code in unchecked cannot overflow.
If you looked carefully at the start of the contract there's a note: Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. Taking in account that, you might find that there's actually a possibility of overflow.
Here's why: The invariant is relying on the fact that a user only mint new tokens through the `_mint` function, but it's actually possible to update the user's balance in a contract that inherits Solmate's ERC20 and modify the balance, because balanceOf is a public variable.
The potential issue with relying on developers to not break the invariant instead of enforcing it through code is that it increases the risk of errors due to oversights, misunderstandings, or deliberate malicious intent.
By omitting over/underflow protection, gas costs can be reduced, but this can lead to unexpected and costly errors that could have been prevented.
However, the decision to rely on developers comes with potential benefits. It allows for the freedom to use cases that are not widely known or accepted yet.
Nevertheless, this approach also means that developers must exercise great care and responsibility to avoid breaking the invariant and ensure the secure and reliable execution of the contract.
function transferFrom(...)

The comment in the code snippet says that it "Saves gas for limited approvals` indicates that it saves gas by reducing the number of SSTORE operations.", but how does that happen?
By loading the value of allowed from memory, it avoids the need for a potentially expensive SSTORE operation. This reduces gas consumption and, thus the cost of executing the contract.

The rest of the function operates similarly to the `transfer` function discussed earlier.
Aaand, thats a wrap! Hopefully that helps you one way or another!

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with bytes032

bytes032 Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @bytes032

Feb 16
After dedicating a few days to studying OZ's Proxy.sol contract I've compiled my learning notes to share with you.

This comprehensive guide is designed to save you time while imparting valuable knowledge.

👇
First, if you are interested in my previously published content - you can find it easily here.

bytes032.xyz
1/ Real world use case

Imagine having an NFT builder, that simplifies NFT creation through a user-friendly interface. Although the initialization data (e.g., name, symbol, royalties) may vary, the code is mostly identical.
Read 86 tweets
Jan 30
I want to be a TOP smart contract auditor.

Solidity is a MUST HAVE, but building a strong foundation in EVM is crucial.

Starting this week, I'll be diving deep into the EVM.

Today, I'm sharing my ORDERED STEP-BY-STEP study plan. Join me, and let's tackle it together! 👇
If you are unsure how to start with Solidity, make sure to check this thread!

1/ First, I'll be watching the course from Ackee. I'm not a big fan of videos, but this one is 🔥 and very explanatory.

Read 15 tweets
Jan 29
Want to make an IMPACT as an ENTRY-LEVEL blockchain security engineer?

Take on CTFs as real engagements & complete an audit report afterward to highlight your skills & report writing abilities!

This is a surefire way to impress potential employers & build your portfolio.🧵
If you're looking for a list of CTF's, check out my compiled list.

How can I write an audit report? You can check the template created by SpearbitDAO github.com/spearbit-audit… to get your feet wet.
Read 5 tweets
Jan 27
As an auditor, it's crucial to know the ERC20 approve vulnerability.

It's a sneaky exploit that can be used to manipulate transaction ordering and double spend allowance.

In this 🧵, I'll share tips on identifying and protecting against this exploit during your audits.
1/ First, let's start with some context.
Whenever you buy tokens or transfer them to other accounts, you interact with the token contract in a predefined way.

In general, the token contract is usually written according to a certain standard.
2/ ERCs (Ethereum Request for Comment) are documents that contain standards and notes for smart contracts development.

Standards describe what should be implemented in the smart contract code and how to interact with it.
Read 32 tweets
Jan 26
Want to do smart contract audits?

You should learn Solidity first. There's no shortcut to that.

However, today I'm sharing with you MY step-by-step guide on how I PERSONALLY studied it, hopefully to help you get started and save you some time 👇
1/ Patrick Collin's course for Blockchain, Solidity, and Full Stack Web3 Development with JavaScript. This one doesn't need an explanation.
2/ cryptozombies.io
Superb resource inspired by the "learn by doing" philosophy. Their courses will take you through various scenarios to help you wet your feet with Solidity.
Read 11 tweets
Jan 24
Yesterday, I dug into USDT. Here are my learnings:

As an auditor, those4️⃣things are to keep in mind when auditing protocols interacting with USDT

☑️ Doesn't allow approving amount M>0 when N>0
☑️ Its upgradeable
☑️ Doesn't return a boolean on ERC20 methods
☑️ It has a blocklist
First, I'm sharing the contract @ Etherscan, because I will use it as a reference.
etherscan.io/address/0xdac1…
1/ It doesn't allow approving amount M > 0 when N > 0

This is to prevent front-running attacks, but if you are not wary about it, it can cause you headaches.

github.com/Uniswap/v2-per… Image
Read 12 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(