tests for allowance approvals on erc1155
This commit is contained in:
parent
a1c121e2fe
commit
60d24ada62
@ -38,8 +38,9 @@ describe('ERC1155Token', () => {
|
|||||||
// tokens & addresses
|
// tokens & addresses
|
||||||
let owner: string;
|
let owner: string;
|
||||||
let spender: string;
|
let spender: string;
|
||||||
|
let delegatedSpender: string;
|
||||||
let receiver: string;
|
let receiver: string;
|
||||||
let token: ERC1155MintableContract;
|
let erc1155Contract: ERC1155MintableContract;
|
||||||
let erc1155Receiver: DummyERC1155ReceiverContract;
|
let erc1155Receiver: DummyERC1155ReceiverContract;
|
||||||
let nonFungibleToken: BigNumber;
|
let nonFungibleToken: BigNumber;
|
||||||
let erc1155Wrapper: Erc1155Wrapper;
|
let erc1155Wrapper: Erc1155Wrapper;
|
||||||
@ -54,8 +55,8 @@ describe('ERC1155Token', () => {
|
|||||||
before(async () => {
|
before(async () => {
|
||||||
// deploy erc1155 contract & receiver
|
// deploy erc1155 contract & receiver
|
||||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
||||||
[owner, spender] = accounts;
|
[owner, spender, delegatedSpender] = accounts;
|
||||||
token = await ERC1155MintableContract.deployFrom0xArtifactAsync(
|
erc1155Contract = await ERC1155MintableContract.deployFrom0xArtifactAsync(
|
||||||
artifacts.ERC1155Mintable,
|
artifacts.ERC1155Mintable,
|
||||||
provider,
|
provider,
|
||||||
txDefaults,
|
txDefaults,
|
||||||
@ -67,7 +68,7 @@ describe('ERC1155Token', () => {
|
|||||||
);
|
);
|
||||||
receiver = erc1155Receiver.address;
|
receiver = erc1155Receiver.address;
|
||||||
// create wrapper & mint erc1155 tokens
|
// create wrapper & mint erc1155 tokens
|
||||||
erc1155Wrapper = new Erc1155Wrapper(token, provider, owner);
|
erc1155Wrapper = new Erc1155Wrapper(erc1155Contract, provider, owner);
|
||||||
fungibleToken = await erc1155Wrapper.mintFungibleTokenAsync(spender, spenderInitialFungibleBalance);
|
fungibleToken = await erc1155Wrapper.mintFungibleTokenAsync(spender, spenderInitialFungibleBalance);
|
||||||
[, nonFungibleToken] = await erc1155Wrapper.mintNonFungibleTokenAsync(spender);
|
[, nonFungibleToken] = await erc1155Wrapper.mintNonFungibleTokenAsync(spender);
|
||||||
});
|
});
|
||||||
@ -170,7 +171,7 @@ describe('ERC1155Token', () => {
|
|||||||
const valueToTransfer = spenderInitialFungibleBalance.plus(1);
|
const valueToTransfer = spenderInitialFungibleBalance.plus(1);
|
||||||
// execute transfer
|
// execute transfer
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
token.safeTransferFrom.sendTransactionAsync(
|
erc1155Contract.safeTransferFrom.sendTransactionAsync(
|
||||||
spender,
|
spender,
|
||||||
receiver,
|
receiver,
|
||||||
tokenToTransfer,
|
tokenToTransfer,
|
||||||
@ -193,7 +194,7 @@ describe('ERC1155Token', () => {
|
|||||||
);
|
);
|
||||||
// execute transfer
|
// execute transfer
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
token.safeTransferFrom.sendTransactionAsync(
|
erc1155Contract.safeTransferFrom.sendTransactionAsync(
|
||||||
spender,
|
spender,
|
||||||
receiver,
|
receiver,
|
||||||
tokenToTransfer,
|
tokenToTransfer,
|
||||||
@ -339,7 +340,7 @@ describe('ERC1155Token', () => {
|
|||||||
const valuesToTransfer = [spenderInitialFungibleBalance.plus(1)];
|
const valuesToTransfer = [spenderInitialFungibleBalance.plus(1)];
|
||||||
// execute transfer
|
// execute transfer
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
token.safeBatchTransferFrom.sendTransactionAsync(
|
erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
|
||||||
spender,
|
spender,
|
||||||
receiver,
|
receiver,
|
||||||
tokensToTransfer,
|
tokensToTransfer,
|
||||||
@ -362,7 +363,7 @@ describe('ERC1155Token', () => {
|
|||||||
);
|
);
|
||||||
// execute transfer
|
// execute transfer
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
token.safeBatchTransferFrom.sendTransactionAsync(
|
erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
|
||||||
spender,
|
spender,
|
||||||
receiver,
|
receiver,
|
||||||
tokensToTransfer,
|
tokensToTransfer,
|
||||||
@ -374,5 +375,113 @@ describe('ERC1155Token', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('setApprovalForAll', () => {
|
||||||
|
it('should transfer token via safeTransferFrom if called by approved account', async () => {
|
||||||
|
// set approval
|
||||||
|
const isApprovedForAll = true;
|
||||||
|
await erc1155Wrapper.setApprovalForAllAsync(spender, delegatedSpender, isApprovedForAll);
|
||||||
|
const isApprovedForAllCheck = await erc1155Wrapper.isApprovedForAllAsync(spender, delegatedSpender);
|
||||||
|
expect(isApprovedForAllCheck).to.be.true();
|
||||||
|
// setup test parameters
|
||||||
|
const tokenHolders = [spender, receiver];
|
||||||
|
const tokenToTransfer = fungibleToken;
|
||||||
|
const valueToTransfer = fungibleValueToTransfer;
|
||||||
|
// check balances before transfer
|
||||||
|
const expectedInitialBalances = [spenderInitialFungibleBalance, receiverInitialFungibleBalance];
|
||||||
|
await erc1155Wrapper.assertBalancesAsync(tokenHolders, [tokenToTransfer], expectedInitialBalances);
|
||||||
|
// execute transfer
|
||||||
|
await erc1155Wrapper.safeTransferFromAsync(
|
||||||
|
spender,
|
||||||
|
receiver,
|
||||||
|
tokenToTransfer,
|
||||||
|
valueToTransfer,
|
||||||
|
receiverCallbackData,
|
||||||
|
delegatedSpender,
|
||||||
|
);
|
||||||
|
// check balances after transfer
|
||||||
|
const expectedFinalBalances = [
|
||||||
|
spenderInitialFungibleBalance.minus(valueToTransfer),
|
||||||
|
receiverInitialFungibleBalance.plus(valueToTransfer),
|
||||||
|
];
|
||||||
|
await erc1155Wrapper.assertBalancesAsync(tokenHolders, [tokenToTransfer], expectedFinalBalances);
|
||||||
|
});
|
||||||
|
it('should throw if trying to transfer tokens via safeTransferFrom by an unapproved account', async () => {
|
||||||
|
// check approval not set
|
||||||
|
const isApprovedForAllCheck = await erc1155Wrapper.isApprovedForAllAsync(spender, delegatedSpender);
|
||||||
|
expect(isApprovedForAllCheck).to.be.false();
|
||||||
|
// setup test parameters
|
||||||
|
const tokenHolders = [spender, receiver];
|
||||||
|
const tokenToTransfer = fungibleToken;
|
||||||
|
const valueToTransfer = fungibleValueToTransfer;
|
||||||
|
// check balances before transfer
|
||||||
|
const expectedInitialBalances = [spenderInitialFungibleBalance, receiverInitialFungibleBalance];
|
||||||
|
await erc1155Wrapper.assertBalancesAsync(tokenHolders, [tokenToTransfer], expectedInitialBalances);
|
||||||
|
// execute transfer
|
||||||
|
await expectTransactionFailedAsync(
|
||||||
|
erc1155Contract.safeTransferFrom.sendTransactionAsync(
|
||||||
|
spender,
|
||||||
|
receiver,
|
||||||
|
tokenToTransfer,
|
||||||
|
valueToTransfer,
|
||||||
|
receiverCallbackData,
|
||||||
|
{ from: delegatedSpender },
|
||||||
|
),
|
||||||
|
RevertReason.InsufficientAllowance,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should transfer token via safeBatchTransferFrom if called by approved account', async () => {
|
||||||
|
// set approval
|
||||||
|
const isApprovedForAll = true;
|
||||||
|
await erc1155Wrapper.setApprovalForAllAsync(spender, delegatedSpender, isApprovedForAll);
|
||||||
|
const isApprovedForAllCheck = await erc1155Wrapper.isApprovedForAllAsync(spender, delegatedSpender);
|
||||||
|
expect(isApprovedForAllCheck).to.be.true();
|
||||||
|
// setup test parameters
|
||||||
|
const tokenHolders = [spender, receiver];
|
||||||
|
const tokensToTransfer = [fungibleToken];
|
||||||
|
const valuesToTransfer = [fungibleValueToTransfer];
|
||||||
|
// check balances before transfer
|
||||||
|
const expectedInitialBalances = [spenderInitialFungibleBalance, receiverInitialFungibleBalance];
|
||||||
|
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||||
|
// execute transfer
|
||||||
|
await erc1155Wrapper.safeBatchTransferFromAsync(
|
||||||
|
spender,
|
||||||
|
receiver,
|
||||||
|
tokensToTransfer,
|
||||||
|
valuesToTransfer,
|
||||||
|
receiverCallbackData,
|
||||||
|
delegatedSpender,
|
||||||
|
);
|
||||||
|
// check balances after transfer
|
||||||
|
const expectedFinalBalances = [
|
||||||
|
spenderInitialFungibleBalance.minus(valuesToTransfer[0]),
|
||||||
|
receiverInitialFungibleBalance.plus(valuesToTransfer[0]),
|
||||||
|
];
|
||||||
|
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||||
|
});
|
||||||
|
it('should throw if trying to transfer tokens via safeBatchTransferFrom by an unapproved account', async () => {
|
||||||
|
// check approval not set
|
||||||
|
const isApprovedForAllCheck = await erc1155Wrapper.isApprovedForAllAsync(spender, delegatedSpender);
|
||||||
|
expect(isApprovedForAllCheck).to.be.false();
|
||||||
|
// setup test parameters
|
||||||
|
const tokenHolders = [spender, receiver];
|
||||||
|
const tokensToTransfer = [fungibleToken];
|
||||||
|
const valuesToTransfer = [fungibleValueToTransfer];
|
||||||
|
// check balances before transfer
|
||||||
|
const expectedInitialBalances = [spenderInitialFungibleBalance, receiverInitialFungibleBalance];
|
||||||
|
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||||
|
// execute transfer
|
||||||
|
await expectTransactionFailedAsync(
|
||||||
|
erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
|
||||||
|
spender,
|
||||||
|
receiver,
|
||||||
|
tokensToTransfer,
|
||||||
|
valuesToTransfer,
|
||||||
|
receiverCallbackData,
|
||||||
|
{ from: delegatedSpender },
|
||||||
|
),
|
||||||
|
RevertReason.InsufficientAllowance,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
// tslint:enable:no-unnecessary-type-assertion
|
// tslint:enable:no-unnecessary-type-assertion
|
||||||
|
@ -32,10 +32,12 @@ export class Erc1155Wrapper {
|
|||||||
token: BigNumber,
|
token: BigNumber,
|
||||||
value: BigNumber,
|
value: BigNumber,
|
||||||
callbackData: string = '0x',
|
callbackData: string = '0x',
|
||||||
|
delegatedSpender: string = '',
|
||||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
|
const spender = _.isEmpty(delegatedSpender) ? from : delegatedSpender;
|
||||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
||||||
await this._erc1155Contract.safeTransferFrom.sendTransactionAsync(from, to, token, value, callbackData, {
|
await this._erc1155Contract.safeTransferFrom.sendTransactionAsync(from, to, token, value, callbackData, {
|
||||||
from,
|
from: spender,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
return tx;
|
return tx;
|
||||||
@ -46,7 +48,9 @@ export class Erc1155Wrapper {
|
|||||||
tokens: BigNumber[],
|
tokens: BigNumber[],
|
||||||
values: BigNumber[],
|
values: BigNumber[],
|
||||||
callbackData: string = '0x',
|
callbackData: string = '0x',
|
||||||
|
delegatedSpender: string = '',
|
||||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
|
const spender = _.isEmpty(delegatedSpender) ? from : delegatedSpender;
|
||||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
||||||
await this._erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
|
await this._erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
|
||||||
from,
|
from,
|
||||||
@ -54,7 +58,7 @@ export class Erc1155Wrapper {
|
|||||||
tokens,
|
tokens,
|
||||||
values,
|
values,
|
||||||
callbackData,
|
callbackData,
|
||||||
{ from },
|
{ from: spender },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return tx;
|
return tx;
|
||||||
@ -98,6 +102,22 @@ export class Erc1155Wrapper {
|
|||||||
const nftId = token.plus(1);
|
const nftId = token.plus(1);
|
||||||
return [token, nftId];
|
return [token, nftId];
|
||||||
}
|
}
|
||||||
|
public async setApprovalForAllAsync(
|
||||||
|
owner: string,
|
||||||
|
beneficiary: string,
|
||||||
|
isApproved: boolean,
|
||||||
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
|
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
||||||
|
await this._erc1155Contract.setApprovalForAll.sendTransactionAsync(beneficiary, isApproved, {
|
||||||
|
from: owner,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
return tx;
|
||||||
|
}
|
||||||
|
public async isApprovedForAllAsync(owner: string, beneficiary: string): Promise<boolean> {
|
||||||
|
const isApprovedForAll = await this._erc1155Contract.isApprovedForAll.callAsync(owner, beneficiary);
|
||||||
|
return isApprovedForAll;
|
||||||
|
}
|
||||||
public async assertBalancesAsync(
|
public async assertBalancesAsync(
|
||||||
owners: string[],
|
owners: string[],
|
||||||
tokens: BigNumber[],
|
tokens: BigNumber[],
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"changes": [
|
"changes": [
|
||||||
{
|
{
|
||||||
"note": "Added `Uint256Underflow` and `TransferRejected` revert reasons",
|
"note": "Added `Uint256Underflow`, `TransferRejected`, and `InsufficientAllowance` revert reasons",
|
||||||
"pr": 1657
|
"pr": 1657
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -261,6 +261,7 @@ export enum RevertReason {
|
|||||||
TxNotFullyConfirmed = 'TX_NOT_FULLY_CONFIRMED',
|
TxNotFullyConfirmed = 'TX_NOT_FULLY_CONFIRMED',
|
||||||
TimeLockIncomplete = 'TIME_LOCK_INCOMPLETE',
|
TimeLockIncomplete = 'TIME_LOCK_INCOMPLETE',
|
||||||
TransferRejected = 'TRANSFER_REJECTED',
|
TransferRejected = 'TRANSFER_REJECTED',
|
||||||
|
InsufficientAllowance = 'INSUFFICIENT_ALLOWANCE',
|
||||||
// DutchAuction
|
// DutchAuction
|
||||||
AuctionInvalidAmount = 'INVALID_AMOUNT',
|
AuctionInvalidAmount = 'INVALID_AMOUNT',
|
||||||
AuctionExpired = 'AUCTION_EXPIRED',
|
AuctionExpired = 'AUCTION_EXPIRED',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user