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?

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

1 Answer 1

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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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