Merge tag 'v2.1.1' of github.com:OpenZeppelin/openzeppelin-solidity
v2.1.1
This commit is contained in:
@ -1,41 +1,39 @@
|
||||
const { ethGetBalance, ethSendTransaction } = require('../helpers/web3');
|
||||
const { ethGetBalance } = require('../helpers/web3');
|
||||
const expectEvent = require('../helpers/expectEvent');
|
||||
const send = require('./../helpers/send');
|
||||
const { ether } = require('../helpers/ether');
|
||||
const { ZERO_ADDRESS } = require('./../helpers/constants');
|
||||
|
||||
const BigNumber = web3.BigNumber;
|
||||
require('../helpers/setup');
|
||||
|
||||
require('chai')
|
||||
.use(require('chai-bignumber')(BigNumber))
|
||||
.should();
|
||||
const shouldFail = require('../helpers/shouldFail');
|
||||
const PaymentSplitter = artifacts.require('PaymentSplitterMock');
|
||||
|
||||
const { expectThrow } = require('../helpers/expectThrow');
|
||||
const { EVMRevert } = require('../helpers/EVMRevert.js');
|
||||
const SplitPayment = artifacts.require('SplitPaymentMock');
|
||||
|
||||
contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1, payer1]) {
|
||||
const amount = web3.toWei(1.0, 'ether');
|
||||
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
contract('PaymentSplitter', function ([_, owner, payee1, payee2, payee3, nonpayee1, payer1]) {
|
||||
const amount = ether(1.0);
|
||||
|
||||
it('rejects an empty set of payees', async function () {
|
||||
await expectThrow(SplitPayment.new([], []), EVMRevert);
|
||||
await shouldFail.reverting(PaymentSplitter.new([], []));
|
||||
});
|
||||
|
||||
it('rejects more payees than shares', async function () {
|
||||
await expectThrow(SplitPayment.new([payee1, payee2, payee3], [20, 30]), EVMRevert);
|
||||
await shouldFail.reverting(PaymentSplitter.new([payee1, payee2, payee3], [20, 30]));
|
||||
});
|
||||
|
||||
it('rejects more shares than payees', async function () {
|
||||
await expectThrow(SplitPayment.new([payee1, payee2], [20, 30, 40]), EVMRevert);
|
||||
await shouldFail.reverting(PaymentSplitter.new([payee1, payee2], [20, 30, 40]));
|
||||
});
|
||||
|
||||
it('rejects null payees', async function () {
|
||||
await expectThrow(SplitPayment.new([payee1, ZERO_ADDRESS], [20, 30]), EVMRevert);
|
||||
await shouldFail.reverting(PaymentSplitter.new([payee1, ZERO_ADDRESS], [20, 30]));
|
||||
});
|
||||
|
||||
it('rejects zero-valued shares', async function () {
|
||||
await expectThrow(SplitPayment.new([payee1, payee2], [20, 0]), EVMRevert);
|
||||
await shouldFail.reverting(PaymentSplitter.new([payee1, payee2], [20, 0]));
|
||||
});
|
||||
|
||||
it('rejects repeated payees', async function () {
|
||||
await expectThrow(SplitPayment.new([payee1, payee1], [20, 30]), EVMRevert);
|
||||
await shouldFail.reverting(PaymentSplitter.new([payee1, payee1], [20, 30]));
|
||||
});
|
||||
|
||||
context('once deployed', function () {
|
||||
@ -43,7 +41,7 @@ contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1,
|
||||
this.payees = [payee1, payee2, payee3];
|
||||
this.shares = [20, 10, 70];
|
||||
|
||||
this.contract = await SplitPayment.new(this.payees, this.shares);
|
||||
this.contract = await PaymentSplitter.new(this.payees, this.shares);
|
||||
});
|
||||
|
||||
it('should have total shares', async function () {
|
||||
@ -58,7 +56,7 @@ contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1,
|
||||
});
|
||||
|
||||
it('should accept payments', async function () {
|
||||
await ethSendTransaction({ from: owner, to: this.contract.address, value: amount });
|
||||
await send.ether(owner, this.contract.address, amount);
|
||||
|
||||
(await ethGetBalance(this.contract.address)).should.be.bignumber.equal(amount);
|
||||
});
|
||||
@ -72,16 +70,16 @@ contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1,
|
||||
});
|
||||
|
||||
it('should throw if no funds to claim', async function () {
|
||||
await expectThrow(this.contract.release(payee1), EVMRevert);
|
||||
await shouldFail.reverting(this.contract.release(payee1));
|
||||
});
|
||||
|
||||
it('should throw if non-payee want to claim', async function () {
|
||||
await ethSendTransaction({ from: payer1, to: this.contract.address, value: amount });
|
||||
await expectThrow(this.contract.release(nonpayee1), EVMRevert);
|
||||
await send.ether(payer1, this.contract.address, amount);
|
||||
await shouldFail.reverting(this.contract.release(nonpayee1));
|
||||
});
|
||||
|
||||
it('should distribute funds to payees', async function () {
|
||||
await ethSendTransaction({ from: payer1, to: this.contract.address, value: amount });
|
||||
await send.ether(payer1, this.contract.address, amount);
|
||||
|
||||
// receive funds
|
||||
const initBalance = await ethGetBalance(this.contract.address);
|
||||
@ -89,19 +87,22 @@ contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1,
|
||||
|
||||
// distribute to payees
|
||||
const initAmount1 = await ethGetBalance(payee1);
|
||||
await this.contract.release(payee1);
|
||||
const { logs: logs1 } = await this.contract.release(payee1);
|
||||
const profit1 = (await ethGetBalance(payee1)).sub(initAmount1);
|
||||
profit1.sub(web3.toWei(0.20, 'ether')).abs().should.be.bignumber.lt(1e16);
|
||||
expectEvent.inLogs(logs1, 'PaymentReleased', { to: payee1, amount: profit1 });
|
||||
|
||||
const initAmount2 = await ethGetBalance(payee2);
|
||||
await this.contract.release(payee2);
|
||||
const { logs: logs2 } = await this.contract.release(payee2);
|
||||
const profit2 = (await ethGetBalance(payee2)).sub(initAmount2);
|
||||
profit2.sub(web3.toWei(0.10, 'ether')).abs().should.be.bignumber.lt(1e16);
|
||||
expectEvent.inLogs(logs2, 'PaymentReleased', { to: payee2, amount: profit2 });
|
||||
|
||||
const initAmount3 = await ethGetBalance(payee3);
|
||||
await this.contract.release(payee3);
|
||||
const { logs: logs3 } = await this.contract.release(payee3);
|
||||
const profit3 = (await ethGetBalance(payee3)).sub(initAmount3);
|
||||
profit3.sub(web3.toWei(0.70, 'ether')).abs().should.be.bignumber.lt(1e16);
|
||||
expectEvent.inLogs(logs3, 'PaymentReleased', { to: payee3, amount: profit3 });
|
||||
|
||||
// end balance should be zero
|
||||
(await ethGetBalance(this.contract.address)).should.be.bignumber.equal(0);
|
||||
@ -1,15 +1,12 @@
|
||||
const { ethGetBalance } = require('../helpers/web3');
|
||||
const { balanceDifference } = require('../helpers/balanceDifference');
|
||||
const { ether } = require('../helpers/ether');
|
||||
|
||||
const BigNumber = web3.BigNumber;
|
||||
|
||||
require('chai')
|
||||
.use(require('chai-bignumber')(BigNumber))
|
||||
.should();
|
||||
require('../helpers/setup');
|
||||
|
||||
const PullPaymentMock = artifacts.require('PullPaymentMock');
|
||||
|
||||
contract('PullPayment', function ([_, payer, payee1, payee2]) {
|
||||
const amount = web3.toWei(17.0, 'ether');
|
||||
const amount = ether(17.0);
|
||||
|
||||
beforeEach(async function () {
|
||||
this.contract = await PullPaymentMock.new({ value: amount });
|
||||
@ -36,16 +33,13 @@ contract('PullPayment', function ([_, payer, payee1, payee2]) {
|
||||
});
|
||||
|
||||
it('can withdraw payment', async function () {
|
||||
const initialBalance = await ethGetBalance(payee1);
|
||||
(await balanceDifference(payee1, async () => {
|
||||
await this.contract.callTransfer(payee1, amount, { from: payer });
|
||||
(await this.contract.payments(payee1)).should.be.bignumber.equal(amount);
|
||||
|
||||
await this.contract.callTransfer(payee1, amount, { from: payer });
|
||||
await this.contract.withdrawPayments(payee1);
|
||||
})).should.be.bignumber.equal(amount);
|
||||
|
||||
(await this.contract.payments(payee1)).should.be.bignumber.equal(amount);
|
||||
|
||||
await this.contract.withdrawPayments(payee1);
|
||||
(await this.contract.payments(payee1)).should.be.bignumber.equal(0);
|
||||
|
||||
const balance = await ethGetBalance(payee1);
|
||||
Math.abs(balance - initialBalance - amount).should.be.lt(1e16);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
const { shouldBehaveLikeEscrow } = require('./Escrow.behavior');
|
||||
const { expectThrow } = require('../helpers/expectThrow');
|
||||
const { EVMRevert } = require('../helpers/EVMRevert');
|
||||
|
||||
const BigNumber = web3.BigNumber;
|
||||
const shouldFail = require('../../helpers/shouldFail');
|
||||
const { ether } = require('../../helpers/ether');
|
||||
|
||||
require('chai')
|
||||
.use(require('chai-bignumber')(BigNumber))
|
||||
.should();
|
||||
require('../../helpers/setup');
|
||||
|
||||
const ConditionalEscrowMock = artifacts.require('ConditionalEscrowMock');
|
||||
|
||||
@ -24,7 +21,7 @@ contract('ConditionalEscrow', function ([_, owner, payee, ...otherAccounts]) {
|
||||
});
|
||||
|
||||
context('when withdrawal is disallowed', function () {
|
||||
const amount = web3.toWei(23.0, 'ether');
|
||||
const amount = ether(23.0);
|
||||
|
||||
beforeEach(async function () {
|
||||
await this.escrow.setAllowed(payee, false);
|
||||
@ -33,7 +30,7 @@ contract('ConditionalEscrow', function ([_, owner, payee, ...otherAccounts]) {
|
||||
it('reverts on withdrawals', async function () {
|
||||
await this.escrow.deposit(payee, { from: owner, value: amount });
|
||||
|
||||
await expectThrow(this.escrow.withdraw(payee, { from: owner }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.withdraw(payee, { from: owner }));
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,16 +1,13 @@
|
||||
const expectEvent = require('../helpers/expectEvent');
|
||||
const { expectThrow } = require('../helpers/expectThrow');
|
||||
const { EVMRevert } = require('../helpers/EVMRevert');
|
||||
const { ethGetBalance } = require('../helpers/web3');
|
||||
const expectEvent = require('../../helpers/expectEvent');
|
||||
const shouldFail = require('../../helpers/shouldFail');
|
||||
const { ethGetBalance } = require('../../helpers/web3');
|
||||
const { balanceDifference } = require('../../helpers/balanceDifference');
|
||||
const { ether } = require('../../helpers/ether');
|
||||
|
||||
const BigNumber = web3.BigNumber;
|
||||
|
||||
require('chai')
|
||||
.use(require('chai-bignumber')(BigNumber))
|
||||
.should();
|
||||
require('../../helpers/setup');
|
||||
|
||||
function shouldBehaveLikeEscrow (primary, [payee1, payee2]) {
|
||||
const amount = web3.toWei(42.0, 'ether');
|
||||
const amount = ether(42.0);
|
||||
|
||||
describe('as an escrow', function () {
|
||||
describe('deposits', function () {
|
||||
@ -27,14 +24,15 @@ function shouldBehaveLikeEscrow (primary, [payee1, payee2]) {
|
||||
});
|
||||
|
||||
it('only the primary account can deposit', async function () {
|
||||
await expectThrow(this.escrow.deposit(payee1, { from: payee2 }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.deposit(payee1, { from: payee2 }));
|
||||
});
|
||||
|
||||
it('emits a deposited event', async function () {
|
||||
const receipt = await this.escrow.deposit(payee1, { from: primary, value: amount });
|
||||
|
||||
const event = expectEvent.inLogs(receipt.logs, 'Deposited', { payee: payee1 });
|
||||
event.args.weiAmount.should.be.bignumber.equal(amount);
|
||||
const { logs } = await this.escrow.deposit(payee1, { from: primary, value: amount });
|
||||
expectEvent.inLogs(logs, 'Deposited', {
|
||||
payee: payee1,
|
||||
weiAmount: amount,
|
||||
});
|
||||
});
|
||||
|
||||
it('can add multiple deposits on a single account', async function () {
|
||||
@ -60,17 +58,13 @@ function shouldBehaveLikeEscrow (primary, [payee1, payee2]) {
|
||||
|
||||
describe('withdrawals', async function () {
|
||||
it('can withdraw payments', async function () {
|
||||
const payeeInitialBalance = await ethGetBalance(payee1);
|
||||
|
||||
await this.escrow.deposit(payee1, { from: primary, value: amount });
|
||||
await this.escrow.withdraw(payee1, { from: primary });
|
||||
(await balanceDifference(payee1, async () => {
|
||||
await this.escrow.deposit(payee1, { from: primary, value: amount });
|
||||
await this.escrow.withdraw(payee1, { from: primary });
|
||||
})).should.be.bignumber.equal(amount);
|
||||
|
||||
(await ethGetBalance(this.escrow.address)).should.be.bignumber.equal(0);
|
||||
|
||||
(await this.escrow.depositsOf(payee1)).should.be.bignumber.equal(0);
|
||||
|
||||
const payeeFinalBalance = await ethGetBalance(payee1);
|
||||
payeeFinalBalance.sub(payeeInitialBalance).should.be.bignumber.equal(amount);
|
||||
});
|
||||
|
||||
it('can do an empty withdrawal', async function () {
|
||||
@ -78,15 +72,16 @@ function shouldBehaveLikeEscrow (primary, [payee1, payee2]) {
|
||||
});
|
||||
|
||||
it('only the primary account can withdraw', async function () {
|
||||
await expectThrow(this.escrow.withdraw(payee1, { from: payee1 }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.withdraw(payee1, { from: payee1 }));
|
||||
});
|
||||
|
||||
it('emits a withdrawn event', async function () {
|
||||
await this.escrow.deposit(payee1, { from: primary, value: amount });
|
||||
const receipt = await this.escrow.withdraw(payee1, { from: primary });
|
||||
|
||||
const event = expectEvent.inLogs(receipt.logs, 'Withdrawn', { payee: payee1 });
|
||||
event.args.weiAmount.should.be.bignumber.equal(amount);
|
||||
const { logs } = await this.escrow.withdraw(payee1, { from: primary });
|
||||
expectEvent.inLogs(logs, 'Withdrawn', {
|
||||
payee: payee1,
|
||||
weiAmount: amount,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,23 +1,19 @@
|
||||
const { expectThrow } = require('../helpers/expectThrow');
|
||||
const { EVMRevert } = require('../helpers/EVMRevert');
|
||||
const expectEvent = require('../helpers/expectEvent');
|
||||
const { ethGetBalance } = require('../helpers/web3');
|
||||
const shouldFail = require('../../helpers/shouldFail');
|
||||
const expectEvent = require('../../helpers/expectEvent');
|
||||
const { balanceDifference } = require('../../helpers/balanceDifference');
|
||||
const { ether } = require('../../helpers/ether');
|
||||
const { ZERO_ADDRESS } = require('../../helpers/constants');
|
||||
|
||||
const BigNumber = web3.BigNumber;
|
||||
|
||||
require('chai')
|
||||
.use(require('chai-bignumber')(BigNumber))
|
||||
.should();
|
||||
require('../../helpers/setup');
|
||||
|
||||
const RefundEscrow = artifacts.require('RefundEscrowMock');
|
||||
|
||||
contract('RefundEscrow', function ([_, primary, beneficiary, refundee1, refundee2]) {
|
||||
const amount = web3.toWei(54.0, 'ether');
|
||||
const amount = ether(54.0);
|
||||
const refundees = [refundee1, refundee2];
|
||||
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
|
||||
it('requires a non-null beneficiary', async function () {
|
||||
await expectThrow(
|
||||
await shouldFail.reverting(
|
||||
RefundEscrow.new(ZERO_ADDRESS, { from: primary })
|
||||
);
|
||||
});
|
||||
@ -41,21 +37,20 @@ contract('RefundEscrow', function ([_, primary, beneficiary, refundee1, refundee
|
||||
|
||||
it('does not refund refundees', async function () {
|
||||
await this.escrow.deposit(refundee1, { from: primary, value: amount });
|
||||
await expectThrow(this.escrow.withdraw(refundee1), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.withdraw(refundee1));
|
||||
});
|
||||
|
||||
it('does not allow beneficiary withdrawal', async function () {
|
||||
await this.escrow.deposit(refundee1, { from: primary, value: amount });
|
||||
await expectThrow(this.escrow.beneficiaryWithdraw(), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.beneficiaryWithdraw());
|
||||
});
|
||||
});
|
||||
|
||||
it('only the primary account can enter closed state', async function () {
|
||||
await expectThrow(this.escrow.close({ from: beneficiary }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.close({ from: beneficiary }));
|
||||
|
||||
const receipt = await this.escrow.close({ from: primary });
|
||||
|
||||
expectEvent.inLogs(receipt.logs, 'Closed');
|
||||
const { logs } = await this.escrow.close({ from: primary });
|
||||
expectEvent.inLogs(logs, 'RefundsClosed');
|
||||
});
|
||||
|
||||
context('closed state', function () {
|
||||
@ -66,36 +61,33 @@ contract('RefundEscrow', function ([_, primary, beneficiary, refundee1, refundee
|
||||
});
|
||||
|
||||
it('rejects deposits', async function () {
|
||||
await expectThrow(this.escrow.deposit(refundee1, { from: primary, value: amount }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.deposit(refundee1, { from: primary, value: amount }));
|
||||
});
|
||||
|
||||
it('does not refund refundees', async function () {
|
||||
await expectThrow(this.escrow.withdraw(refundee1), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.withdraw(refundee1));
|
||||
});
|
||||
|
||||
it('allows beneficiary withdrawal', async function () {
|
||||
const beneficiaryInitialBalance = await ethGetBalance(beneficiary);
|
||||
await this.escrow.beneficiaryWithdraw();
|
||||
const beneficiaryFinalBalance = await ethGetBalance(beneficiary);
|
||||
|
||||
beneficiaryFinalBalance.sub(beneficiaryInitialBalance).should.be.bignumber.equal(amount * refundees.length);
|
||||
(await balanceDifference(beneficiary, () =>
|
||||
this.escrow.beneficiaryWithdraw()
|
||||
)).should.be.bignumber.equal(amount * refundees.length);
|
||||
});
|
||||
|
||||
it('prevents entering the refund state', async function () {
|
||||
await expectThrow(this.escrow.enableRefunds({ from: primary }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.enableRefunds({ from: primary }));
|
||||
});
|
||||
|
||||
it('prevents re-entering the closed state', async function () {
|
||||
await expectThrow(this.escrow.close({ from: primary }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.close({ from: primary }));
|
||||
});
|
||||
});
|
||||
|
||||
it('only the primary account can enter refund state', async function () {
|
||||
await expectThrow(this.escrow.enableRefunds({ from: beneficiary }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.enableRefunds({ from: beneficiary }));
|
||||
|
||||
const receipt = await this.escrow.enableRefunds({ from: primary });
|
||||
|
||||
expectEvent.inLogs(receipt.logs, 'RefundsEnabled');
|
||||
const { logs } = await this.escrow.enableRefunds({ from: primary });
|
||||
expectEvent.inLogs(logs, 'RefundsEnabled');
|
||||
});
|
||||
|
||||
context('refund state', function () {
|
||||
@ -106,29 +98,27 @@ contract('RefundEscrow', function ([_, primary, beneficiary, refundee1, refundee
|
||||
});
|
||||
|
||||
it('rejects deposits', async function () {
|
||||
await expectThrow(this.escrow.deposit(refundee1, { from: primary, value: amount }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.deposit(refundee1, { from: primary, value: amount }));
|
||||
});
|
||||
|
||||
it('refunds refundees', async function () {
|
||||
for (const refundee of [refundee1, refundee2]) {
|
||||
const refundeeInitialBalance = await ethGetBalance(refundee);
|
||||
await this.escrow.withdraw(refundee, { from: primary });
|
||||
const refundeeFinalBalance = await ethGetBalance(refundee);
|
||||
|
||||
refundeeFinalBalance.sub(refundeeInitialBalance).should.be.bignumber.equal(amount);
|
||||
(await balanceDifference(refundee, () =>
|
||||
this.escrow.withdraw(refundee, { from: primary }))
|
||||
).should.be.bignumber.equal(amount);
|
||||
}
|
||||
});
|
||||
|
||||
it('does not allow beneficiary withdrawal', async function () {
|
||||
await expectThrow(this.escrow.beneficiaryWithdraw(), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.beneficiaryWithdraw());
|
||||
});
|
||||
|
||||
it('prevents entering the closed state', async function () {
|
||||
await expectThrow(this.escrow.close({ from: primary }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.close({ from: primary }));
|
||||
});
|
||||
|
||||
it('prevents re-entering the refund state', async function () {
|
||||
await expectThrow(this.escrow.enableRefunds({ from: primary }), EVMRevert);
|
||||
await shouldFail.reverting(this.escrow.enableRefunds({ from: primary }));
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user