I am trying to enable a gas fee refund by referring to this doc. The refund thing is working but I am not able to get the exact refund which is equal to the actual gas fee. The refund amount is either less or more. I tried doing gas profiling and tried setting different values of baseGas and gasPrice using tenderly. Will appreciate if someone could look into this and guide on how to do the gnosis safe refund properly.

1 Answer 1


I tried to figure out but there is no service which would return baseGas or recommended gasLimit for your safe transaction.

I could only find the way SafeTxGas is returned is by using below method.

/// @dev Allows to estimate a Safe transaction.
///      This method is only meant for estimation purpose, therefore the call will always revert and encode the result in the revert data.
///      Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction`
/// @param to Destination address of Safe transaction.
/// @param value Ether value of Safe transaction.
/// @param data Data payload of Safe transaction.
/// @param operation Operation type of Safe transaction.
/// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).
/// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.
function requiredTxGas(
    address to,
    uint256 value,
    bytes calldata data,
    Enum.Operation operation
) external returns (uint256) {
    uint256 startGas = gasleft();
    // We don't provide an error message here, as we use it to return the estimate
    require(execute(to, value, data, operation, gasleft()));
    uint256 requiredGas = startGas - gasleft();
    // Convert response to string and return via error message


 * @dev Performs a delegatecall on a targetContract in the context of self.
 * Internally reverts execution to avoid side effects (making it static).
 * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.
 * Specifically, the `returndata` after a call to this method will be:
 * `success:bool || response.length:uint256 || response:bytes`.
 * @param targetContract Address of the contract containing the code to execute.
 * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).
function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {
    // solhint-disable-next-line no-inline-assembly
    assembly {
        let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)

        mstore(0x00, success)
        mstore(0x20, returndatasize())
        returndatacopy(0x40, 0, returndatasize())
        revert(0, add(returndatasize(), 0x40))

regarding baseGas, waiting for the right answer from community.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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