I have seen code on mitigate payload attack as such. So from this code, i can assume that an address have a payload size of 32 not 20? What about other datatype like bytes, string, uint8 etc. Where can i find the payload size of each data type?

contract NonPayloadAttackableToken {
    modifier onlyPayloadSize(uint size) { 
          assert(msg.data.length >= size + 4);
function transfer(address _to, uint256 _value) onlyPayloadSize(2 * 32) {
     // do stuff   
  • Worth noting an example of this, in Gnosis MultiSigWallet test, at github.com/gnosis/MultiSigWallet/blob/master/contracts/…. Commented Nov 16, 2018 at 12:32
  • The documentation on this example states This modifier is present in some real world token contracts, and due to a solidity bug it was not compatible with multisig wallets. Not sure what it means though... Commented Nov 16, 2018 at 12:35

1 Answer 1


The formal specification is the solidity ABI

  • All static types are padded to 32 bytes, ie uintXXX, address, bool, etc.

  • Dynamic types like string, bytes and arrays are encoded in two pieces, a "header" that has a fixed 32 bytes size and a "tail" that contains the data that has variable size.

  • Tuples and structs, see documentation. Since a tuple can has static and dynamic types it is a mix of both.

Enforcing precise data size can be problematic in general.

For example multisig wallets (ie solidity call) will add data padding, for that reason the check is with greater or equal (msg.data.length >= size + 4).

It can cause problems if you want to use a function with that modifier from another public function.

function foo(uint a, uint b) 
    bar(a, b, msg.sender);

function bar(uint a, uint b, address c)
    // If called directly it will succeed
    // If called from 'foo' it will fail. msg.data are foo parameters only

Some frameworks have removed those checks because it can cause lots of problems to try to maintain them.

  • So if my function is (bytes, string, uint) it will still be onlyPayloadSize (3*32) for the payload validation?
    – vincentsty
    Commented Nov 17, 2018 at 10:11
  • No, bytes and string are dynamic types, each will have 32 + data length.
    – Ismael
    Commented Nov 17, 2018 at 20:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.