When writing assembly to which memory address should I start writing

assemblyevmsolidity

when should you start writing to memory address mstore(0x40, x) and when to mstore(0x80, x)?

Some contracts that I've seen, for example this one https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol

They use the 0x40 memory address, but others use the 0x80.

What is the difference, and which one should I use?

Thanks a lot hope the question is clear.

Best Answer

If you are asking the question, you probably should write at the address returned by mload(0x40), you can read more about the solidity memory layout in the documentation.

This is what the code that you linked is doing :

// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)

// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)

Writing directly to 0x80 or any other fixed address is a possible optimization (because don't pay additional gas for an mload(0x40) instruction) if you either :

  • Know that this is the current value at memory[0x40] (0x80 is the initial value stored at 0x40)
  • Don't care about overwriting allocating memory / respecting solidity memory model. (proxy do this for instance by writing an arbitrary amount of data starting at address 0x00)

In any case, if you intend to return / use the any allocated memory space, make sure to mark that memory as allocated by incrementing the free memory pointer :

// Allocate 32 bytes of memory by :
// taking the value of the free memory pointer : mload(0x40)
// incrementing it by 0x20 (32) : add(mload(0x40), 0x20)
// writing the resulting value to 0x40 : mstore(0x40, ...)
mstore(0x40, add(mload(0x40), 0x20))

I hope this answers your question.

Related Topic