@abcoathup I seem to have the same problem. Unfortunately, the contract that sends the Ether is not under my control, and has already been deployed to the mainnet as an unupgradable contract. In this case, is there any way I can receive Ether with a proxy contract?
Minimal code to reproduce
Contracts:
pragma solidity 0.6.12;
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
interface IPayer {
function pay(uint amount) external;
}
/**
* @dev Mimic the behavior of the mainnet contract that sends Ether
*/
contract Payer is IPayer {
constructor() public { }
receive() external payable { }
function pay(uint amount) external override {
require(address(this).balance > amount, "pay: NOT_ENOUGH_ETH");
msg.sender.transfer(amount);
}
}
contract ReceiverUpgradable is Initializable {
IPayer public payer;
event Received(uint amount);
function initialize(IPayer _payer) public initializer {
payer = _payer;
}
receive() external payable {
emit Received(msg.value);
}
function demandPay(uint amount) external {
payer.pay(amount);
}
}
Test script:
describe("Upgradable Receiver", async () => {
let deployer: Signer;
let payer: Payer;
let receiver: ReceiverUpgradable;
before(async () => {
[ deployer ] = await ethers.getSigners();
const payerFactory = await ethers.getContractFactory("Payer", deployer);
payer = (await payerFactory.deploy()) as Payer;
const receiverFactory = await ethers.getContractFactory("ReceiverUpgradable", deployer);
receiver = (await upgrades.deployProxy(
receiverFactory,
[ payer.address ]
)) as ReceiverUpgradable;
await deployer.sendTransaction({
to: payer.address,
value: parseEther("1"),
});
});
it("should receive required amount of Ether from the payer", async () => {
const balanceBefore = await ethers.provider.getBalance(receiver.address);
await receiver.connect(deployer).demandPay(parseEther("0.5"));
const balanceAfter = await ethers.provider.getBalance(receiver.address);
const balanceChange = bn(balanceAfter).sub(bn(balanceBefore));
expect(balanceChange).to.equal(parseEther("0.5"));
});
});
Error message:
1) Upgradable Receiver
should receive required amount of Ether from the payer:
Error: Transaction reverted: contract call run out of gas and made the transaction revert
at <UnrecognizedContract>.<unknown> (unknown)
at Payer.pay (contracts/Payer.sol:15)
at ReceiverUpgradable.demandPay (contracts/ReceiverUpgradable.sol:21)
at <UnrecognizedContract>.<unknown> (0xa513e6e4b8f2a923d98304ec87f64353c4d5c853)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at EthModule._sendTransactionAndReturnHash (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1303:9)
at HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:102:18)
at EthersProviderWrapper.send (node_modules/@nomiclabs/hardhat-ethers/src/ethers-provider-wrapper.ts:13:20)
Thanks!