const { accounts, contract } = require('@openzeppelin/test-environment'); const { balance, ether, expectRevert, send } = require('@openzeppelin/test-helpers'); const { expect } = require('chai'); const AddressImpl = contract.fromArtifact('AddressImpl'); const EtherReceiver = contract.fromArtifact('EtherReceiverMock'); describe('Address', function () { const [ recipient, other ] = accounts; beforeEach(async function () { this.mock = await AddressImpl.new(); }); describe('isContract', function () { it('should return false for account address', async function () { expect(await this.mock.isContract(other)).to.equal(false); }); it('should return true for contract address', async function () { const contract = await AddressImpl.new(); expect(await this.mock.isContract(contract.address)).to.equal(true); }); }); describe('sendValue', function () { beforeEach(async function () { this.recipientTracker = await balance.tracker(recipient); }); context('when sender contract has no funds', function () { it('sends 0 wei', async function () { await this.mock.sendValue(other, 0); expect(await this.recipientTracker.delta()).to.be.bignumber.equal('0'); }); it('reverts when sending non-zero amounts', async function () { await expectRevert(this.mock.sendValue(other, 1), 'Address: insufficient balance'); }); }); context('when sender contract has funds', function () { const funds = ether('1'); beforeEach(async function () { await send.ether(other, this.mock.address, funds); }); it('sends 0 wei', async function () { await this.mock.sendValue(recipient, 0); expect(await this.recipientTracker.delta()).to.be.bignumber.equal('0'); }); it('sends non-zero amounts', async function () { await this.mock.sendValue(recipient, funds.subn(1)); expect(await this.recipientTracker.delta()).to.be.bignumber.equal(funds.subn(1)); }); it('sends the whole balance', async function () { await this.mock.sendValue(recipient, funds); expect(await this.recipientTracker.delta()).to.be.bignumber.equal(funds); expect(await balance.current(this.mock.address)).to.be.bignumber.equal('0'); }); it('reverts when sending more than the balance', async function () { await expectRevert(this.mock.sendValue(recipient, funds.addn(1)), 'Address: insufficient balance'); }); context('with contract recipient', function () { beforeEach(async function () { this.contractRecipient = await EtherReceiver.new(); }); it('sends funds', async function () { const tracker = await balance.tracker(this.contractRecipient.address); await this.contractRecipient.setAcceptEther(true); await this.mock.sendValue(this.contractRecipient.address, funds); expect(await tracker.delta()).to.be.bignumber.equal(funds); }); it('reverts on recipient revert', async function () { await this.contractRecipient.setAcceptEther(false); await expectRevert( this.mock.sendValue(this.contractRecipient.address, funds), 'Address: unable to send value, recipient may have reverted' ); }); }); }); }); });