I came across different versions of delegatecall
via assembly and I tried all of them - no different result so far. How do they differ and which is the best version to use?
OpenZeppelin version:
assembly {
let ptr := mload(0x40)
calldatacopy(ptr, 0, calldatasize)
let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0)
let size := returndatasize
returndatacopy(ptr, 0, size)
switch result
case 0 { revert(ptr, size) }
default { return(ptr, size) }
}
MakerDAO version:
assembly {
let succeeded := delegatecall(sub(gas, 5000), _target, add(_calldata, 0x20), mload(_calldata), 0, 0)
let size := returndatasize
response := mload(0x40)
mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
mstore(response, size)
returndatacopy(add(response, 0x20), 0, size)
switch iszero(succeeded)
case 1 {
revert(add(response, 0x20), size)
}
}
Simple version:
assembly {
let succeeded := delegatecall(sub(gas, 5000), _target, add(_calldata, 0x20), mload(_calldata), 0, 32)
response := mload(0)
switch iszero(succeeded)
case 1 {
revert(0, 0)
}
}