diff options
-rw-r--r-- | packages/contracts/src/2.0.0/extensions/OrderValidator/OrderValidator.sol | 19 | ||||
-rw-r--r-- | packages/contracts/test/extensions/order_validator.ts | 50 |
2 files changed, 69 insertions, 0 deletions
diff --git a/packages/contracts/src/2.0.0/extensions/OrderValidator/OrderValidator.sol b/packages/contracts/src/2.0.0/extensions/OrderValidator/OrderValidator.sol index 8f4ce9ccc..a18345245 100644 --- a/packages/contracts/src/2.0.0/extensions/OrderValidator/OrderValidator.sol +++ b/packages/contracts/src/2.0.0/extensions/OrderValidator/OrderValidator.sol @@ -158,6 +158,25 @@ contract OrderValidator { return (balance, allowance); } + /// @dev Fetches token balances and allowances of an address for each given assetProxy. Supports ERC20 and ERC721. + /// @param target Address to fetch balances and allowances of. + /// @param assetData Array of encoded byte arrays that can be decoded by a specified proxy contract when transferring asset. + /// @return Balances and allowances of assets. + /// For ERC721 tokens, these values will always be 1 or 0. + function getBalancesAndAllowances(address target, bytes[] memory assetData) + public + view + returns (uint256[] memory, uint256[] memory) + { + uint256 length = assetData.length; + uint256[] memory balances = new uint256[](length); + uint256[] memory allowances = new uint256[](length); + for (uint256 i = 0; i != length; i++) { + (balances[i], allowances[i]) = getBalanceAndAllowance(target, assetData[i]); + } + return (balances, allowances); + } + /// @dev Calls `token.ownerOf(tokenId)`, but returns a null owner instead of reverting on an unowned token. /// @param token Address of ERC721 token. /// @param tokenId The identifier for the specific NFT. diff --git a/packages/contracts/test/extensions/order_validator.ts b/packages/contracts/test/extensions/order_validator.ts index a3b704f27..3a57cfc37 100644 --- a/packages/contracts/test/extensions/order_validator.ts +++ b/packages/contracts/test/extensions/order_validator.ts @@ -217,6 +217,56 @@ describe('OrderValidator', () => { }); }); }); + describe('getBalancesAndAllowances', () => { + it('should return the correct balances and allowances when all values are 0', async () => { + const [ + [erc20Balance, erc721Balance], + [erc20Allowance, erc721Allowance], + ] = await orderValidator.getBalancesAndAllowances.callAsync(makerAddress, [ + erc20AssetData, + erc721AssetData, + ]); + expect(erc20Balance).to.be.bignumber.equal(constants.ZERO_AMOUNT); + expect(erc721Balance).to.be.bignumber.equal(constants.ZERO_AMOUNT); + expect(erc20Allowance).to.be.bignumber.equal(constants.ZERO_AMOUNT); + expect(erc721Allowance).to.be.bignumber.equal(constants.ZERO_AMOUNT); + }); + it('should return the correct balances and allowances when balances and allowances are non-zero', async () => { + const balance = new BigNumber(123); + const allowance = new BigNumber(456); + await web3Wrapper.awaitTransactionSuccessAsync( + await erc20Token.setBalance.sendTransactionAsync(makerAddress, balance), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await erc20Token.approve.sendTransactionAsync(erc20Proxy.address, allowance, { + from: makerAddress, + }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await erc721Token.mint.sendTransactionAsync(makerAddress, tokenId), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await erc721Token.approve.sendTransactionAsync(erc721Proxy.address, tokenId, { + from: makerAddress, + }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + const [ + [erc20Balance, erc721Balance], + [erc20Allowance, erc721Allowance], + ] = await orderValidator.getBalancesAndAllowances.callAsync(makerAddress, [ + erc20AssetData, + erc721AssetData, + ]); + expect(erc20Balance).to.be.bignumber.equal(balance); + expect(erc721Balance).to.be.bignumber.equal(ERC721_BALANCE); + expect(erc20Allowance).to.be.bignumber.equal(allowance); + expect(erc721Allowance).to.be.bignumber.equal(ERC721_ALLOWANCE); + }); + }); describe('getTraderInfo', () => { beforeEach(async () => { signedOrder = await orderFactory.newSignedOrderAsync(); |