Fails to send funds from one contract to another

Question asked by tsudmi on GitHub: https://github.com/OpenZeppelin/openzeppelin-sdk/issues/1444

I get a Error: Error: Returned error: VM Exception while processing transaction: revert when calling transfer from one contract to another.

:1234: Code to reproduce

Here is a reproducible example:

ContractA.sol:

pragma solidity 0.6.2;

import "@openzeppelin/upgrades/contracts/Initializable.sol";

contract ContractA is Initializable {
    address private admin;

    function initialize(address _admin) public initializer {
        admin = _admin;
    }

    receive() external payable { }
}

ContractB.sol:

pragma solidity 0.6.2;

import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "./ContractA.sol";

contract ContractB is Initializable {
    ContractA private contractA;

    function initialize(ContractA _contractA) public initializer {
        contractA = _contractA;
    }

    function withdraw() external payable {
        payable(address(contractA)).transfer(msg.value);
    }
}

It will revert on withdraw function call of ContractB.

:computer: Environment
ganache-cli: 6.9.0
openzeppelin/cli: 2.7.0
openzeppelin/upgrades: 2.7.0

This is due to EIP1884 change in gas cost for SLOAD in the Istanbul hard fork. For details see: OpenZeppelin upgradeable contracts affected by Istanbul hardfork

The solutions to how we can deal with this are detailed in the following post: