UNPKG

@animoca/ethereum-contracts-sale

Version:
122 lines (97 loc) 4.3 kB
const {network, artifacts, web3} = require('hardhat'); const {BN, balance, expectRevert, expectEvent} = require('@openzeppelin/test-helpers'); const {Zero} = require('@animoca/ethereum-contracts-core').constants; const {shouldBeEqualWithETHDecimalPrecision} = require('@animoca/ethereum-contracts-core/test/utils/weiPrecision'); const IERC20 = artifacts.require('node_modules/@animoca/ethereum-contracts-assets/artifacts/contracts/token/ERC20/IERC20.sol:IERC20'); /* * behavior overrides * contract (address) - sale contract (default: this.contract) * amount (BN) - amount of purchase token to use in the purchase (default: estimatePurchase().totalPrice) * amountVariance (BN) - amount to adjust the purchase token amount by (default: 0) * totalPricePrecision (number) - the precision deviation to accept in the price paid (default: 0) * ethTokenAddress (address) - special purchase token address representing a purchase with ETH (default: this.ethTokenAddress) */ function isEthToken(token, overrides = {}) { return token === (overrides.ethTokenAddress || this.ethTokenAddress); } async function getBalance(token, account, overrides = {}) { if (isEthToken.bind(this)(token, overrides)) { return await balance.current(account); } const contract = await IERC20.at(token); return await contract.balanceOf(account); } async function doPurchaseFor(purchase, overrides = {}) { const contract = overrides.contract || this.contract; const estimatePurchase = await contract.estimatePurchase(purchase.recipient, purchase.token, purchase.sku, purchase.quantity, purchase.userData, { from: purchase.purchaser, }); const totalPrice = estimatePurchase.totalPrice; let amount = overrides.amount || totalPrice; let amountVariance = overrides.amountVariance; if (!amountVariance) { amountVariance = Zero; } amount = amount.add(amountVariance); let etherValue; if (isEthToken.bind(this)(purchase.token, overrides)) { etherValue = amount; } else { const erc20Contract = await IERC20.at(purchase.token); await erc20Contract.approve(contract.address, amount, {from: purchase.purchaser}); etherValue = Zero; } const purchaseFor = contract.purchaseFor(purchase.recipient, purchase.token, purchase.sku, purchase.quantity, purchase.userData, { from: purchase.purchaser, value: etherValue, }); return { purchaseFor, totalPrice, }; } async function shouldPurchaseFor(purchase, overrides = {}) { const balanceBefore = await getBalance.bind(this)(purchase.token, purchase.purchaser, overrides); const {purchaseFor, totalPrice} = await doPurchaseFor.bind(this)(purchase, overrides); const receipt = await purchaseFor; expectEvent(receipt, 'Purchase', { purchaser: purchase.purchaser, recipient: purchase.recipient, token: web3.utils.toChecksumAddress(purchase.token), sku: purchase.sku, quantity: purchase.quantity, userData: purchase.userData, totalPrice: totalPrice, }); if (isEthToken.bind(this)(purchase.token, overrides)) { const tx = await web3.eth.getTransaction(receipt.tx); const transferredValue = new BN(tx.value); if (overrides.amountVariance) { transferredValue.should.be.bignumber.equal(totalPrice.add(overrides.amountVariance)); } else if (overrides.totalPricePrecision) { shouldBeEqualWithETHDecimalPrecision(transferredValue, totalPrice, overrides.totalPricePrecision); } else { transferredValue.should.be.bignumber.equal(totalPrice); } } else { const balanceAfter = await getBalance.bind(this)(purchase.token, purchase.purchaser, overrides); const balanceDiff = balanceBefore.sub(balanceAfter); if (overrides.totalPricePrecision) { shouldBeEqualWithETHDecimalPrecision(balanceDiff, totalPrice, overrides.totalPricePrecision); } else { balanceDiff.should.be.bignumber.equal(totalPrice); } } } async function shouldRevertAndNotPurchaseFor(revertMessage, purchase, overrides = {}) { const {purchaseFor} = await doPurchaseFor.bind(this)(purchase, overrides); if (revertMessage) { await expectRevert(purchaseFor, revertMessage); } else { await expectRevert.unspecified(purchaseFor); } } module.exports = { shouldPurchaseFor, shouldRevertAndNotPurchaseFor, };