3

I am trying to call a library function using assembly and the delegatecall opcode. The library function accepts two parameters, the state object storage pointer and an address, it returns a single uint.

I can tell if the op fails because the data at in_pos is untouched, however when it does work it always returns zero even if the function being called simply returns a 0x01 value.

state is a struct that is shared by the calling contract and the library, its position is 0

address t = 0xTargetLibraryAddress;
address a = 0xAccount;
bytes32 result;
assembly {
   let in_pos := mload(0x40)
   mstore(in_pos, 0x12345678) //a valid func sig within the library
   mstore(add(in_pos, 0x04), state)
   mstore(add(in_pos, 0x24), a)
   let success := delegatecall(sub(gas, 10000), t, in_pos, 0x44, in_pos, 0x20)
   result := mload(in_pos)
   mstore(0x40, add(in_pos, 0x44))
}

Any suggestions?

  • What is the value of success? – Tjaden Hess Mar 27 '17 at 5:43
  • success is always zero. No matter what combination I try. – slothbag Mar 27 '17 at 8:29
  • I'm facing the exact same issue, did you manage to find a solution yet? success is indeed always zero. – Nico Vergauwen Aug 31 '18 at 12:35
2

From what I can gather mstore() will write in 32 byte chunks, therefore mstore(in_pos, 0x04) is still in the same space as in_pos and will overwrite the 4 bytes function signature.

What I ended up doing is writing the 4 bytes in the first 32 bytes, the 1st arg in the 2nd 32 bytes and the 2nd arg in the 3rd 32 bytes, then called delegatecall pointing to the start of the 4 byte signature by using a 28 byte offset.

delegatecall(sub(gas, 1000), t, add(in_pos, 28), 0x44, in_pos, 0x20)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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