When to use arrays vs mappings in Solidity?
Arrays are useful when you know the size of the collection in advance, and you need to be able to iterate over the elements in a specific order. Mappings are useful when you don't know the size of the collection in advance, and you need to be able to quickly lookup values. Here are a few specific scenarios where you might choose to use one over the other: 1. Use an array when you need to store a collection of items that need to be accessed by index. 2. Use a mapping when you need to asso...
Ethereum vanity addresses
Ethereum vanity address is a one-of-a-kind customized address that has portions of it chosen rather than being created at random. Why would you create a vanity address? First of all, it looks cool. The second thing it can help you with is to reinforce your brand and make you more noticeable. How to generate your own vanity address? Creating a vanity address is a straightforward trial-and-error process. When performing high-risk cryptographic operations, such as private key creation, it is imp...
Bored Ape Yacht Club: Smart Contract Breakdown
Bored Ape Yacht Club (BAYC) is a popular NFT collection created by Yuga Labs. In this post, we’ll go over BAYC smart contract code. The source code is available on EtherScan.ERC721BAYC is implemented as an ERC721 token, a standard that defines a set of functions that a smart contract must implement in order to be considered a compliant ERC721 token. These functions include the ability to transfer tokens, approve other addresses to manage your tokens, and check token ownership.ERC721 interface...
Co-founder & CTO of Blank. Building software and helping companies enter web3.
When to use arrays vs mappings in Solidity?
Arrays are useful when you know the size of the collection in advance, and you need to be able to iterate over the elements in a specific order. Mappings are useful when you don't know the size of the collection in advance, and you need to be able to quickly lookup values. Here are a few specific scenarios where you might choose to use one over the other: 1. Use an array when you need to store a collection of items that need to be accessed by index. 2. Use a mapping when you need to asso...
Ethereum vanity addresses
Ethereum vanity address is a one-of-a-kind customized address that has portions of it chosen rather than being created at random. Why would you create a vanity address? First of all, it looks cool. The second thing it can help you with is to reinforce your brand and make you more noticeable. How to generate your own vanity address? Creating a vanity address is a straightforward trial-and-error process. When performing high-risk cryptographic operations, such as private key creation, it is imp...
Bored Ape Yacht Club: Smart Contract Breakdown
Bored Ape Yacht Club (BAYC) is a popular NFT collection created by Yuga Labs. In this post, we’ll go over BAYC smart contract code. The source code is available on EtherScan.ERC721BAYC is implemented as an ERC721 token, a standard that defines a set of functions that a smart contract must implement in order to be considered a compliant ERC721 token. These functions include the ability to transfer tokens, approve other addresses to manage your tokens, and check token ownership.ERC721 interface...
Share Dialog
Share Dialog
Co-founder & CTO of Blank. Building software and helping companies enter web3.

Subscribe to 0xMarko

Subscribe to 0xMarko
Some time ago @RareSkills_io on Twitter posted a fun gas puzzle called Mint150.
The goal of this puzzle is to mint 150 #NFTs for yourself in one transaction while staying under a certain gas limit.
Smart contract code: https://t.co/TLGP8W1LbY Test code: https://t.co/CPXHadkgNX
Rules are simple:
You may not create more accounts. You may only use the attacker account.
Since the mint has to be done in one transaction, everything should be implemented in the constructor.
You may not modify the victim contract
Let's go over the implementation👇

Line 7 initializes ERC721 which we have to exploit.
Lines 9-11 determine which token IDs will be minted. This is required since the test performs a random number of mints during setup to prevent test fitting. We can determine loop bounds after we get our initial token ID.
The goal of the loop is to mint and transfer 150 tokens. Because our account starts with a token balance of zero, minting and transferring a token immediately changes our balance from 0 to 1 and then back to 0. Because of the way the SSTORE opcode works, this uses a lot of gas. SSTORE is expensive, and the price is determined by a variety of factors.
Here is the cost breakdown:
If the value of the slot changes from 0 to any non-zero value, the cost is 20000
If the value of the slot changes from 1 to any non-zero value, the cost is 5000
If the value of the slot changes from any non-zero value to 0, the cost is 5000
In our situation, this means that each time the loop iterates, we will have to pay 25000 gas for updating our balance from 0 to 1 and then back to 0.
One clever approach we may do is to "premint" 1 #NFT before the loop, which will cause our balance to switch between 1 and 2 in the loop. Gas cost will significantly drop as a result. Premint is on line 13.
Line 15 - 22 is our loop that mints and transfers 150 tokens from the contracts to the initial caller account.
Line 24 transfers preminted NFT and that’s it.
Additionally, the reentrancy attack with the callback function onERC721Received on ERC 721 can be used to solve this challenge since Mint150 contract uses _safeMint and has no reentrancy guard.
However, the onERC721Received callback won’t be triggered if the mint function is called from the constructor, since the method which checks if the caller is a contract (EXTCODESIZE) returns 0 if it is called from the constructor of a contract.
To work around the EXTCODESIZE problem, deploy a new contract from the Attacker contract.
The biggest take from this puzzle is to understand how SSTORE opcode works and how to use it to your advantage.
Some time ago @RareSkills_io on Twitter posted a fun gas puzzle called Mint150.
The goal of this puzzle is to mint 150 #NFTs for yourself in one transaction while staying under a certain gas limit.
Smart contract code: https://t.co/TLGP8W1LbY Test code: https://t.co/CPXHadkgNX
Rules are simple:
You may not create more accounts. You may only use the attacker account.
Since the mint has to be done in one transaction, everything should be implemented in the constructor.
You may not modify the victim contract
Let's go over the implementation👇

Line 7 initializes ERC721 which we have to exploit.
Lines 9-11 determine which token IDs will be minted. This is required since the test performs a random number of mints during setup to prevent test fitting. We can determine loop bounds after we get our initial token ID.
The goal of the loop is to mint and transfer 150 tokens. Because our account starts with a token balance of zero, minting and transferring a token immediately changes our balance from 0 to 1 and then back to 0. Because of the way the SSTORE opcode works, this uses a lot of gas. SSTORE is expensive, and the price is determined by a variety of factors.
Here is the cost breakdown:
If the value of the slot changes from 0 to any non-zero value, the cost is 20000
If the value of the slot changes from 1 to any non-zero value, the cost is 5000
If the value of the slot changes from any non-zero value to 0, the cost is 5000
In our situation, this means that each time the loop iterates, we will have to pay 25000 gas for updating our balance from 0 to 1 and then back to 0.
One clever approach we may do is to "premint" 1 #NFT before the loop, which will cause our balance to switch between 1 and 2 in the loop. Gas cost will significantly drop as a result. Premint is on line 13.
Line 15 - 22 is our loop that mints and transfers 150 tokens from the contracts to the initial caller account.
Line 24 transfers preminted NFT and that’s it.
Additionally, the reentrancy attack with the callback function onERC721Received on ERC 721 can be used to solve this challenge since Mint150 contract uses _safeMint and has no reentrancy guard.
However, the onERC721Received callback won’t be triggered if the mint function is called from the constructor, since the method which checks if the caller is a contract (EXTCODESIZE) returns 0 if it is called from the constructor of a contract.
To work around the EXTCODESIZE problem, deploy a new contract from the Attacker contract.
The biggest take from this puzzle is to understand how SSTORE opcode works and how to use it to your advantage.
<100 subscribers
<100 subscribers
No activity yet