/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; library ExternalCall { // Source: https://github.com/gnosis/MultiSigWallet/blob/master/contracts/MultiSigWallet.sol // call has been separated into its own function in order to take advantage // of the Solidity's code generator to produce a loop that copies tx.data into memory. function externalCall(address destination, uint value, bytes memory data, uint dataOffset, uint dataLength, uint gasLimit) internal returns(bool result) { // solium-disable-next-line security/no-inline-assembly if (gasLimit == 0) { gasLimit = gasleft() - 40000; } assembly { let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention) let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that result := call( gasLimit, destination, value, add(d, dataOffset), dataLength, // Size of the input (in bytes) - this is what fixes the padding problem x, 0 // Output is ignored, therefore the output size is zero ) } } }