I am attempting to perform operations on returned data from delegatecall
opcode using a similar familiar proxy pattern:
assembly {
let ptr := mload(0x40) // load empty memory address pointer
calldatacopy(ptr, 0, calldatasize()) // copy calldata to memory
mstore(0x40, add(ptr, calldatasize())) // reset free memory pointer
let outptr := add(ptr, calldatasize()) // new free memory pointer for output location
success := delegatecall(gas(), implementation, ptr, calldatasize(), outptr, 0) // delegate call passing all calldata returning 0 on failure, 1 on success
returndatacopy(outptr, 0, returndatasize())
The resulting returned data looks something like this (including my returned revert reason):
0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f6e6f7420696d706c656d656e74656400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000....
So to help break it down, this is as far as I've understood this layout.
There is an initial 4-bytes:
0x08c379a0
Then follows a 32-byte memory slot filled with:
0x0000000000000000000000000000000000000000000000000000000000000020
which itself contains a value = 32Then follows the next 32-byte slot with the expected data; an array length:
0x000000000000000000000000000000000000000000000000000000000000000f
= 15 bytesAnd the array itself, in this case a string, in the next 32-byte slot:
0x6e6f7420696d706c656d656e7465640000000000000000000000000000000000
- "not implemented" which is my error string 15-bytes long, the rest of the slot 0s.Then follows 0's for the rest of the 100-byte-long return data.
My questions are:
- What does the leading 4-bytes
0x08c379a0
mean? There is a different leading 4-bytes it seems depending on what the returned data is. - What is the preceding padded
0x20
that appears before my error message array? - Why is the total returndata length 100-bytes that is filled with mostly 0's where my reversion messages do not fill it? If I lengthen my revert return reasons beyond the 100-bytes, the returndata also lengthens accordingly.