├── migrations
└── .none
├── .soliumignore
├── .gitattributes
├── .gitignore
├── .solcover.js
├── typings
├── mocha.d.ts
├── truffle.d.ts
├── contracts
│ ├── index.d.ts
│ ├── LibEIP712.d.ts
│ ├── IERC165.d.ts
│ ├── IERC1271Wallet.d.ts
│ ├── SignatureValidator.d.ts
│ ├── ERC1155Metadata.d.ts
│ ├── ERC1271WalletMock.d.ts
│ ├── Ownable.d.ts
│ ├── OwnableMock.d.ts
│ ├── ERC1155MetadataMock.d.ts
│ ├── IERC1155TokenReceiver.d.ts
│ ├── IERC20.d.ts
│ ├── IERC1155Meta.d.ts
│ ├── ERC20.d.ts
│ ├── ERC1155ReceiverMock.d.ts
│ ├── IERC1155.d.ts
│ ├── ERC1155.d.ts
│ ├── ERC1155MintBurn.d.ts
│ ├── ERC20Mock.d.ts
│ ├── ERC1155PackedBalance.d.ts
│ ├── ERC1155MintBurnPackedBalance.d.ts
│ ├── ERC1155OperatorMock.d.ts
│ ├── ERC1155Meta.d.ts
│ ├── ERC1155MetaPackedBalance.d.ts
│ └── ERC1155MetaMintBurnMock.d.ts
└── txTypes.d.ts
├── contracts
├── mocks
│ ├── OwnableMock.sol
│ ├── ERC1155MetadataMock.sol
│ ├── ERC1271WalletMock.sol
│ ├── ERC1155MetaMintBurnMock.sol
│ ├── ERC1155MetaMintBurnPackedBalanceMock.sol
│ ├── ERC1155OperatorMock.sol
│ ├── ERC1155ReceiverMock.sol
│ └── ERC20Mock.sol
├── interfaces
│ ├── IERC165.sol
│ ├── IERC20.sol
│ ├── IERC1271Wallet.sol
│ ├── IERC1155TokenReceiver.sol
│ ├── IERC1155Meta.sol
│ └── IERC1155.sol
├── utils
│ ├── Ownable.sol
│ ├── Address.sol
│ ├── SafeMath.sol
│ ├── LibEIP712.sol
│ ├── LibBytes.sol
│ └── SignatureValidator.sol
└── tokens
│ ├── ERC1155
│ ├── ERC1155Metadata.sol
│ ├── ERC1155MintBurn.sol
│ └── ERC1155.sol
│ └── ERC1155PackedBalance
│ └── ERC1155MintBurnPackedBalance.sol
├── src
└── tests
│ ├── utils
│ ├── index.ts
│ └── contract.ts
│ ├── Ownable.spec.ts
│ ├── SignatureValidator.spec.ts
│ └── ERC1155Metadata.spec.ts
├── .soliumrc.json
├── tsconfig.json
├── truffle.js
├── LICENSE
├── tslint.json
└── package.json
/migrations/.none:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.soliumignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.sol linguist-language=Solidity
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | node_modules/
4 |
5 | *.js.map
6 | build/
7 |
8 | .DS_Store
9 | .vscode
10 | .idea/
11 | *.iml
12 |
13 | npm-debug.log*
14 | yarn-debug.log*
15 | yarn-error.log*
16 | lerna-debug.log*
17 |
--------------------------------------------------------------------------------
/.solcover.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | port: '8545',
3 | norpc: true,
4 | testCommand: 'truffle test --network coverage',
5 | skipFiles: [
6 | 'ERC1155MockNoBalancePacking.sol',
7 | 'ERC1155Mock.sol',
8 | 'ERC1155MockX.sol',
9 | 'ERC1155OperatorMock.sol',
10 | 'ERC1155ReceiverMock.sol',
11 | 'ERC20Mock.sol',
12 | 'ERC721Mock.sol'
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/typings/mocha.d.ts:
--------------------------------------------------------------------------------
1 | export {};
2 |
3 | // Adding if method for mocha's describe method
4 | /* https://github.com/mochajs/mocha/issues/591#issuecomment-443841252 */
5 | ///
6 | declare module "mocha" {
7 | interface SuiteFunction {
8 | if: (condition: boolean, message: string, func: (this: Mocha.Suite) => void) => void;
9 | }
10 | }
--------------------------------------------------------------------------------
/typings/truffle.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'truffle' {
2 | import * as truffle from 'truffle-contract'
3 |
4 | interface ArtifactsGlobal {
5 | require(name: string): truffle.TruffleContract
6 | }
7 |
8 | global {
9 | function contract(
10 | name: string,
11 | callback: (accounts: Array) => void
12 | ): void;
13 | const artifacts: ArtifactsGlobal
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/contracts/mocks/OwnableMock.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | import "../utils/Ownable.sol";
4 |
5 |
6 | /**
7 | * @dev Contract that is ownable
8 | */
9 | contract OwnableMock is Ownable {
10 | uint256 internal mockStateOwner = 0;
11 | uint256 internal mockStateNonOwner = 0;
12 |
13 | function ownerCall() external onlyOwner() {
14 | mockStateOwner += 1;
15 | }
16 |
17 | function nonOwnerCall() external {
18 | mockStateNonOwner += 1;
19 | }
20 | }
--------------------------------------------------------------------------------
/contracts/interfaces/IERC165.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 |
4 | /**
5 | * @title ERC165
6 | * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
7 | */
8 | interface IERC165 {
9 |
10 | /**
11 | * @notice Query if a contract implements an interface
12 | * @dev Interface identification is specified in ERC-165. This function
13 | * uses less than 30,000 gas
14 | * @param _interfaceId The interface identifier, as specified in ERC-165
15 | */
16 | function supportsInterface(bytes4 _interfaceId)
17 | external
18 | view
19 | returns (bool);
20 | }
--------------------------------------------------------------------------------
/src/tests/utils/index.ts:
--------------------------------------------------------------------------------
1 | import * as chai from 'chai'
2 | import chaiAsPromised from 'chai-as-promised'
3 | const ChaiBigNumber = require('chai-bignumber')
4 | import chaiString from 'chai-string'
5 | import * as ethers from 'ethers'
6 |
7 | export * from './contract'
8 | export * from './helpers'
9 |
10 | const BigNumber = ethers.utils.BigNumber
11 | export { BigNumber }
12 |
13 | export const { assert, expect } = chai
14 | .use(chaiString)
15 | .use(chaiAsPromised)
16 | .use(ChaiBigNumber());
17 |
18 | describe.if = function (condition: boolean, message: string, func: (this: Mocha.Suite) => void): void {
19 | const run: Mocha.PendingSuiteFunction = condition ? this : this.skip;
20 | run(message, func);
21 | }
--------------------------------------------------------------------------------
/.soliumrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "solium:all",
3 | "plugins": ["security"],
4 | "rules": {
5 | "imports-on-top": 1,
6 | "variable-declarations": 1,
7 | "array-declarations": 1,
8 | "operator-whitespace": 1,
9 | "lbrace": 1,
10 | "mixedcase": 0,
11 | "camelcase": 1,
12 | "uppercase": 1,
13 | "no-empty-blocks": 1,
14 | "no-unused-vars": 1,
15 | "quotes": 1,
16 | "indentation": ["error", 2],
17 | "arg-overflow": ["error", 8],
18 | "whitespace": 1,
19 | "deprecated-suicide": 1,
20 | "pragma-on-top": 1,
21 | "no-experimental": 0,
22 | "security/enforce-explicit-visibility": ["error"],
23 | "security/no-block-members": ["warning"],
24 | "security/no-low-level-calls": 0,
25 | "security/no-inline-assembly": 0
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/contracts/interfaces/IERC20.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | /**
4 | * @title ERC20 interface
5 | * @dev see https://eips.ethereum.org/EIPS/eip-20
6 | */
7 | interface IERC20 {
8 | function transfer(address to, uint256 value) external returns (bool);
9 | function approve(address spender, uint256 value) external returns (bool);
10 | function transferFrom(address from, address to, uint256 value) external returns (bool);
11 | function totalSupply() external view returns (uint256);
12 | function balanceOf(address who) external view returns (uint256);
13 | function allowance(address owner, address spender) external view returns (uint256);
14 | event Transfer(address indexed from, address indexed to, uint256 value);
15 | event Approval(address indexed owner, address indexed spender, uint256 value);
16 | }
--------------------------------------------------------------------------------
/typings/contracts/index.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import {
5 | BigNumberish,
6 | EventDescription,
7 | FunctionDescription
8 | } from "ethers/utils";
9 |
10 | export class TransactionOverrides {
11 | nonce?: BigNumberish | Promise;
12 | gasLimit?: BigNumberish | Promise;
13 | gasPrice?: BigNumberish | Promise;
14 | value?: BigNumberish | Promise;
15 | chainId?: number | Promise;
16 | }
17 |
18 | export interface TypedEventDescription<
19 | T extends Pick
20 | > extends EventDescription {
21 | encodeTopics: T["encodeTopics"];
22 | }
23 |
24 | export interface TypedFunctionDescription<
25 | T extends Pick
26 | > extends FunctionDescription {
27 | encode: T["encode"];
28 | }
29 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "allowSyntheticDefaultImports": true,
8 | "resolveJsonModule": true,
9 | "downlevelIteration": true,
10 | "importHelpers": true,
11 | "removeComments": false,
12 |
13 | "strictNullChecks": true,
14 | "noImplicitUseStrict": true,
15 | "noImplicitAny": false,
16 | "noImplicitReturns": true,
17 | "noImplicitThis": true,
18 | "noUnusedParameters": false,
19 | "noErrorTruncation": true,
20 | "esModuleInterop": true,
21 |
22 | "experimentalDecorators": true,
23 | "forceConsistentCasingInFileNames": true,
24 | "allowJs": false,
25 | "checkJs": false,
26 |
27 | "baseUrl": ".",
28 | "outDir": "build",
29 | "lib": ["es2017", "dom"],
30 |
31 | "typeRoots": [
32 | "./node_modules/@types"
33 | ]
34 |
35 | },
36 |
37 | "include": [
38 | "typings", "src"
39 | ],
40 |
41 | "exclude": [
42 | "node_modules",
43 | "dist"
44 | ]
45 | }
46 |
--------------------------------------------------------------------------------
/truffle.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // See
3 | // to customize your Truffle configuration!
4 |
5 | networks: {
6 | ganache: {
7 | network_id: 127001,
8 | host: "127.0.0.1",
9 | port: 8545
10 | },
11 | coverage: {
12 | host: "localhost",
13 | network_id: "*",
14 | port: 8545, // <-- If you change this, also set the port option in .solcover.js.
15 | gas: 0xfffffffffff, // <-- Use this high gas value
16 | gasPrice: 0x0000000000000001 // <-- Use this low gas price
17 | },
18 | },
19 |
20 | compilers: {
21 | solc: {
22 | version: "./node_modules/solc"
23 | }
24 | },
25 | solc: {
26 | optimizer: {
27 | enabled: true, // TO TURN ON for launch
28 | runs: 500,
29 | details: {
30 | yul: true
31 | }
32 | }
33 | },
34 |
35 | mocha: {
36 | reporter: "eth-gas-reporter",
37 | reporterOptions: {
38 | currency: "USD",
39 | gasPrice: 10,
40 | showTimeSpent: true
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/typings/txTypes.d.ts:
--------------------------------------------------------------------------------
1 | import { Wallet } from 'ethers'
2 | import { BigNumber } from 'ethers/utils'
3 |
4 | export type GasReceipt = {
5 | gasLimit: number | string | BigNumber;
6 | baseGas: number | string | BigNumber;
7 | gasPrice: number | string | BigNumber;
8 | feeRecipient: string;
9 | feeTokenData: string | Uint8Array;
10 | };
11 |
12 | export type TransferSignature = {
13 | contractAddress: string;
14 | signerWallet: Wallet;
15 | receiver: string;
16 | id: number | string | BigNumber;
17 | amount: number | string | BigNumber;
18 | transferData: Uint8Array | null;
19 | nonce: number | string | BigNumber;
20 | }
21 |
22 | export type BatchTransferSignature = {
23 | contractAddress: string;
24 | signerWallet: Wallet;
25 | receiver: string;
26 | ids: number[] | string[] | BigNumber[];
27 | amounts: number[] | string[] | BigNumber[];
28 | transferData: Uint8Array | null;
29 | nonce: number | string | BigNumber;
30 | }
31 |
32 |
33 | export type ApprovalSignature = {
34 | contractAddress: string;
35 | signerWallet: Wallet;
36 | operator: string;
37 | approved: boolean;
38 | nonce: number | string | BigNumber;
39 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017-present https://github.com/horizon-games
2 |
3 | MIT License
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/typings/contracts/LibEIP712.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface LibEIP712Interface extends Interface {
14 | functions: {};
15 |
16 | events: {};
17 | }
18 |
19 | export class LibEIP712 extends Contract {
20 | connect(signerOrProvider: Signer | Provider | string): LibEIP712;
21 | attach(addressOrName: string): LibEIP712;
22 | deployed(): Promise;
23 |
24 | on(event: EventFilter | string, listener: Listener): LibEIP712;
25 | once(event: EventFilter | string, listener: Listener): LibEIP712;
26 | addListener(eventName: EventFilter | string, listener: Listener): LibEIP712;
27 | removeAllListeners(eventName: EventFilter | string): LibEIP712;
28 | removeListener(eventName: any, listener: Listener): LibEIP712;
29 |
30 | interface: LibEIP712Interface;
31 |
32 | functions: {};
33 |
34 | filters: {};
35 |
36 | estimate: {};
37 | }
38 |
--------------------------------------------------------------------------------
/typings/contracts/IERC165.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface IERC165Interface extends Interface {
14 | functions: {};
15 |
16 | events: {};
17 | }
18 |
19 | export class IERC165 extends Contract {
20 | connect(signerOrProvider: Signer | Provider | string): IERC165;
21 | attach(addressOrName: string): IERC165;
22 | deployed(): Promise;
23 |
24 | on(event: EventFilter | string, listener: Listener): IERC165;
25 | once(event: EventFilter | string, listener: Listener): IERC165;
26 | addListener(eventName: EventFilter | string, listener: Listener): IERC165;
27 | removeAllListeners(eventName: EventFilter | string): IERC165;
28 | removeListener(eventName: any, listener: Listener): IERC165;
29 |
30 | interface: IERC165Interface;
31 |
32 | functions: {
33 | supportsInterface(_interfaceId: Arrayish): Promise;
34 | };
35 |
36 | filters: {};
37 |
38 | estimate: {};
39 | }
40 |
--------------------------------------------------------------------------------
/typings/contracts/IERC1271Wallet.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface IERC1271WalletInterface extends Interface {
14 | functions: {};
15 |
16 | events: {};
17 | }
18 |
19 | export class IERC1271Wallet extends Contract {
20 | connect(signerOrProvider: Signer | Provider | string): IERC1271Wallet;
21 | attach(addressOrName: string): IERC1271Wallet;
22 | deployed(): Promise;
23 |
24 | on(event: EventFilter | string, listener: Listener): IERC1271Wallet;
25 | once(event: EventFilter | string, listener: Listener): IERC1271Wallet;
26 | addListener(
27 | eventName: EventFilter | string,
28 | listener: Listener
29 | ): IERC1271Wallet;
30 | removeAllListeners(eventName: EventFilter | string): IERC1271Wallet;
31 | removeListener(eventName: any, listener: Listener): IERC1271Wallet;
32 |
33 | interface: IERC1271WalletInterface;
34 |
35 | functions: {
36 | isValidSignature(_hash: Arrayish, _signature: Arrayish): Promise;
37 | };
38 |
39 | filters: {};
40 |
41 | estimate: {};
42 | }
43 |
--------------------------------------------------------------------------------
/contracts/utils/Ownable.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 |
4 | /**
5 | * @title Ownable
6 | * @dev The Ownable contract has an owner address, and provides basic authorization control
7 | * functions, this simplifies the implementation of "user permissions".
8 | */
9 | contract Ownable {
10 | address private owner;
11 |
12 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
13 |
14 | /**
15 | * @dev The Ownable constructor sets the original `owner` of the contract to the sender
16 | * account.
17 | */
18 | constructor () internal {
19 | owner = msg.sender;
20 | emit OwnershipTransferred(address(0), owner);
21 | }
22 |
23 | /**
24 | * @dev Throws if called by any account other than the owner.
25 | */
26 | modifier onlyOwner() {
27 | require(msg.sender == owner, "Ownable#onlyOwner: SENDER_IS_NOT_OWNER");
28 | _;
29 | }
30 |
31 | /**
32 | * @notice Transfers the ownership of the contract to new address
33 | * @param _newOwner Address of the new owner
34 | */
35 | function transferOwnership(address _newOwner) public onlyOwner {
36 | require(_newOwner != address(0), "Ownable#transferOwnership: INVALID_ADDRESS");
37 | emit OwnershipTransferred(owner, _newOwner);
38 | owner = _newOwner;
39 | }
40 |
41 | /**
42 | * @notice Returns the address of the owner.
43 | */
44 | function getOwner() public view returns (address) {
45 | return owner;
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/typings/contracts/SignatureValidator.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface SignatureValidatorInterface extends Interface {
14 | functions: {};
15 |
16 | events: {};
17 | }
18 |
19 | export class SignatureValidator extends Contract {
20 | connect(signerOrProvider: Signer | Provider | string): SignatureValidator;
21 | attach(addressOrName: string): SignatureValidator;
22 | deployed(): Promise;
23 |
24 | on(event: EventFilter | string, listener: Listener): SignatureValidator;
25 | once(event: EventFilter | string, listener: Listener): SignatureValidator;
26 | addListener(
27 | eventName: EventFilter | string,
28 | listener: Listener
29 | ): SignatureValidator;
30 | removeAllListeners(eventName: EventFilter | string): SignatureValidator;
31 | removeListener(eventName: any, listener: Listener): SignatureValidator;
32 |
33 | interface: SignatureValidatorInterface;
34 |
35 | functions: {
36 | isValidSignature(
37 | _signerAddress: string,
38 | _hash: Arrayish,
39 | _data: Arrayish,
40 | _sig: Arrayish
41 | ): Promise;
42 | };
43 |
44 | filters: {};
45 |
46 | estimate: {};
47 | }
48 |
--------------------------------------------------------------------------------
/typings/contracts/ERC1155Metadata.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155MetadataInterface extends Interface {
14 | functions: {};
15 |
16 | events: {
17 | URI: TypedEventDescription<{
18 | encodeTopics([_uri, _id]: [null, BigNumberish | null]): string[];
19 | }>;
20 | };
21 | }
22 |
23 | export class ERC1155Metadata extends Contract {
24 | connect(signerOrProvider: Signer | Provider | string): ERC1155Metadata;
25 | attach(addressOrName: string): ERC1155Metadata;
26 | deployed(): Promise;
27 |
28 | on(event: EventFilter | string, listener: Listener): ERC1155Metadata;
29 | once(event: EventFilter | string, listener: Listener): ERC1155Metadata;
30 | addListener(
31 | eventName: EventFilter | string,
32 | listener: Listener
33 | ): ERC1155Metadata;
34 | removeAllListeners(eventName: EventFilter | string): ERC1155Metadata;
35 | removeListener(eventName: any, listener: Listener): ERC1155Metadata;
36 |
37 | interface: ERC1155MetadataInterface;
38 |
39 | functions: {
40 | uri(_id: BigNumberish): Promise;
41 | };
42 |
43 | filters: {
44 | URI(_uri: null, _id: BigNumberish | null): EventFilter;
45 | };
46 |
47 | estimate: {};
48 | }
49 |
--------------------------------------------------------------------------------
/contracts/mocks/ERC1155MetadataMock.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 | pragma experimental ABIEncoderV2;
3 |
4 | import "../tokens/ERC1155/ERC1155Metadata.sol";
5 |
6 |
7 | contract ERC1155MetadataMock is ERC1155Metadata {
8 |
9 | /***********************************|
10 | | Base URI Functions |
11 | |__________________________________*/
12 |
13 | /**
14 | * @notice Will update the base URL of token's URI
15 | * @param _newBaseMetadataURI New base URL of token's URI
16 | */
17 | function setBaseMetadataURI(string memory _newBaseMetadataURI) public {
18 | super._setBaseMetadataURI(_newBaseMetadataURI);
19 | }
20 |
21 |
22 | /***********************************|
23 | | Log URI Functions |
24 | |__________________________________*/
25 |
26 | /**
27 | * @notice Will emit default URI log event for corresponding token _id
28 | * @param _tokenIDs Array of IDs of tokens to log default URI
29 | */
30 | function logURIsMock(uint256[] memory _tokenIDs) public {
31 | super._logURIs(_tokenIDs);
32 | }
33 |
34 | /**
35 | * @notice Will emit a specific URI log event for corresponding token
36 | * @param _tokenIDs IDs of the token corresponding to the _uris logged
37 | * @param _URIs The URIs of the specified _tokenIDs
38 | */
39 | function logURIsMock2(uint256[] memory _tokenIDs, string[] memory _URIs) public {
40 | super._logURIs(_tokenIDs, _URIs);
41 | }
42 |
43 |
44 | /***********************************|
45 | | Unsupported Functions |
46 | |__________________________________*/
47 |
48 | function () external {
49 | revert('ERC1155MetadataMock: INVALID_METHOD');
50 | }
51 | }
--------------------------------------------------------------------------------
/contracts/interfaces/IERC1271Wallet.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 |
4 | interface IERC1271Wallet {
5 |
6 | /**
7 | * @notice Verifies whether the provided signature is valid with respect to the provided data
8 | * @dev MUST return the correct magic value if the signature provided is valid for the provided data
9 | * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)")
10 | * > This function MAY modify Ethereum's state
11 | * @param _data Arbitrary length data signed on the behalf of address(this)
12 | * @param _signature Signature byte array associated with _data
13 | * @return Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise
14 | *
15 | */
16 | function isValidSignature(
17 | bytes calldata _data,
18 | bytes calldata _signature)
19 | external
20 | view
21 | returns (bytes4 magicValue);
22 |
23 | /**
24 | * @notice Verifies whether the provided signature is valid with respect to the provided hash
25 | * @dev MUST return the correct magic value if the signature provided is valid for the provided hash
26 | * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)")
27 | * > This function MAY modify Ethereum's state
28 | * @param _hash keccak256 hash that was signed
29 | * @param _signature Signature byte array associated with _data
30 | * @return Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise
31 | */
32 | function isValidSignature(
33 | bytes32 _hash,
34 | bytes calldata _signature)
35 | external
36 | view
37 | returns (bytes4 magicValue);
38 | }
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "defaultSeverity": "warning",
3 | "rules": {
4 | "class-name": true,
5 | "comment-format": [
6 | false,
7 | "check-space"
8 | ],
9 | "curly": false,
10 | "indent": [true, "spaces", 2],
11 | "interface-name": false,
12 | "jsdoc-format": true,
13 | "no-consecutive-blank-lines": false,
14 | "no-debugger": true,
15 | "no-duplicate-variable": true,
16 | "no-eval": true,
17 | "no-internal-module": true,
18 | "no-trailing-whitespace": false,
19 | "no-shadowed-variable": false,
20 | "no-switch-case-fall-through": true,
21 | "no-unused-expression": false,
22 | "no-use-before-declare": false,
23 | "no-var-keyword": true,
24 | "import-name": false,
25 | "jsx-no-multiline-js": false,
26 | "jsx-no-lambda": false,
27 | "one-line": [
28 | true,
29 | "check-open-brace",
30 | "check-whitespace",
31 | "check-catch"
32 | ],
33 | "quotemark": [
34 | true,
35 | "single",
36 | "jsx-double"
37 | ],
38 | "semicolon": [true, "never"],
39 | "trailing-comma": [
40 | true,
41 | {
42 | "multiline": "never",
43 | "singleline": "never"
44 | }
45 | ],
46 | "triple-equals": [
47 | true,
48 | "allow-null-check"
49 | ],
50 | "typedef-whitespace": [
51 | true,
52 | {
53 | "call-signature": "nospace",
54 | "index-signature": "nospace",
55 | "parameter": "nospace",
56 | "property-declaration": "nospace",
57 | "variable-declaration": "nospace"
58 | }
59 | ],
60 | "variable-name": [
61 | true,
62 | "ban-keywords"
63 | ],
64 | "whitespace": [
65 | true,
66 | "check-branch",
67 | "check-decl",
68 | "check-separator",
69 | "check-type"
70 | ]
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/contracts/utils/Address.sol:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 ZeroEx Intl.
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 |
14 | pragma solidity ^0.5.12;
15 |
16 |
17 | /**
18 | * Utility library of inline functions on addresses
19 | */
20 | library Address {
21 |
22 | /**
23 | * Returns whether the target address is a contract
24 | * @dev This function will return false if invoked during the constructor of a contract,
25 | * as the code is not actually created until after the constructor finishes.
26 | * @param account address of the account to check
27 | * @return whether the target address is a contract
28 | */
29 | function isContract(address account) internal view returns (bool) {
30 | bytes32 codehash;
31 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
32 |
33 | // XXX Currently there is no better way to check if there is a contract in an address
34 | // than to check the size of the code at that address.
35 | // See https://ethereum.stackexchange.com/a/14016/36603
36 | // for more details about how this works.
37 | // TODO Check this again before the Serenity release, because all addresses will be
38 | // contracts then.
39 | assembly { codehash := extcodehash(account) }
40 | return (codehash != 0x0 && codehash != accountHash);
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/typings/contracts/ERC1271WalletMock.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1271WalletMockInterface extends Interface {
14 | functions: {
15 | setShouldReject: TypedFunctionDescription<{
16 | encode([_value]: [boolean]): string;
17 | }>;
18 | };
19 |
20 | events: {};
21 | }
22 |
23 | export class ERC1271WalletMock extends Contract {
24 | connect(signerOrProvider: Signer | Provider | string): ERC1271WalletMock;
25 | attach(addressOrName: string): ERC1271WalletMock;
26 | deployed(): Promise;
27 |
28 | on(event: EventFilter | string, listener: Listener): ERC1271WalletMock;
29 | once(event: EventFilter | string, listener: Listener): ERC1271WalletMock;
30 | addListener(
31 | eventName: EventFilter | string,
32 | listener: Listener
33 | ): ERC1271WalletMock;
34 | removeAllListeners(eventName: EventFilter | string): ERC1271WalletMock;
35 | removeListener(eventName: any, listener: Listener): ERC1271WalletMock;
36 |
37 | interface: ERC1271WalletMockInterface;
38 |
39 | functions: {
40 | isValidSignature(_hash: Arrayish, _signature: Arrayish): Promise;
41 |
42 | setShouldReject(
43 | _value: boolean,
44 | overrides?: TransactionOverrides
45 | ): Promise;
46 |
47 | ERC1271_INVALID(): Promise;
48 | ERC1271_MAGIC_VAL(): Promise;
49 | shouldReject(): Promise;
50 | };
51 |
52 | filters: {};
53 |
54 | estimate: {
55 | setShouldReject(_value: boolean): Promise;
56 | };
57 | }
58 |
--------------------------------------------------------------------------------
/typings/contracts/Ownable.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface OwnableInterface extends Interface {
14 | functions: {
15 | transferOwnership: TypedFunctionDescription<{
16 | encode([_newOwner]: [string]): string;
17 | }>;
18 | };
19 |
20 | events: {
21 | OwnershipTransferred: TypedEventDescription<{
22 | encodeTopics([previousOwner, newOwner]: [
23 | string | null,
24 | string | null
25 | ]): string[];
26 | }>;
27 | };
28 | }
29 |
30 | export class Ownable extends Contract {
31 | connect(signerOrProvider: Signer | Provider | string): Ownable;
32 | attach(addressOrName: string): Ownable;
33 | deployed(): Promise;
34 |
35 | on(event: EventFilter | string, listener: Listener): Ownable;
36 | once(event: EventFilter | string, listener: Listener): Ownable;
37 | addListener(eventName: EventFilter | string, listener: Listener): Ownable;
38 | removeAllListeners(eventName: EventFilter | string): Ownable;
39 | removeListener(eventName: any, listener: Listener): Ownable;
40 |
41 | interface: OwnableInterface;
42 |
43 | functions: {
44 | transferOwnership(
45 | _newOwner: string,
46 | overrides?: TransactionOverrides
47 | ): Promise;
48 |
49 | getOwner(): Promise;
50 | };
51 |
52 | filters: {
53 | OwnershipTransferred(
54 | previousOwner: string | null,
55 | newOwner: string | null
56 | ): EventFilter;
57 | };
58 |
59 | estimate: {
60 | transferOwnership(_newOwner: string): Promise;
61 | };
62 | }
63 |
--------------------------------------------------------------------------------
/contracts/mocks/ERC1271WalletMock.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | import "../interfaces/IERC1271Wallet.sol";
4 |
5 |
6 | // Contract to test safe transfer behavior.
7 | contract ERC1271WalletMock is IERC1271Wallet {
8 | bytes4 constant public ERC1271_MAGIC_VAL = 0x20c13b0b;
9 | bytes4 constant public ERC1271_INVALID = 0x0;
10 |
11 | // Keep values from last received contract.
12 | bool public shouldReject;
13 |
14 | // Set rejection to true by default
15 | constructor () public {
16 | shouldReject = true;
17 | }
18 |
19 | function setShouldReject(bool _value) public {
20 | shouldReject = _value;
21 | }
22 |
23 | /**
24 | * @dev Should return whether the signature provided is valid for the provided data
25 | * @param _data Arbitrary length data signed on the behalf of address(this)
26 | * @param _signature Signature byte array associated with _data
27 | *
28 | * MUST return the bytes4 magic value 0x20c13b0b when function passes.
29 | * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)
30 | */
31 | function isValidSignature(
32 | bytes calldata _data,
33 | bytes calldata _signature)
34 | external
35 | view
36 | returns (bytes4 magicValue)
37 | {
38 | magicValue = shouldReject ? ERC1271_INVALID : ERC1271_MAGIC_VAL;
39 | return magicValue;
40 | }
41 |
42 |
43 | /**
44 | * @dev Should return whether the signature provided is valid for the provided hash
45 | * @param _hash keccak256 hash that was signed
46 | * @param _signature Signature byte array associated with _data
47 | *
48 | * MUST return the bytes4 magic value 0x20c13b0b when function passes.
49 | * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)
50 | */
51 | function isValidSignature(
52 | bytes32 _hash,
53 | bytes calldata _signature)
54 | external
55 | view
56 | returns (bytes4 magicValue)
57 | {
58 | magicValue = shouldReject ? ERC1271_INVALID : ERC1271_MAGIC_VAL;
59 | return magicValue;
60 | }
61 |
62 | }
--------------------------------------------------------------------------------
/contracts/utils/SafeMath.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 |
4 | /**
5 | * @title SafeMath
6 | * @dev Unsigned math operations with safety checks that revert on error
7 | */
8 | library SafeMath {
9 |
10 | /**
11 | * @dev Multiplies two unsigned integers, reverts on overflow.
12 | */
13 | function mul(uint256 a, uint256 b) internal pure returns (uint256) {
14 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
15 | // benefit is lost if 'b' is also tested.
16 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
17 | if (a == 0) {
18 | return 0;
19 | }
20 |
21 | uint256 c = a * b;
22 | require(c / a == b, "SafeMath#mul: OVERFLOW");
23 |
24 | return c;
25 | }
26 |
27 | /**
28 | * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
29 | */
30 | function div(uint256 a, uint256 b) internal pure returns (uint256) {
31 | // Solidity only automatically asserts when dividing by 0
32 | require(b > 0, "SafeMath#div: DIVISION_BY_ZERO");
33 | uint256 c = a / b;
34 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold
35 |
36 | return c;
37 | }
38 |
39 | /**
40 | * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
41 | */
42 | function sub(uint256 a, uint256 b) internal pure returns (uint256) {
43 | require(b <= a, "SafeMath#sub: UNDERFLOW");
44 | uint256 c = a - b;
45 |
46 | return c;
47 | }
48 |
49 | /**
50 | * @dev Adds two unsigned integers, reverts on overflow.
51 | */
52 | function add(uint256 a, uint256 b) internal pure returns (uint256) {
53 | uint256 c = a + b;
54 | require(c >= a, "SafeMath#add: OVERFLOW");
55 |
56 | return c;
57 | }
58 |
59 | /**
60 | * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
61 | * reverts when dividing by zero.
62 | */
63 | function mod(uint256 a, uint256 b) internal pure returns (uint256) {
64 | require(b != 0, "SafeMath#mod: DIVISION_BY_ZERO");
65 | return a % b;
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/contracts/mocks/ERC1155MetaMintBurnMock.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 | pragma experimental ABIEncoderV2;
3 |
4 | import "../tokens/ERC1155/ERC1155Meta.sol";
5 | import "../tokens/ERC1155/ERC1155MintBurn.sol";
6 | import "../tokens/ERC1155/ERC1155Metadata.sol";
7 |
8 |
9 | contract ERC1155MetaMintBurnMock is ERC1155Meta, ERC1155MintBurn, ERC1155Metadata {
10 |
11 | constructor() public { }
12 |
13 | // ---- Minting functions
14 |
15 | /**
16 | * @dev Mint _value of tokens of a given id
17 | * @param _to The address to mint tokens to.
18 | * @param _id token id to mint
19 | * @param _value The amount to be minted
20 | * @param _data Data to be passed if receiver is contract
21 | */
22 | function mintMock(address _to, uint256 _id, uint256 _value, bytes memory _data)
23 | public
24 | {
25 | super._mint(_to, _id, _value, _data);
26 | }
27 |
28 | /**
29 | * @dev Mint tokens for each ids in _ids
30 | * @param _to The address to mint tokens to.
31 | * @param _ids Array of ids to mint
32 | * @param _values Array of amount of tokens to mint per id
33 | * @param _data Data to be passed if receiver is contract
34 | */
35 | function batchMintMock(address _to, uint256[] memory _ids, uint256[] memory _values, bytes memory _data)
36 | public
37 | {
38 | super._batchMint(_to, _ids, _values, _data);
39 | }
40 |
41 | // ---- Burning functions
42 |
43 | /**
44 | * @dev burn _value of tokens of a given token id
45 | * @param _from The address to burn tokens from.
46 | * @param _id token id to burn
47 | * @param _value The amount to be burned
48 | */
49 | function burnMock(address _from, uint256 _id, uint256 _value)
50 | public
51 | {
52 | super._burn(_from, _id, _value);
53 | }
54 |
55 | /**
56 | * @dev burn _value of tokens of a given token id
57 | * @param _from The address to burn tokens from.
58 | * @param _ids Array of token ids to burn
59 | * @param _values Array of the amount to be burned
60 | */
61 | function batchBurnMock(address _from, uint256[] memory _ids, uint256[] memory _values)
62 | public
63 | {
64 | super._batchBurn(_from, _ids, _values);
65 | }
66 |
67 | /***********************************|
68 | | Unsupported Functions |
69 | |__________________________________*/
70 |
71 | function () external {
72 | revert("ERC1155MetaMintBurnMock: INVALID_METHOD");
73 | }
74 | }
--------------------------------------------------------------------------------
/contracts/mocks/ERC1155MetaMintBurnPackedBalanceMock.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 | pragma experimental ABIEncoderV2;
3 |
4 | import "../tokens/ERC1155PackedBalance/ERC1155MetaPackedBalance.sol";
5 | import "../tokens/ERC1155PackedBalance/ERC1155MintBurnPackedBalance.sol";
6 |
7 |
8 | contract ERC1155MetaMintBurnPackedBalanceMock is ERC1155MintBurnPackedBalance, ERC1155MetaPackedBalance {
9 |
10 | constructor() public {}
11 |
12 | // ---- Minting functions
13 |
14 | /**
15 | * @dev Mint _value of tokens of a given id
16 | * @param _to The address to mint tokens to.
17 | * @param _id token id to mint
18 | * @param _value The amount to be minted
19 | * @param _data Data to be passed if receiver is contract
20 | */
21 | function mintMock(address _to, uint256 _id, uint256 _value, bytes memory _data)
22 | public
23 | {
24 | _mint(_to, _id, _value, _data);
25 | }
26 |
27 | /**
28 | * @dev Mint tokens for each ids in _ids
29 | * @param _to The address to mint tokens to.
30 | * @param _ids Array of ids to mint
31 | * @param _values Array of amount of tokens to mint per id
32 | * @param _data Data to be passed if receiver is contract
33 | */
34 | function batchMintMock(address _to, uint256[] memory _ids, uint256[] memory _values, bytes memory _data)
35 | public
36 | {
37 | _batchMint(_to, _ids, _values, _data);
38 | }
39 |
40 | // ---- Burning functions
41 |
42 | /**
43 | * @dev burn _value of tokens of a given token id
44 | * @param _from The address to burn tokens from.
45 | * @param _id token id to burn
46 | * @param _value The amount to be burned
47 | */
48 | function burnMock(address _from, uint256 _id, uint256 _value)
49 | public
50 | {
51 | _burn(_from, _id, _value);
52 | }
53 |
54 | /**
55 | * @dev burn _value of tokens of a given token id
56 | * @param _from The address to burn tokens from.
57 | * @param _ids Array of token ids to burn
58 | * @param _values Array of the amount to be burned
59 | */
60 | function batchBurnMock(address _from, uint256[] memory _ids, uint256[] memory _values)
61 | public
62 | {
63 | _batchBurn(_from, _ids, _values);
64 | }
65 |
66 | /***********************************|
67 | | Unsupported Functions |
68 | |__________________________________*/
69 |
70 | function () external {
71 | revert('ERC1155MetaMintBurnPackedBalanceMock: INVALID_METHOD');
72 | }
73 |
74 | }
--------------------------------------------------------------------------------
/typings/contracts/OwnableMock.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface OwnableMockInterface extends Interface {
14 | functions: {
15 | transferOwnership: TypedFunctionDescription<{
16 | encode([_newOwner]: [string]): string;
17 | }>;
18 |
19 | ownerCall: TypedFunctionDescription<{ encode([]: []): string }>;
20 |
21 | nonOwnerCall: TypedFunctionDescription<{ encode([]: []): string }>;
22 | };
23 |
24 | events: {
25 | OwnershipTransferred: TypedEventDescription<{
26 | encodeTopics([previousOwner, newOwner]: [
27 | string | null,
28 | string | null
29 | ]): string[];
30 | }>;
31 | };
32 | }
33 |
34 | export class OwnableMock extends Contract {
35 | connect(signerOrProvider: Signer | Provider | string): OwnableMock;
36 | attach(addressOrName: string): OwnableMock;
37 | deployed(): Promise;
38 |
39 | on(event: EventFilter | string, listener: Listener): OwnableMock;
40 | once(event: EventFilter | string, listener: Listener): OwnableMock;
41 | addListener(eventName: EventFilter | string, listener: Listener): OwnableMock;
42 | removeAllListeners(eventName: EventFilter | string): OwnableMock;
43 | removeListener(eventName: any, listener: Listener): OwnableMock;
44 |
45 | interface: OwnableMockInterface;
46 |
47 | functions: {
48 | transferOwnership(
49 | _newOwner: string,
50 | overrides?: TransactionOverrides
51 | ): Promise;
52 |
53 | ownerCall(overrides?: TransactionOverrides): Promise;
54 |
55 | nonOwnerCall(
56 | overrides?: TransactionOverrides
57 | ): Promise;
58 |
59 | getOwner(): Promise;
60 | };
61 |
62 | filters: {
63 | OwnershipTransferred(
64 | previousOwner: string | null,
65 | newOwner: string | null
66 | ): EventFilter;
67 | };
68 |
69 | estimate: {
70 | transferOwnership(_newOwner: string): Promise;
71 |
72 | ownerCall(): Promise;
73 |
74 | nonOwnerCall(): Promise;
75 | };
76 | }
77 |
--------------------------------------------------------------------------------
/contracts/utils/LibEIP712.sol:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 ZeroEx Intl.
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | * Unless required by applicable law or agreed to in writing, software
8 | * distributed under the License is distributed on an "AS IS" BASIS,
9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | * See the License for the specific language governing permissions and
11 | * limitations under the License.
12 | */
13 | pragma solidity ^0.5.12;
14 |
15 |
16 | contract LibEIP712 {
17 |
18 | // keccak256(
19 | // "EIP712Domain(address verifyingContract)"
20 | // );
21 | bytes32 internal constant DOMAIN_SEPARATOR_TYPEHASH = 0x035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d4749;
22 |
23 | // Domain seperator created in constructor
24 | bytes32 internal EIP712_DOMAIN_HASH;
25 |
26 | // Instantiate EIP712_DOMAIN_HASH
27 | constructor ()
28 | public
29 | {
30 | EIP712_DOMAIN_HASH = keccak256(abi.encodePacked(DOMAIN_SEPARATOR_TYPEHASH, address(this)));
31 | }
32 |
33 | /**
34 | * @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain.
35 | * @param hashStruct The EIP712 hash struct.
36 | * @return EIP712 hash applied to this EIP712 Domain.
37 | */
38 | function hashEIP712Message(bytes32 hashStruct)
39 | internal
40 | view
41 | returns (bytes32 result)
42 | {
43 |
44 | return keccak256(
45 | abi.encodePacked(
46 | bytes32(0x1901000000000000000000000000000000000000000000000000000000000000),
47 | EIP712_DOMAIN_HASH,
48 | hashStruct
49 | ));
50 |
51 | //bytes32 eip712DomainHash = EIP712_DOMAIN_HASH;
52 | // Assembly for more efficient computing:
53 | // assembly {
54 | // // Load free memory pointer
55 | // let memPtr := mload(64)
56 |
57 | // mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header
58 | // mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash
59 | // mstore(add(memPtr, 34), hashStruct) // Hash of struct
60 |
61 | // // Compute hash
62 | // result := keccak256(memPtr, 66)
63 | // }
64 | // return result;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/contracts/utils/LibBytes.sol:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2018 ZeroEx Intl.
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | This is a truncated version of the original LibBytes.sol library from ZeroEx.
13 | */
14 |
15 | pragma solidity ^0.5.12;
16 |
17 |
18 | library LibBytes {
19 | using LibBytes for bytes;
20 |
21 |
22 | /***********************************|
23 | | Pop Bytes Functions |
24 | |__________________________________*/
25 |
26 | /**
27 | * @dev Pops the last byte off of a byte array by modifying its length.
28 | * @param b Byte array that will be modified.
29 | * @return The byte that was popped off.
30 | */
31 | function popLastByte(bytes memory b)
32 | internal
33 | pure
34 | returns (bytes1 result)
35 | {
36 | require(
37 | b.length > 0,
38 | "LibBytes#popLastByte: GREATER_THAN_ZERO_LENGTH_REQUIRED"
39 | );
40 |
41 | // Store last byte.
42 | result = b[b.length - 1];
43 |
44 | assembly {
45 | // Decrement length of byte array.
46 | let newLen := sub(mload(b), 1)
47 | mstore(b, newLen)
48 | }
49 | return result;
50 | }
51 |
52 |
53 | /***********************************|
54 | | Read Bytes Functions |
55 | |__________________________________*/
56 |
57 | /**
58 | * @dev Reads a bytes32 value from a position in a byte array.
59 | * @param b Byte array containing a bytes32 value.
60 | * @param index Index in byte array of bytes32 value.
61 | * @return bytes32 value from byte array.
62 | */
63 | function readBytes32(
64 | bytes memory b,
65 | uint256 index
66 | )
67 | internal
68 | pure
69 | returns (bytes32 result)
70 | {
71 | require(
72 | b.length >= index + 32,
73 | "LibBytes#readBytes32: GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED"
74 | );
75 |
76 | // Arrays are prefixed by a 256 bit length parameter
77 | index += 32;
78 |
79 | // Read the bytes32 from array memory
80 | assembly {
81 | result := mload(add(b, index))
82 | }
83 | return result;
84 | }
85 |
86 | }
--------------------------------------------------------------------------------
/typings/contracts/ERC1155MetadataMock.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155MetadataMockInterface extends Interface {
14 | functions: {
15 | setBaseMetadataURI: TypedFunctionDescription<{
16 | encode([_newBaseMetadataURI]: [string]): string;
17 | }>;
18 |
19 | logURIsMock: TypedFunctionDescription<{
20 | encode([_tokenIDs]: [(BigNumberish)[]]): string;
21 | }>;
22 |
23 | logURIsMock2: TypedFunctionDescription<{
24 | encode([_tokenIDs, _URIs]: [(BigNumberish)[], (string)[]]): string;
25 | }>;
26 | };
27 |
28 | events: {
29 | URI: TypedEventDescription<{
30 | encodeTopics([_uri, _id]: [null, BigNumberish | null]): string[];
31 | }>;
32 | };
33 | }
34 |
35 | export class ERC1155MetadataMock extends Contract {
36 | connect(signerOrProvider: Signer | Provider | string): ERC1155MetadataMock;
37 | attach(addressOrName: string): ERC1155MetadataMock;
38 | deployed(): Promise;
39 |
40 | on(event: EventFilter | string, listener: Listener): ERC1155MetadataMock;
41 | once(event: EventFilter | string, listener: Listener): ERC1155MetadataMock;
42 | addListener(
43 | eventName: EventFilter | string,
44 | listener: Listener
45 | ): ERC1155MetadataMock;
46 | removeAllListeners(eventName: EventFilter | string): ERC1155MetadataMock;
47 | removeListener(eventName: any, listener: Listener): ERC1155MetadataMock;
48 |
49 | interface: ERC1155MetadataMockInterface;
50 |
51 | functions: {
52 | uri(_id: BigNumberish): Promise;
53 |
54 | setBaseMetadataURI(
55 | _newBaseMetadataURI: string,
56 | overrides?: TransactionOverrides
57 | ): Promise;
58 |
59 | logURIsMock(
60 | _tokenIDs: (BigNumberish)[],
61 | overrides?: TransactionOverrides
62 | ): Promise;
63 |
64 | logURIsMock2(
65 | _tokenIDs: (BigNumberish)[],
66 | _URIs: (string)[],
67 | overrides?: TransactionOverrides
68 | ): Promise;
69 | };
70 |
71 | filters: {
72 | URI(_uri: null, _id: BigNumberish | null): EventFilter;
73 | };
74 |
75 | estimate: {
76 | setBaseMetadataURI(_newBaseMetadataURI: string): Promise;
77 |
78 | logURIsMock(_tokenIDs: (BigNumberish)[]): Promise;
79 |
80 | logURIsMock2(
81 | _tokenIDs: (BigNumberish)[],
82 | _URIs: (string)[]
83 | ): Promise;
84 | };
85 | }
86 |
--------------------------------------------------------------------------------
/typings/contracts/IERC1155TokenReceiver.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface IERC1155TokenReceiverInterface extends Interface {
14 | functions: {
15 | onERC1155Received: TypedFunctionDescription<{
16 | encode([_operator, _from, _id, _amount, _data]: [
17 | string,
18 | string,
19 | BigNumberish,
20 | BigNumberish,
21 | Arrayish
22 | ]): string;
23 | }>;
24 |
25 | onERC1155BatchReceived: TypedFunctionDescription<{
26 | encode([_operator, _from, _ids, _amounts, _data]: [
27 | string,
28 | string,
29 | (BigNumberish)[],
30 | (BigNumberish)[],
31 | Arrayish
32 | ]): string;
33 | }>;
34 | };
35 |
36 | events: {};
37 | }
38 |
39 | export class IERC1155TokenReceiver extends Contract {
40 | connect(signerOrProvider: Signer | Provider | string): IERC1155TokenReceiver;
41 | attach(addressOrName: string): IERC1155TokenReceiver;
42 | deployed(): Promise;
43 |
44 | on(event: EventFilter | string, listener: Listener): IERC1155TokenReceiver;
45 | once(event: EventFilter | string, listener: Listener): IERC1155TokenReceiver;
46 | addListener(
47 | eventName: EventFilter | string,
48 | listener: Listener
49 | ): IERC1155TokenReceiver;
50 | removeAllListeners(eventName: EventFilter | string): IERC1155TokenReceiver;
51 | removeListener(eventName: any, listener: Listener): IERC1155TokenReceiver;
52 |
53 | interface: IERC1155TokenReceiverInterface;
54 |
55 | functions: {
56 | supportsInterface(interfaceID: Arrayish): Promise;
57 |
58 | onERC1155Received(
59 | _operator: string,
60 | _from: string,
61 | _id: BigNumberish,
62 | _amount: BigNumberish,
63 | _data: Arrayish,
64 | overrides?: TransactionOverrides
65 | ): Promise;
66 |
67 | onERC1155BatchReceived(
68 | _operator: string,
69 | _from: string,
70 | _ids: (BigNumberish)[],
71 | _amounts: (BigNumberish)[],
72 | _data: Arrayish,
73 | overrides?: TransactionOverrides
74 | ): Promise;
75 | };
76 |
77 | filters: {};
78 |
79 | estimate: {
80 | onERC1155Received(
81 | _operator: string,
82 | _from: string,
83 | _id: BigNumberish,
84 | _amount: BigNumberish,
85 | _data: Arrayish
86 | ): Promise;
87 |
88 | onERC1155BatchReceived(
89 | _operator: string,
90 | _from: string,
91 | _ids: (BigNumberish)[],
92 | _amounts: (BigNumberish)[],
93 | _data: Arrayish
94 | ): Promise;
95 | };
96 | }
97 |
--------------------------------------------------------------------------------
/contracts/interfaces/IERC1155TokenReceiver.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | /**
4 | * @dev ERC-1155 interface for accepting safe transfers.
5 | */
6 | interface IERC1155TokenReceiver {
7 |
8 | /**
9 | * @notice Handle the receipt of a single ERC1155 token type
10 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated
11 | * This function MAY throw to revert and reject the transfer
12 | * Return of other amount than the magic value MUST result in the transaction being reverted
13 | * Note: The token contract address is always the message sender
14 | * @param _operator The address which called the `safeTransferFrom` function
15 | * @param _from The address which previously owned the token
16 | * @param _id The id of the token being transferred
17 | * @param _amount The amount of tokens being transferred
18 | * @param _data Additional data with no specified format
19 | * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
20 | */
21 | function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4);
22 |
23 | /**
24 | * @notice Handle the receipt of multiple ERC1155 token types
25 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated
26 | * This function MAY throw to revert and reject the transfer
27 | * Return of other amount than the magic value WILL result in the transaction being reverted
28 | * Note: The token contract address is always the message sender
29 | * @param _operator The address which called the `safeBatchTransferFrom` function
30 | * @param _from The address which previously owned the token
31 | * @param _ids An array containing ids of each token being transferred
32 | * @param _amounts An array containing amounts of each token being transferred
33 | * @param _data Additional data with no specified format
34 | * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
35 | */
36 | function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4);
37 |
38 | /**
39 | * @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types.
40 | * @param interfaceID The ERC-165 interface ID that is queried for support.s
41 | * @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface.
42 | * This function MUST NOT consume more than 5,000 gas.
43 | * @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported.
44 | */
45 | function supportsInterface(bytes4 interfaceID) external view returns (bool);
46 |
47 | }
--------------------------------------------------------------------------------
/contracts/interfaces/IERC1155Meta.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | interface IERC1155Meta {
4 |
5 | /****************************************|
6 | | Public Meta Transfer Functions |
7 | |_______________________________________*/
8 |
9 | /**
10 | * @notice Allows anyone with a valid signature to transfer _amount amount of a token _id on the bahalf of _from
11 | * @param _from Source address
12 | * @param _to Target address
13 | * @param _id ID of the token type
14 | * @param _amount Transfered amount
15 | * @param _isGasFee Whether gas is reimbursed to executor or not
16 | * @param _data Encodes a meta transfer indicator, signature, gas payment receipt and extra transfer data
17 | * _data should be encoded as ((bytes32 r, bytes32 s, uint8 v, SignatureType sigType), (GasReceipt g, bytes data))
18 | * i.e. high level encoding should be (bytes, bytes), where the latter bytes array is a nested bytes array
19 | */
20 | function metaSafeTransferFrom(
21 | address _from,
22 | address _to,
23 | uint256 _id,
24 | uint256 _amount,
25 | bool _isGasFee,
26 | bytes calldata _data)
27 | external;
28 |
29 |
30 | /**
31 | * @notice Allows anyone with a valid signature to transfer multiple types of tokens on the bahalf of _from
32 | * @param _from Source addresses
33 | * @param _to Target addresses
34 | * @param _ids IDs of each token type
35 | * @param _amounts Transfer amounts per token type
36 | * @param _data Encodes a meta transfer indicator, signature, gas payment receipt and extra transfer data
37 | * _data should be encoded as ((bytes32 r, bytes32 s, uint8 v, SignatureType sigType), (GasReceipt g, bytes data))
38 | * i.e. high level encoding should be (bytes, bytes), where the latter bytes array is a nested bytes array
39 | */
40 | function metaSafeBatchTransferFrom(
41 | address _from,
42 | address _to,
43 | uint256[] calldata _ids,
44 | uint256[] calldata _amounts,
45 | bool _isGasFee,
46 | bytes calldata _data)
47 | external;
48 |
49 |
50 | /***********************************|
51 | | Operator Functions |
52 | |__________________________________*/
53 |
54 | /**
55 | * @notice Approve the passed address to spend on behalf of _from if valid signature is provided
56 | * @param _owner Address that wants to set operator status _spender
57 | * @param _operator Address to add to the set of authorized operators
58 | * @param _approved True if the operator is approved, false to revoke approval
59 | * @param _isGasFee Whether gas will be reimbursed or not, with vlid signature
60 | * @param _data Encodes signature and gas payment receipt
61 | * _data should be encoded as ((bytes32 r, bytes32 s, uint8 v, SignatureType sigType), (GasReceipt g))
62 | * i.e. high level encoding should be (bytes, bytes), where the latter bytes array is a nested bytes array
63 | */
64 | function metaSetApprovalForAll(
65 | address _owner,
66 | address _operator,
67 | bool _approved,
68 | bool _isGasFee,
69 | bytes calldata _data)
70 | external;
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/typings/contracts/IERC20.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface IERC20Interface extends Interface {
14 | functions: {
15 | transfer: TypedFunctionDescription<{
16 | encode([to, value]: [string, BigNumberish]): string;
17 | }>;
18 |
19 | approve: TypedFunctionDescription<{
20 | encode([spender, value]: [string, BigNumberish]): string;
21 | }>;
22 |
23 | transferFrom: TypedFunctionDescription<{
24 | encode([from, to, value]: [string, string, BigNumberish]): string;
25 | }>;
26 | };
27 |
28 | events: {
29 | Approval: TypedEventDescription<{
30 | encodeTopics([owner, spender, value]: [
31 | string | null,
32 | string | null,
33 | null
34 | ]): string[];
35 | }>;
36 |
37 | Transfer: TypedEventDescription<{
38 | encodeTopics([from, to, value]: [
39 | string | null,
40 | string | null,
41 | null
42 | ]): string[];
43 | }>;
44 | };
45 | }
46 |
47 | export class IERC20 extends Contract {
48 | connect(signerOrProvider: Signer | Provider | string): IERC20;
49 | attach(addressOrName: string): IERC20;
50 | deployed(): Promise;
51 |
52 | on(event: EventFilter | string, listener: Listener): IERC20;
53 | once(event: EventFilter | string, listener: Listener): IERC20;
54 | addListener(eventName: EventFilter | string, listener: Listener): IERC20;
55 | removeAllListeners(eventName: EventFilter | string): IERC20;
56 | removeListener(eventName: any, listener: Listener): IERC20;
57 |
58 | interface: IERC20Interface;
59 |
60 | functions: {
61 | balanceOf(who: string): Promise;
62 |
63 | allowance(owner: string, spender: string): Promise;
64 |
65 | transfer(
66 | to: string,
67 | value: BigNumberish,
68 | overrides?: TransactionOverrides
69 | ): Promise;
70 |
71 | approve(
72 | spender: string,
73 | value: BigNumberish,
74 | overrides?: TransactionOverrides
75 | ): Promise;
76 |
77 | transferFrom(
78 | from: string,
79 | to: string,
80 | value: BigNumberish,
81 | overrides?: TransactionOverrides
82 | ): Promise;
83 |
84 | totalSupply(): Promise;
85 | };
86 |
87 | filters: {
88 | Approval(
89 | owner: string | null,
90 | spender: string | null,
91 | value: null
92 | ): EventFilter;
93 |
94 | Transfer(from: string | null, to: string | null, value: null): EventFilter;
95 | };
96 |
97 | estimate: {
98 | transfer(to: string, value: BigNumberish): Promise;
99 |
100 | approve(spender: string, value: BigNumberish): Promise;
101 |
102 | transferFrom(
103 | from: string,
104 | to: string,
105 | value: BigNumberish
106 | ): Promise;
107 | };
108 | }
109 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "multi-token-standard",
3 | "version": "0.8.4",
4 | "description": "ERC1155 Multi-Token Standard implementation for Ethereum",
5 | "repository": "https://github.com/horizon-games/multi-token-standard",
6 | "license": "MIT",
7 | "keywords": [
8 | "token",
9 | "ERC",
10 | "ERC1155",
11 | "ERC-1155",
12 | "Fungible",
13 | "Non-Fungible",
14 | "ethereum",
15 | "horizongames"
16 | ],
17 | "files": [
18 | "LICENSE",
19 | "build",
20 | "contracts",
21 | "typings"
22 | ],
23 | "scripts": {
24 | "build": "truffle compile --all && yarn gen:contract-typings && tsc -b",
25 | "clean": "rm -rf build && rm -rf typings/contracts",
26 | "migrate": "truffle migrate --network ganache --reset",
27 | "migrate:rinkeby": "truffle migrate --network rinkeby",
28 | "test": "tsc -b && truffle test --network ganache build/*.spec.js",
29 | "test:benchmark": "tsc -b && truffle test --network ganache build/*.bench.js",
30 | "test:coverage": "solidity-coverage",
31 | "gen:contract-typings": "typechain --target ethers --outDir typings/contracts './build/contracts/*.json'",
32 | "lint": "yarn lint:ts && yarn lint:sol",
33 | "lint:fix": "yarn lint:ts:fix && yarn lint:sol:fix",
34 | "lint:sol": "solium -d .",
35 | "lint:sol:fix": "solium -d contracts/ --fix",
36 | "lint:ts": "tslint -c tslint.json -p .",
37 | "lint:ts:fix": "tslint -c tslint.json -p . --fix",
38 | "ganache": "ganache-cli --networkId ${npm_package_config_ganacheNetworkID} --port ${npm_package_config_ganachePort} --gasLimit ${npm_package_config_ganacheGasLimit} --gasPrice ${npm_package_config_ganacheGasPrice} --defaultBalanceEther ${npm_package_config_etherBalance} --deterministic --mnemonic \"${npm_package_config_mnemonic}\" ${npm_package_config_extra}",
39 | "ganache:verbose": "ganache-cli --networkId ${npm_package_config_ganacheNetworkID} --verbose --port ${npm_package_config_ganachePort} --gasLimit ${npm_package_config_ganacheGasLimit} --gasPrice ${npm_package_config_ganacheGasPrice} --defaultBalanceEther ${npm_package_config_etherBalance} --deterministic --mnemonic \"${npm_package_config_mnemonic}\" ${npm_package_config_extra}",
40 | "ganache:stop": "ps aux | grep ganache-cli | grep -v grep | awk '{print $2}' | xargs kill -9",
41 | "console": "truffle console"
42 | },
43 | "config": {
44 | "mnemonic": "dose weasel clever culture letter volume endorse used harvest ripple circle install",
45 | "ganacheNetworkID": 127001,
46 | "ganachePort": 8545,
47 | "ganacheGasLimit": "0xfffffffffff",
48 | "ganacheGasPrice": "20000000000",
49 | "etherBalance": "100000",
50 | "extra": ""
51 | },
52 | "devDependencies": {
53 | "@types/chai-as-promised": "^7.1.0",
54 | "@types/chai-string": "^1.4.1",
55 | "@types/mocha": "^5.2.7",
56 | "chai": "^4.2.0",
57 | "chai-as-promised": "^7.1.1",
58 | "chai-bignumber": "^3.0.0",
59 | "chai-string": "^1.5.0",
60 | "dotenv": "^8.0.0",
61 | "eth-gas-reporter": "^0.2.1",
62 | "ethers": "^4.0.31",
63 | "ganache-cli": "^6.4.4",
64 | "ganache-core": "^2.5.6",
65 | "solc": "0.5.12",
66 | "solidity-coverage": "^0.5.11",
67 | "solium": "^1.2.4",
68 | "truffle": "^5.0.25",
69 | "truffle-contract": "^4.0.22",
70 | "truffle-hdwallet-provider": "1.0.12",
71 | "tslint": "^5.18.0",
72 | "typechain": "^0.3.17",
73 | "typescript": "3.5.2",
74 | "zos-lib": "^2.4.0"
75 | },
76 | "dependencies": {}
77 | }
78 |
--------------------------------------------------------------------------------
/contracts/tokens/ERC1155/ERC1155Metadata.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.11;
2 | import "../../interfaces/IERC1155.sol";
3 |
4 |
5 | /**
6 | * @notice Contract that handles metadata related methods.
7 | * @dev Methods assume a deterministic generation of URI based on token IDs.
8 | * Methods also assume that URI uses hex representation of token IDs.
9 | */
10 | contract ERC1155Metadata {
11 |
12 | // URI's default URI prefix
13 | string internal baseMetadataURI;
14 | event URI(string _uri, uint256 indexed _id);
15 |
16 |
17 | /***********************************|
18 | | Metadata Public Function s |
19 | |__________________________________*/
20 |
21 | /**
22 | * @notice A distinct Uniform Resource Identifier (URI) for a given token.
23 | * @dev URIs are defined in RFC 3986.
24 | * URIs are assumed to be deterministically generated based on token ID
25 | * Token IDs are assumed to be represented in their hex format in URIs
26 | * @return URI string
27 | */
28 | function uri(uint256 _id) public view returns (string memory) {
29 | return string(abi.encodePacked(baseMetadataURI, _uint2str(_id), ".json"));
30 | }
31 |
32 |
33 | /***********************************|
34 | | Metadata Internal Functions |
35 | |__________________________________*/
36 |
37 | /**
38 | * @notice Will emit default URI log event for corresponding token _id
39 | * @param _tokenIDs Array of IDs of tokens to log default URI
40 | */
41 | function _logURIs(uint256[] memory _tokenIDs) internal {
42 | string memory baseURL = baseMetadataURI;
43 | string memory tokenURI;
44 |
45 | for (uint256 i = 0; i < _tokenIDs.length; i++) {
46 | tokenURI = string(abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json"));
47 | emit URI(tokenURI, _tokenIDs[i]);
48 | }
49 | }
50 |
51 | /**
52 | * @notice Will emit a specific URI log event for corresponding token
53 | * @param _tokenIDs IDs of the token corresponding to the _uris logged
54 | * @param _URIs The URIs of the specified _tokenIDs
55 | */
56 | function _logURIs(uint256[] memory _tokenIDs, string[] memory _URIs) internal {
57 | require(_tokenIDs.length == _URIs.length, "ERC1155Metadata#_logURIs: INVALID_ARRAYS_LENGTH");
58 | for (uint256 i = 0; i < _tokenIDs.length; i++) {
59 | emit URI(_URIs[i], _tokenIDs[i]);
60 | }
61 | }
62 |
63 | /**
64 | * @notice Will update the base URL of token's URI
65 | * @param _newBaseMetadataURI New base URL of token's URI
66 | */
67 | function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal {
68 | baseMetadataURI = _newBaseMetadataURI;
69 | }
70 |
71 |
72 | /***********************************|
73 | | Utility Internal Functions |
74 | |__________________________________*/
75 |
76 | /**
77 | * @notice Convert uint256 to string
78 | * @param _i Unsigned integer to convert to string
79 | */
80 | function _uint2str(uint256 _i) internal pure returns (string memory _uintAsString) {
81 | if (_i == 0) {
82 | return "0";
83 | }
84 |
85 | uint256 j = _i;
86 | uint256 ii = _i;
87 | uint256 len;
88 |
89 | // Get number of bytes
90 | while (j != 0) {
91 | len++;
92 | j /= 10;
93 | }
94 |
95 | bytes memory bstr = new bytes(len);
96 | uint256 k = len - 1;
97 |
98 | // Get each individual ASCII
99 | while (ii != 0) {
100 | bstr[k--] = byte(uint8(48 + ii % 10));
101 | ii /= 10;
102 | }
103 |
104 | // Convert to string
105 | return string(bstr);
106 | }
107 |
108 | }
--------------------------------------------------------------------------------
/typings/contracts/IERC1155Meta.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface IERC1155MetaInterface extends Interface {
14 | functions: {
15 | metaSafeTransferFrom: TypedFunctionDescription<{
16 | encode([_from, _to, _id, _amount, _isGasFee, _data]: [
17 | string,
18 | string,
19 | BigNumberish,
20 | BigNumberish,
21 | boolean,
22 | Arrayish
23 | ]): string;
24 | }>;
25 |
26 | metaSafeBatchTransferFrom: TypedFunctionDescription<{
27 | encode([_from, _to, _ids, _amounts, _isGasFee, _data]: [
28 | string,
29 | string,
30 | (BigNumberish)[],
31 | (BigNumberish)[],
32 | boolean,
33 | Arrayish
34 | ]): string;
35 | }>;
36 |
37 | metaSetApprovalForAll: TypedFunctionDescription<{
38 | encode([_owner, _operator, _approved, _isGasFee, _data]: [
39 | string,
40 | string,
41 | boolean,
42 | boolean,
43 | Arrayish
44 | ]): string;
45 | }>;
46 | };
47 |
48 | events: {};
49 | }
50 |
51 | export class IERC1155Meta extends Contract {
52 | connect(signerOrProvider: Signer | Provider | string): IERC1155Meta;
53 | attach(addressOrName: string): IERC1155Meta;
54 | deployed(): Promise;
55 |
56 | on(event: EventFilter | string, listener: Listener): IERC1155Meta;
57 | once(event: EventFilter | string, listener: Listener): IERC1155Meta;
58 | addListener(
59 | eventName: EventFilter | string,
60 | listener: Listener
61 | ): IERC1155Meta;
62 | removeAllListeners(eventName: EventFilter | string): IERC1155Meta;
63 | removeListener(eventName: any, listener: Listener): IERC1155Meta;
64 |
65 | interface: IERC1155MetaInterface;
66 |
67 | functions: {
68 | metaSafeTransferFrom(
69 | _from: string,
70 | _to: string,
71 | _id: BigNumberish,
72 | _amount: BigNumberish,
73 | _isGasFee: boolean,
74 | _data: Arrayish,
75 | overrides?: TransactionOverrides
76 | ): Promise;
77 |
78 | metaSafeBatchTransferFrom(
79 | _from: string,
80 | _to: string,
81 | _ids: (BigNumberish)[],
82 | _amounts: (BigNumberish)[],
83 | _isGasFee: boolean,
84 | _data: Arrayish,
85 | overrides?: TransactionOverrides
86 | ): Promise;
87 |
88 | metaSetApprovalForAll(
89 | _owner: string,
90 | _operator: string,
91 | _approved: boolean,
92 | _isGasFee: boolean,
93 | _data: Arrayish,
94 | overrides?: TransactionOverrides
95 | ): Promise;
96 | };
97 |
98 | filters: {};
99 |
100 | estimate: {
101 | metaSafeTransferFrom(
102 | _from: string,
103 | _to: string,
104 | _id: BigNumberish,
105 | _amount: BigNumberish,
106 | _isGasFee: boolean,
107 | _data: Arrayish
108 | ): Promise;
109 |
110 | metaSafeBatchTransferFrom(
111 | _from: string,
112 | _to: string,
113 | _ids: (BigNumberish)[],
114 | _amounts: (BigNumberish)[],
115 | _isGasFee: boolean,
116 | _data: Arrayish
117 | ): Promise;
118 |
119 | metaSetApprovalForAll(
120 | _owner: string,
121 | _operator: string,
122 | _approved: boolean,
123 | _isGasFee: boolean,
124 | _data: Arrayish
125 | ): Promise;
126 | };
127 | }
128 |
--------------------------------------------------------------------------------
/contracts/tokens/ERC1155/ERC1155MintBurn.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | import "./ERC1155.sol";
4 |
5 |
6 | /**
7 | * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume
8 | * a parent contract to be executed as they are `internal` functions
9 | */
10 | contract ERC1155MintBurn is ERC1155 {
11 |
12 |
13 | /****************************************|
14 | | Minting Functions |
15 | |_______________________________________*/
16 |
17 | /**
18 | * @notice Mint _amount of tokens of a given id
19 | * @param _to The address to mint tokens to
20 | * @param _id Token id to mint
21 | * @param _amount The amount to be minted
22 | * @param _data Data to pass if receiver is contract
23 | */
24 | function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data)
25 | internal
26 | {
27 | // Add _amount
28 | balances[_to][_id] = balances[_to][_id].add(_amount);
29 |
30 | // Emit event
31 | emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);
32 |
33 | // Calling onReceive method if recipient is contract
34 | _callonERC1155Received(address(0x0), _to, _id, _amount, _data);
35 | }
36 |
37 | /**
38 | * @notice Mint tokens for each ids in _ids
39 | * @param _to The address to mint tokens to
40 | * @param _ids Array of ids to mint
41 | * @param _amounts Array of amount of tokens to mint per id
42 | * @param _data Data to pass if receiver is contract
43 | */
44 | function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
45 | internal
46 | {
47 | require(_ids.length == _amounts.length, "ERC1155MintBurn#batchMint: INVALID_ARRAYS_LENGTH");
48 |
49 | // Number of mints to execute
50 | uint256 nMint = _ids.length;
51 |
52 | // Executing all minting
53 | for (uint256 i = 0; i < nMint; i++) {
54 | // Update storage balance
55 | balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]);
56 | }
57 |
58 | // Emit batch mint event
59 | emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);
60 |
61 | // Calling onReceive method if recipient is contract
62 | _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, _data);
63 | }
64 |
65 |
66 | /****************************************|
67 | | Burning Functions |
68 | |_______________________________________*/
69 |
70 | /**
71 | * @notice Burn _amount of tokens of a given token id
72 | * @param _from The address to burn tokens from
73 | * @param _id Token id to burn
74 | * @param _amount The amount to be burned
75 | */
76 | function _burn(address _from, uint256 _id, uint256 _amount)
77 | internal
78 | {
79 | //Substract _amount
80 | balances[_from][_id] = balances[_from][_id].sub(_amount);
81 |
82 | // Emit event
83 | emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
84 | }
85 |
86 | /**
87 | * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
88 | * @param _from The address to burn tokens from
89 | * @param _ids Array of token ids to burn
90 | * @param _amounts Array of the amount to be burned
91 | */
92 | function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts)
93 | internal
94 | {
95 | require(_ids.length == _amounts.length, "ERC1155MintBurn#batchBurn: INVALID_ARRAYS_LENGTH");
96 |
97 | // Number of mints to execute
98 | uint256 nBurn = _ids.length;
99 |
100 | // Executing all minting
101 | for (uint256 i = 0; i < nBurn; i++) {
102 | // Update storage balance
103 | balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]);
104 | }
105 |
106 | // Emit batch mint event
107 | emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
108 | }
109 |
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/typings/contracts/ERC20.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC20Interface extends Interface {
14 | functions: {
15 | transfer: TypedFunctionDescription<{
16 | encode([to, value]: [string, BigNumberish]): string;
17 | }>;
18 |
19 | approve: TypedFunctionDescription<{
20 | encode([spender, value]: [string, BigNumberish]): string;
21 | }>;
22 |
23 | transferFrom: TypedFunctionDescription<{
24 | encode([from, to, value]: [string, string, BigNumberish]): string;
25 | }>;
26 |
27 | increaseAllowance: TypedFunctionDescription<{
28 | encode([spender, addedValue]: [string, BigNumberish]): string;
29 | }>;
30 |
31 | decreaseAllowance: TypedFunctionDescription<{
32 | encode([spender, subtractedValue]: [string, BigNumberish]): string;
33 | }>;
34 | };
35 |
36 | events: {
37 | Approval: TypedEventDescription<{
38 | encodeTopics([owner, spender, value]: [
39 | string | null,
40 | string | null,
41 | null
42 | ]): string[];
43 | }>;
44 |
45 | Transfer: TypedEventDescription<{
46 | encodeTopics([from, to, value]: [
47 | string | null,
48 | string | null,
49 | null
50 | ]): string[];
51 | }>;
52 | };
53 | }
54 |
55 | export class ERC20 extends Contract {
56 | connect(signerOrProvider: Signer | Provider | string): ERC20;
57 | attach(addressOrName: string): ERC20;
58 | deployed(): Promise;
59 |
60 | on(event: EventFilter | string, listener: Listener): ERC20;
61 | once(event: EventFilter | string, listener: Listener): ERC20;
62 | addListener(eventName: EventFilter | string, listener: Listener): ERC20;
63 | removeAllListeners(eventName: EventFilter | string): ERC20;
64 | removeListener(eventName: any, listener: Listener): ERC20;
65 |
66 | interface: ERC20Interface;
67 |
68 | functions: {
69 | balanceOf(owner: string): Promise;
70 |
71 | allowance(owner: string, spender: string): Promise;
72 |
73 | transfer(
74 | to: string,
75 | value: BigNumberish,
76 | overrides?: TransactionOverrides
77 | ): Promise;
78 |
79 | approve(
80 | spender: string,
81 | value: BigNumberish,
82 | overrides?: TransactionOverrides
83 | ): Promise;
84 |
85 | transferFrom(
86 | from: string,
87 | to: string,
88 | value: BigNumberish,
89 | overrides?: TransactionOverrides
90 | ): Promise;
91 |
92 | increaseAllowance(
93 | spender: string,
94 | addedValue: BigNumberish,
95 | overrides?: TransactionOverrides
96 | ): Promise;
97 |
98 | decreaseAllowance(
99 | spender: string,
100 | subtractedValue: BigNumberish,
101 | overrides?: TransactionOverrides
102 | ): Promise;
103 |
104 | totalSupply(): Promise;
105 | };
106 |
107 | filters: {
108 | Approval(
109 | owner: string | null,
110 | spender: string | null,
111 | value: null
112 | ): EventFilter;
113 |
114 | Transfer(from: string | null, to: string | null, value: null): EventFilter;
115 | };
116 |
117 | estimate: {
118 | transfer(to: string, value: BigNumberish): Promise;
119 |
120 | approve(spender: string, value: BigNumberish): Promise;
121 |
122 | transferFrom(
123 | from: string,
124 | to: string,
125 | value: BigNumberish
126 | ): Promise;
127 |
128 | increaseAllowance(
129 | spender: string,
130 | addedValue: BigNumberish
131 | ): Promise;
132 |
133 | decreaseAllowance(
134 | spender: string,
135 | subtractedValue: BigNumberish
136 | ): Promise;
137 | };
138 | }
139 |
--------------------------------------------------------------------------------
/typings/contracts/ERC1155ReceiverMock.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155ReceiverMockInterface extends Interface {
14 | functions: {
15 | setShouldReject: TypedFunctionDescription<{
16 | encode([_value]: [boolean]): string;
17 | }>;
18 |
19 | onERC1155Received: TypedFunctionDescription<{
20 | encode([_operator, _from, _id, _value, _data]: [
21 | string,
22 | string,
23 | BigNumberish,
24 | BigNumberish,
25 | Arrayish
26 | ]): string;
27 | }>;
28 |
29 | onERC1155BatchReceived: TypedFunctionDescription<{
30 | encode([_operator, _from, _ids, _values, _data]: [
31 | string,
32 | string,
33 | (BigNumberish)[],
34 | (BigNumberish)[],
35 | Arrayish
36 | ]): string;
37 | }>;
38 | };
39 |
40 | events: {
41 | TransferBatchReceiver: TypedEventDescription<{
42 | encodeTopics([_from, _to, _fromBalances, _toBalances]: [
43 | null,
44 | null,
45 | null,
46 | null
47 | ]): string[];
48 | }>;
49 |
50 | TransferSingleReceiver: TypedEventDescription<{
51 | encodeTopics([_from, _to, _fromBalance, _toBalance]: [
52 | null,
53 | null,
54 | null,
55 | null
56 | ]): string[];
57 | }>;
58 | };
59 | }
60 |
61 | export class ERC1155ReceiverMock extends Contract {
62 | connect(signerOrProvider: Signer | Provider | string): ERC1155ReceiverMock;
63 | attach(addressOrName: string): ERC1155ReceiverMock;
64 | deployed(): Promise;
65 |
66 | on(event: EventFilter | string, listener: Listener): ERC1155ReceiverMock;
67 | once(event: EventFilter | string, listener: Listener): ERC1155ReceiverMock;
68 | addListener(
69 | eventName: EventFilter | string,
70 | listener: Listener
71 | ): ERC1155ReceiverMock;
72 | removeAllListeners(eventName: EventFilter | string): ERC1155ReceiverMock;
73 | removeListener(eventName: any, listener: Listener): ERC1155ReceiverMock;
74 |
75 | interface: ERC1155ReceiverMockInterface;
76 |
77 | functions: {
78 | supportsInterface(interfaceID: Arrayish): Promise;
79 |
80 | setShouldReject(
81 | _value: boolean,
82 | overrides?: TransactionOverrides
83 | ): Promise;
84 |
85 | onERC1155Received(
86 | _operator: string,
87 | _from: string,
88 | _id: BigNumberish,
89 | _value: BigNumberish,
90 | _data: Arrayish,
91 | overrides?: TransactionOverrides
92 | ): Promise;
93 |
94 | onERC1155BatchReceived(
95 | _operator: string,
96 | _from: string,
97 | _ids: (BigNumberish)[],
98 | _values: (BigNumberish)[],
99 | _data: Arrayish,
100 | overrides?: TransactionOverrides
101 | ): Promise;
102 |
103 | lastData(): Promise;
104 | lastId(): Promise;
105 | lastOperator(): Promise;
106 | lastValue(): Promise;
107 | shouldReject(): Promise;
108 | };
109 |
110 | filters: {
111 | TransferBatchReceiver(
112 | _from: null,
113 | _to: null,
114 | _fromBalances: null,
115 | _toBalances: null
116 | ): EventFilter;
117 |
118 | TransferSingleReceiver(
119 | _from: null,
120 | _to: null,
121 | _fromBalance: null,
122 | _toBalance: null
123 | ): EventFilter;
124 | };
125 |
126 | estimate: {
127 | setShouldReject(_value: boolean): Promise;
128 |
129 | onERC1155Received(
130 | _operator: string,
131 | _from: string,
132 | _id: BigNumberish,
133 | _value: BigNumberish,
134 | _data: Arrayish
135 | ): Promise;
136 |
137 | onERC1155BatchReceived(
138 | _operator: string,
139 | _from: string,
140 | _ids: (BigNumberish)[],
141 | _values: (BigNumberish)[],
142 | _data: Arrayish
143 | ): Promise;
144 | };
145 | }
146 |
--------------------------------------------------------------------------------
/src/tests/Ownable.spec.ts:
--------------------------------------------------------------------------------
1 | import * as ethers from 'ethers'
2 |
3 | import { AbstractContract, expect, RevertError } from './utils'
4 | import * as utils from './utils'
5 |
6 | import { OwnableMock } from 'typings/contracts/OwnableMock'
7 | import { AddressZero } from 'ethers/constants';
8 |
9 | // init test wallets from package.json mnemonic
10 | const web3 = (global as any).web3
11 |
12 | const {
13 | wallet: ownerWallet,
14 | } = utils.createTestWallet(web3, 0)
15 |
16 | const {
17 | wallet: userWallet,
18 | } = utils.createTestWallet(web3, 2)
19 |
20 | contract('Ownable Contract', (accounts: string[]) => {
21 |
22 | let ownableMockAbstract: AbstractContract
23 | let ownerOwnableMockContract: OwnableMock
24 | let userOwnableMockContract: OwnableMock
25 |
26 | // load contract abi and deploy to test server
27 | before(async () => {
28 | ownableMockAbstract = await AbstractContract.fromArtifactName('OwnableMock')
29 | })
30 |
31 | // deploy before each test, to reset state of contract
32 | beforeEach(async () => {
33 | ownerOwnableMockContract = await ownableMockAbstract.deploy(ownerWallet) as OwnableMock
34 | userOwnableMockContract = await ownerOwnableMockContract.connect(userWallet) as OwnableMock
35 | })
36 |
37 | describe('getOwner() Function', () => {
38 |
39 | it('should return current owner', async () => {
40 | const orginalOwner = await ownerOwnableMockContract.functions.getOwner()
41 | expect(orginalOwner).to.be.equal(ownerWallet.address)
42 | })
43 |
44 | })
45 |
46 | describe('ownerCall() Function', () => {
47 |
48 | it('should REVERT if called by a non-owner address', async () => {
49 |
50 | const tx = userOwnableMockContract.functions.ownerCall()
51 | await expect(tx).to.be.rejectedWith( RevertError("Ownable#onlyOwner: SENDER_IS_NOT_OWNER") )
52 | })
53 |
54 | it('should PASS if called by owner address', async () => {
55 | const tx = ownerOwnableMockContract.functions.ownerCall()
56 | await expect(tx).to.be.fulfilled
57 | })
58 |
59 | })
60 |
61 | describe('nonOwnerCall() Function', () => {
62 |
63 | it('should PASS if called by a non-owner address', async () => {
64 | const tx = userOwnableMockContract.functions.nonOwnerCall()
65 | await expect(tx).to.be.fulfilled
66 | })
67 |
68 | it('should PASS if called by owner address', async () => {
69 | const tx = ownerOwnableMockContract.functions.nonOwnerCall()
70 | await expect(tx).to.be.fulfilled
71 | })
72 | })
73 |
74 | describe('transferOwnership() Function', () => {
75 |
76 | it('should REVERT if sender is not owner', async () => {
77 | const tx = userOwnableMockContract.functions.transferOwnership(userWallet.address)
78 | await expect(tx).to.be.rejectedWith( RevertError("Ownable#onlyOwner: SENDER_IS_NOT_OWNER") )
79 | })
80 |
81 | it('should REVERT if new owner is 0x0', async () => {
82 | const tx = ownerOwnableMockContract.functions.transferOwnership(AddressZero)
83 | await expect(tx).to.be.rejectedWith( RevertError("Ownable#transferOwnership: INVALID_ADDRESS") )
84 | })
85 |
86 | it('should update owner when it passes', async () => {
87 | const oldOwner = await ownerOwnableMockContract.functions.getOwner()
88 | await ownerOwnableMockContract.functions.transferOwnership(userWallet.address)
89 | const newOwner = await ownerOwnableMockContract.functions.getOwner()
90 |
91 | expect(oldOwner).to.be.equal(ownerWallet.address)
92 | expect(newOwner).to.be.equal(userWallet.address)
93 | })
94 |
95 | context('When Ownership Transfer is Successful', () => {
96 | let tx: ethers.ContractTransaction
97 |
98 | beforeEach(async () => {
99 | tx = await ownerOwnableMockContract.functions.transferOwnership(userWallet.address)
100 | })
101 |
102 | it('should emit OwnershipTransferred event when successful', async () => {
103 | const receipt = await tx.wait(1)
104 | const ev = receipt.events!.pop()!
105 | expect(ev.event).to.be.eql('OwnershipTransferred')
106 | })
107 |
108 | it('should have old owner as `previousOwner` field', async () => {
109 | const receipt = await tx.wait(1)
110 | const ev = receipt.events!.pop()!
111 |
112 | const args = ev.args! as any
113 | expect(args.previousOwner).to.be.eql(ownerWallet.address)
114 | })
115 |
116 | it('should have new owner as `newOwner` field', async () => {
117 | const receipt = await tx.wait(1)
118 | const ev = receipt.events!.pop()!
119 |
120 | const args = ev.args! as any
121 | expect(args.newOwner).to.be.eql(userWallet.address)
122 | })
123 |
124 | })
125 |
126 | })
127 | })
--------------------------------------------------------------------------------
/contracts/tokens/ERC1155PackedBalance/ERC1155MintBurnPackedBalance.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | import "./ERC1155PackedBalance.sol";
4 |
5 |
6 | /**
7 | * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume
8 | * a parent contract to be executed as they are `internal` functions.
9 | */
10 | contract ERC1155MintBurnPackedBalance is ERC1155PackedBalance {
11 |
12 |
13 | /****************************************|
14 | | Minting Functions |
15 | |_______________________________________*/
16 |
17 | /**
18 | * @notice Mint _amount of tokens of a given id
19 | * @param _to The address to mint tokens to
20 | * @param _id Token id to mint
21 | * @param _amount The amount to be minted
22 | * @param _data Data to pass if receiver is contract
23 | */
24 | function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data)
25 | internal
26 | {
27 | //Add _amount
28 | _updateIDBalance(_to, _id, _amount, Operations.Add); // Add amount to recipient
29 |
30 | // Emit event
31 | emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);
32 |
33 | // Calling onReceive method if recipient is contract
34 | _callonERC1155Received(address(0x0), _to, _id, _amount, _data);
35 | }
36 |
37 | /**
38 | * @notice Mint tokens for each (_ids[i], _amounts[i]) pair
39 | * @param _to The address to mint tokens to
40 | * @param _ids Array of ids to mint
41 | * @param _amounts Array of amount of tokens to mint per id
42 | * @param _data Data to pass if receiver is contract
43 | */
44 | function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
45 | internal
46 | {
47 | require(_ids.length == _amounts.length, "ERC1155MintBurnPackedBalance#_batchMint: INVALID_ARRAYS_LENGTH");
48 |
49 | // Load first bin and index where the token ID balance exists
50 | (uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);
51 |
52 | // Balance for current bin in memory (initialized with first transfer)
53 | uint256 balTo = _viewUpdateIDBalance(balances[_to][bin], index, _amounts[0], Operations.Add);
54 |
55 | // Number of transfer to execute
56 | uint256 nTransfer = _ids.length;
57 |
58 | // Last bin updated
59 | uint256 lastBin = bin;
60 |
61 | for (uint256 i = 1; i < nTransfer; i++) {
62 | (bin, index) = getIDBinIndex(_ids[i]);
63 |
64 | // If new bin
65 | if (bin != lastBin) {
66 | // Update storage balance of previous bin
67 | balances[_to][lastBin] = balTo;
68 | balTo = balances[_to][bin];
69 | // Bin will be the most recent bin
70 | lastBin = bin;
71 | }
72 |
73 | // // Update memory balance
74 | balTo = _viewUpdateIDBalance(balTo, index, _amounts[i], Operations.Add);
75 | }
76 |
77 | // Update storage of the last bin visited
78 | balances[_to][bin] = balTo;
79 |
80 | // //Emit event
81 | emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);
82 |
83 | // Calling onReceive method if recipient is contract
84 | _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, _data);
85 | }
86 |
87 |
88 | /****************************************|
89 | | Burning Functions |
90 | |_______________________________________*/
91 |
92 | /**
93 | * @notice Burn _amount of tokens of a given token id
94 | * @param _from The address to burn tokens from
95 | * @param _id Token id to burn
96 | * @param _amount The amount to be burned
97 | */
98 | function _burn(address _from, uint256 _id, uint256 _amount)
99 | internal
100 | {
101 | //Substract _amount
102 | _updateIDBalance(_from, _id, _amount, Operations.Sub);
103 |
104 | // Emit event
105 | emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
106 | }
107 |
108 |
109 | // USE EFFICIENT BURN IF POSSIBLE
110 |
111 | /**
112 | * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
113 | * @param _from The address to burn tokens from
114 | * @param _ids Array of token ids to burn
115 | * @param _amounts Array of the amount to be burned
116 | */
117 | function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts)
118 | internal
119 | {
120 | require(_ids.length == _amounts.length, "ERC1155MintBurnPackedBalance#batchBurn: INVALID_ARRAYS_LENGTH");
121 |
122 | // Number of mints to execute
123 | uint256 nBurn = _ids.length;
124 |
125 | // Executing all minting
126 | for (uint256 i = 0; i < nBurn; i++) {
127 | // Update storage balance
128 | _updateIDBalance(_from, _ids[i], _amounts[i], Operations.Sub); // Add amount to recipient
129 | }
130 |
131 | // Emit batch mint event
132 | emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
133 | }
134 |
135 | }
136 |
137 |
--------------------------------------------------------------------------------
/typings/contracts/IERC1155.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface IERC1155Interface extends Interface {
14 | functions: {
15 | safeTransferFrom: TypedFunctionDescription<{
16 | encode([_from, _to, _id, _amount, _data]: [
17 | string,
18 | string,
19 | BigNumberish,
20 | BigNumberish,
21 | Arrayish
22 | ]): string;
23 | }>;
24 |
25 | safeBatchTransferFrom: TypedFunctionDescription<{
26 | encode([_from, _to, _ids, _amounts, _data]: [
27 | string,
28 | string,
29 | (BigNumberish)[],
30 | (BigNumberish)[],
31 | Arrayish
32 | ]): string;
33 | }>;
34 |
35 | setApprovalForAll: TypedFunctionDescription<{
36 | encode([_operator, _approved]: [string, boolean]): string;
37 | }>;
38 | };
39 |
40 | events: {
41 | ApprovalForAll: TypedEventDescription<{
42 | encodeTopics([_owner, _operator, _approved]: [
43 | string | null,
44 | string | null,
45 | null
46 | ]): string[];
47 | }>;
48 |
49 | TransferBatch: TypedEventDescription<{
50 | encodeTopics([_operator, _from, _to, _ids, _amounts]: [
51 | string | null,
52 | string | null,
53 | string | null,
54 | null,
55 | null
56 | ]): string[];
57 | }>;
58 |
59 | TransferSingle: TypedEventDescription<{
60 | encodeTopics([_operator, _from, _to, _id, _amount]: [
61 | string | null,
62 | string | null,
63 | string | null,
64 | null,
65 | null
66 | ]): string[];
67 | }>;
68 |
69 | URI: TypedEventDescription<{
70 | encodeTopics([_amount, _id]: [null, BigNumberish | null]): string[];
71 | }>;
72 | };
73 | }
74 |
75 | export class IERC1155 extends Contract {
76 | connect(signerOrProvider: Signer | Provider | string): IERC1155;
77 | attach(addressOrName: string): IERC1155;
78 | deployed(): Promise;
79 |
80 | on(event: EventFilter | string, listener: Listener): IERC1155;
81 | once(event: EventFilter | string, listener: Listener): IERC1155;
82 | addListener(eventName: EventFilter | string, listener: Listener): IERC1155;
83 | removeAllListeners(eventName: EventFilter | string): IERC1155;
84 | removeListener(eventName: any, listener: Listener): IERC1155;
85 |
86 | interface: IERC1155Interface;
87 |
88 | functions: {
89 | balanceOf(_owner: string, _id: BigNumberish): Promise;
90 |
91 | balanceOfBatch(
92 | _owners: (string)[],
93 | _ids: (BigNumberish)[]
94 | ): Promise<(BigNumber)[]>;
95 |
96 | isApprovedForAll(_owner: string, _operator: string): Promise;
97 |
98 | safeTransferFrom(
99 | _from: string,
100 | _to: string,
101 | _id: BigNumberish,
102 | _amount: BigNumberish,
103 | _data: Arrayish,
104 | overrides?: TransactionOverrides
105 | ): Promise;
106 |
107 | safeBatchTransferFrom(
108 | _from: string,
109 | _to: string,
110 | _ids: (BigNumberish)[],
111 | _amounts: (BigNumberish)[],
112 | _data: Arrayish,
113 | overrides?: TransactionOverrides
114 | ): Promise;
115 |
116 | setApprovalForAll(
117 | _operator: string,
118 | _approved: boolean,
119 | overrides?: TransactionOverrides
120 | ): Promise;
121 | };
122 |
123 | filters: {
124 | ApprovalForAll(
125 | _owner: string | null,
126 | _operator: string | null,
127 | _approved: null
128 | ): EventFilter;
129 |
130 | TransferBatch(
131 | _operator: string | null,
132 | _from: string | null,
133 | _to: string | null,
134 | _ids: null,
135 | _amounts: null
136 | ): EventFilter;
137 |
138 | TransferSingle(
139 | _operator: string | null,
140 | _from: string | null,
141 | _to: string | null,
142 | _id: null,
143 | _amount: null
144 | ): EventFilter;
145 |
146 | URI(_amount: null, _id: BigNumberish | null): EventFilter;
147 | };
148 |
149 | estimate: {
150 | safeTransferFrom(
151 | _from: string,
152 | _to: string,
153 | _id: BigNumberish,
154 | _amount: BigNumberish,
155 | _data: Arrayish
156 | ): Promise;
157 |
158 | safeBatchTransferFrom(
159 | _from: string,
160 | _to: string,
161 | _ids: (BigNumberish)[],
162 | _amounts: (BigNumberish)[],
163 | _data: Arrayish
164 | ): Promise;
165 |
166 | setApprovalForAll(
167 | _operator: string,
168 | _approved: boolean
169 | ): Promise;
170 | };
171 | }
172 |
--------------------------------------------------------------------------------
/typings/contracts/ERC1155.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155Interface extends Interface {
14 | functions: {
15 | safeTransferFrom: TypedFunctionDescription<{
16 | encode([_from, _to, _id, _amount, _data]: [
17 | string,
18 | string,
19 | BigNumberish,
20 | BigNumberish,
21 | Arrayish
22 | ]): string;
23 | }>;
24 |
25 | safeBatchTransferFrom: TypedFunctionDescription<{
26 | encode([_from, _to, _ids, _amounts, _data]: [
27 | string,
28 | string,
29 | (BigNumberish)[],
30 | (BigNumberish)[],
31 | Arrayish
32 | ]): string;
33 | }>;
34 |
35 | setApprovalForAll: TypedFunctionDescription<{
36 | encode([_operator, _approved]: [string, boolean]): string;
37 | }>;
38 | };
39 |
40 | events: {
41 | ApprovalForAll: TypedEventDescription<{
42 | encodeTopics([_owner, _operator, _approved]: [
43 | string | null,
44 | string | null,
45 | null
46 | ]): string[];
47 | }>;
48 |
49 | TransferBatch: TypedEventDescription<{
50 | encodeTopics([_operator, _from, _to, _ids, _amounts]: [
51 | string | null,
52 | string | null,
53 | string | null,
54 | null,
55 | null
56 | ]): string[];
57 | }>;
58 |
59 | TransferSingle: TypedEventDescription<{
60 | encodeTopics([_operator, _from, _to, _id, _amount]: [
61 | string | null,
62 | string | null,
63 | string | null,
64 | null,
65 | null
66 | ]): string[];
67 | }>;
68 |
69 | URI: TypedEventDescription<{
70 | encodeTopics([_uri, _id]: [null, BigNumberish | null]): string[];
71 | }>;
72 | };
73 | }
74 |
75 | export class ERC1155 extends Contract {
76 | connect(signerOrProvider: Signer | Provider | string): ERC1155;
77 | attach(addressOrName: string): ERC1155;
78 | deployed(): Promise;
79 |
80 | on(event: EventFilter | string, listener: Listener): ERC1155;
81 | once(event: EventFilter | string, listener: Listener): ERC1155;
82 | addListener(eventName: EventFilter | string, listener: Listener): ERC1155;
83 | removeAllListeners(eventName: EventFilter | string): ERC1155;
84 | removeListener(eventName: any, listener: Listener): ERC1155;
85 |
86 | interface: ERC1155Interface;
87 |
88 | functions: {
89 | isApprovedForAll(_owner: string, _operator: string): Promise;
90 |
91 | balanceOf(_owner: string, _id: BigNumberish): Promise;
92 |
93 | balanceOfBatch(
94 | _owners: (string)[],
95 | _ids: (BigNumberish)[]
96 | ): Promise<(BigNumber)[]>;
97 |
98 | supportsInterface(_interfaceID: Arrayish): Promise;
99 |
100 | safeTransferFrom(
101 | _from: string,
102 | _to: string,
103 | _id: BigNumberish,
104 | _amount: BigNumberish,
105 | _data: Arrayish,
106 | overrides?: TransactionOverrides
107 | ): Promise;
108 |
109 | safeBatchTransferFrom(
110 | _from: string,
111 | _to: string,
112 | _ids: (BigNumberish)[],
113 | _amounts: (BigNumberish)[],
114 | _data: Arrayish,
115 | overrides?: TransactionOverrides
116 | ): Promise;
117 |
118 | setApprovalForAll(
119 | _operator: string,
120 | _approved: boolean,
121 | overrides?: TransactionOverrides
122 | ): Promise;
123 | };
124 |
125 | filters: {
126 | ApprovalForAll(
127 | _owner: string | null,
128 | _operator: string | null,
129 | _approved: null
130 | ): EventFilter;
131 |
132 | TransferBatch(
133 | _operator: string | null,
134 | _from: string | null,
135 | _to: string | null,
136 | _ids: null,
137 | _amounts: null
138 | ): EventFilter;
139 |
140 | TransferSingle(
141 | _operator: string | null,
142 | _from: string | null,
143 | _to: string | null,
144 | _id: null,
145 | _amount: null
146 | ): EventFilter;
147 |
148 | URI(_uri: null, _id: BigNumberish | null): EventFilter;
149 | };
150 |
151 | estimate: {
152 | safeTransferFrom(
153 | _from: string,
154 | _to: string,
155 | _id: BigNumberish,
156 | _amount: BigNumberish,
157 | _data: Arrayish
158 | ): Promise;
159 |
160 | safeBatchTransferFrom(
161 | _from: string,
162 | _to: string,
163 | _ids: (BigNumberish)[],
164 | _amounts: (BigNumberish)[],
165 | _data: Arrayish
166 | ): Promise;
167 |
168 | setApprovalForAll(
169 | _operator: string,
170 | _approved: boolean
171 | ): Promise;
172 | };
173 | }
174 |
--------------------------------------------------------------------------------
/typings/contracts/ERC1155MintBurn.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155MintBurnInterface extends Interface {
14 | functions: {
15 | safeBatchTransferFrom: TypedFunctionDescription<{
16 | encode([_from, _to, _ids, _amounts, _data]: [
17 | string,
18 | string,
19 | (BigNumberish)[],
20 | (BigNumberish)[],
21 | Arrayish
22 | ]): string;
23 | }>;
24 |
25 | safeTransferFrom: TypedFunctionDescription<{
26 | encode([_from, _to, _id, _amount, _data]: [
27 | string,
28 | string,
29 | BigNumberish,
30 | BigNumberish,
31 | Arrayish
32 | ]): string;
33 | }>;
34 |
35 | setApprovalForAll: TypedFunctionDescription<{
36 | encode([_operator, _approved]: [string, boolean]): string;
37 | }>;
38 | };
39 |
40 | events: {
41 | ApprovalForAll: TypedEventDescription<{
42 | encodeTopics([_owner, _operator, _approved]: [
43 | string | null,
44 | string | null,
45 | null
46 | ]): string[];
47 | }>;
48 |
49 | TransferBatch: TypedEventDescription<{
50 | encodeTopics([_operator, _from, _to, _ids, _amounts]: [
51 | string | null,
52 | string | null,
53 | string | null,
54 | null,
55 | null
56 | ]): string[];
57 | }>;
58 |
59 | TransferSingle: TypedEventDescription<{
60 | encodeTopics([_operator, _from, _to, _id, _amount]: [
61 | string | null,
62 | string | null,
63 | string | null,
64 | null,
65 | null
66 | ]): string[];
67 | }>;
68 |
69 | URI: TypedEventDescription<{
70 | encodeTopics([_uri, _id]: [null, BigNumberish | null]): string[];
71 | }>;
72 | };
73 | }
74 |
75 | export class ERC1155MintBurn extends Contract {
76 | connect(signerOrProvider: Signer | Provider | string): ERC1155MintBurn;
77 | attach(addressOrName: string): ERC1155MintBurn;
78 | deployed(): Promise;
79 |
80 | on(event: EventFilter | string, listener: Listener): ERC1155MintBurn;
81 | once(event: EventFilter | string, listener: Listener): ERC1155MintBurn;
82 | addListener(
83 | eventName: EventFilter | string,
84 | listener: Listener
85 | ): ERC1155MintBurn;
86 | removeAllListeners(eventName: EventFilter | string): ERC1155MintBurn;
87 | removeListener(eventName: any, listener: Listener): ERC1155MintBurn;
88 |
89 | interface: ERC1155MintBurnInterface;
90 |
91 | functions: {
92 | balanceOf(_owner: string, _id: BigNumberish): Promise;
93 |
94 | balanceOfBatch(
95 | _owners: (string)[],
96 | _ids: (BigNumberish)[]
97 | ): Promise<(BigNumber)[]>;
98 |
99 | isApprovedForAll(_owner: string, _operator: string): Promise;
100 |
101 | supportsInterface(_interfaceID: Arrayish): Promise;
102 |
103 | safeBatchTransferFrom(
104 | _from: string,
105 | _to: string,
106 | _ids: (BigNumberish)[],
107 | _amounts: (BigNumberish)[],
108 | _data: Arrayish,
109 | overrides?: TransactionOverrides
110 | ): Promise;
111 |
112 | safeTransferFrom(
113 | _from: string,
114 | _to: string,
115 | _id: BigNumberish,
116 | _amount: BigNumberish,
117 | _data: Arrayish,
118 | overrides?: TransactionOverrides
119 | ): Promise;
120 |
121 | setApprovalForAll(
122 | _operator: string,
123 | _approved: boolean,
124 | overrides?: TransactionOverrides
125 | ): Promise;
126 | };
127 |
128 | filters: {
129 | ApprovalForAll(
130 | _owner: string | null,
131 | _operator: string | null,
132 | _approved: null
133 | ): EventFilter;
134 |
135 | TransferBatch(
136 | _operator: string | null,
137 | _from: string | null,
138 | _to: string | null,
139 | _ids: null,
140 | _amounts: null
141 | ): EventFilter;
142 |
143 | TransferSingle(
144 | _operator: string | null,
145 | _from: string | null,
146 | _to: string | null,
147 | _id: null,
148 | _amount: null
149 | ): EventFilter;
150 |
151 | URI(_uri: null, _id: BigNumberish | null): EventFilter;
152 | };
153 |
154 | estimate: {
155 | safeBatchTransferFrom(
156 | _from: string,
157 | _to: string,
158 | _ids: (BigNumberish)[],
159 | _amounts: (BigNumberish)[],
160 | _data: Arrayish
161 | ): Promise;
162 |
163 | safeTransferFrom(
164 | _from: string,
165 | _to: string,
166 | _id: BigNumberish,
167 | _amount: BigNumberish,
168 | _data: Arrayish
169 | ): Promise;
170 |
171 | setApprovalForAll(
172 | _operator: string,
173 | _approved: boolean
174 | ): Promise;
175 | };
176 | }
177 |
--------------------------------------------------------------------------------
/typings/contracts/ERC20Mock.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC20MockInterface extends Interface {
14 | functions: {
15 | approve: TypedFunctionDescription<{
16 | encode([spender, value]: [string, BigNumberish]): string;
17 | }>;
18 |
19 | decreaseAllowance: TypedFunctionDescription<{
20 | encode([spender, subtractedValue]: [string, BigNumberish]): string;
21 | }>;
22 |
23 | increaseAllowance: TypedFunctionDescription<{
24 | encode([spender, addedValue]: [string, BigNumberish]): string;
25 | }>;
26 |
27 | transfer: TypedFunctionDescription<{
28 | encode([to, value]: [string, BigNumberish]): string;
29 | }>;
30 |
31 | transferFrom: TypedFunctionDescription<{
32 | encode([from, to, value]: [string, string, BigNumberish]): string;
33 | }>;
34 |
35 | mockMint: TypedFunctionDescription<{
36 | encode([_address, _amount]: [string, BigNumberish]): string;
37 | }>;
38 |
39 | batchTransfer: TypedFunctionDescription<{
40 | encode([_tokens, _to, _amounts]: [
41 | (string)[],
42 | string,
43 | (BigNumberish)[]
44 | ]): string;
45 | }>;
46 | };
47 |
48 | events: {
49 | Approval: TypedEventDescription<{
50 | encodeTopics([owner, spender, value]: [
51 | string | null,
52 | string | null,
53 | null
54 | ]): string[];
55 | }>;
56 |
57 | Transfer: TypedEventDescription<{
58 | encodeTopics([from, to, value]: [
59 | string | null,
60 | string | null,
61 | null
62 | ]): string[];
63 | }>;
64 | };
65 | }
66 |
67 | export class ERC20Mock extends Contract {
68 | connect(signerOrProvider: Signer | Provider | string): ERC20Mock;
69 | attach(addressOrName: string): ERC20Mock;
70 | deployed(): Promise;
71 |
72 | on(event: EventFilter | string, listener: Listener): ERC20Mock;
73 | once(event: EventFilter | string, listener: Listener): ERC20Mock;
74 | addListener(eventName: EventFilter | string, listener: Listener): ERC20Mock;
75 | removeAllListeners(eventName: EventFilter | string): ERC20Mock;
76 | removeListener(eventName: any, listener: Listener): ERC20Mock;
77 |
78 | interface: ERC20MockInterface;
79 |
80 | functions: {
81 | allowance(owner: string, spender: string): Promise;
82 |
83 | balanceOf(owner: string): Promise;
84 |
85 | approve(
86 | spender: string,
87 | value: BigNumberish,
88 | overrides?: TransactionOverrides
89 | ): Promise;
90 |
91 | decreaseAllowance(
92 | spender: string,
93 | subtractedValue: BigNumberish,
94 | overrides?: TransactionOverrides
95 | ): Promise;
96 |
97 | increaseAllowance(
98 | spender: string,
99 | addedValue: BigNumberish,
100 | overrides?: TransactionOverrides
101 | ): Promise;
102 |
103 | transfer(
104 | to: string,
105 | value: BigNumberish,
106 | overrides?: TransactionOverrides
107 | ): Promise;
108 |
109 | transferFrom(
110 | from: string,
111 | to: string,
112 | value: BigNumberish,
113 | overrides?: TransactionOverrides
114 | ): Promise;
115 |
116 | mockMint(
117 | _address: string,
118 | _amount: BigNumberish,
119 | overrides?: TransactionOverrides
120 | ): Promise;
121 |
122 | batchTransfer(
123 | _tokens: (string)[],
124 | _to: string,
125 | _amounts: (BigNumberish)[],
126 | overrides?: TransactionOverrides
127 | ): Promise;
128 |
129 | totalSupply(): Promise;
130 | };
131 |
132 | filters: {
133 | Approval(
134 | owner: string | null,
135 | spender: string | null,
136 | value: null
137 | ): EventFilter;
138 |
139 | Transfer(from: string | null, to: string | null, value: null): EventFilter;
140 | };
141 |
142 | estimate: {
143 | approve(spender: string, value: BigNumberish): Promise;
144 |
145 | decreaseAllowance(
146 | spender: string,
147 | subtractedValue: BigNumberish
148 | ): Promise;
149 |
150 | increaseAllowance(
151 | spender: string,
152 | addedValue: BigNumberish
153 | ): Promise;
154 |
155 | transfer(to: string, value: BigNumberish): Promise;
156 |
157 | transferFrom(
158 | from: string,
159 | to: string,
160 | value: BigNumberish
161 | ): Promise;
162 |
163 | mockMint(_address: string, _amount: BigNumberish): Promise;
164 |
165 | batchTransfer(
166 | _tokens: (string)[],
167 | _to: string,
168 | _amounts: (BigNumberish)[]
169 | ): Promise;
170 | };
171 | }
172 |
--------------------------------------------------------------------------------
/contracts/utils/SignatureValidator.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | import "../interfaces/IERC1271Wallet.sol";
4 | import "./LibBytes.sol";
5 | import "./LibEIP712.sol";
6 |
7 | /**
8 | * @dev Contains logic for signature validation.
9 | * Signatures from wallet contracts assume ERC-1271 support (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1271.md)
10 | * Notes: Methods are strongly inspired by contracts in https://github.com/0xProject/0x-monorepo/blob/development/
11 | */
12 | contract SignatureValidator is LibEIP712 {
13 | using LibBytes for bytes;
14 |
15 | /***********************************|
16 | | Variables |
17 | |__________________________________*/
18 |
19 |
20 | // bytes4(keccak256("isValidSignature(bytes,bytes)")
21 | bytes4 constant internal ERC1271_MAGICVALUE = 0x20c13b0b;
22 |
23 | // Allowed signature types.
24 | enum SignatureType {
25 | Illegal, // 0x00, default value
26 | EIP712, // 0x01
27 | EthSign, // 0x02
28 | WalletBytes, // 0x03 To call isValidSignature(bytes, bytes) on wallet contract
29 | WalletBytes32, // 0x04 To call isValidSignature(bytes32, bytes) on wallet contract
30 | NSignatureTypes // 0x05, number of signature types. Always leave at end.
31 | }
32 |
33 |
34 | /***********************************|
35 | | Signature Functions |
36 | |__________________________________*/
37 |
38 | /**
39 | * @dev Verifies that a hash has been signed by the given signer.
40 | * @param _signerAddress Address that should have signed the given hash.
41 | * @param _hash Hash of the EIP-712 encoded data
42 | * @param _data Full EIP-712 data structure that was hashed and signed
43 | * @param _sig Proof that the hash has been signed by signer.
44 | * @return True if the address recovered from the provided signature matches the input signer address.
45 | */
46 | function isValidSignature(
47 | address _signerAddress,
48 | bytes32 _hash,
49 | bytes memory _data,
50 | bytes memory _sig
51 | )
52 | public
53 | view
54 | returns (bool isValid)
55 | {
56 | require(
57 | _sig.length > 0,
58 | "SignatureValidator#isValidSignature: LENGTH_GREATER_THAN_0_REQUIRED"
59 | );
60 |
61 | require(
62 | _signerAddress != address(0x0),
63 | "SignatureValidator#isValidSignature: INVALID_SIGNER"
64 | );
65 |
66 | // Pop last byte off of signature byte array.
67 | uint8 signatureTypeRaw = uint8(_sig.popLastByte());
68 |
69 | // Ensure signature is supported
70 | require(
71 | signatureTypeRaw < uint8(SignatureType.NSignatureTypes),
72 | "SignatureValidator#isValidSignature: UNSUPPORTED_SIGNATURE"
73 | );
74 |
75 | // Extract signature type
76 | SignatureType signatureType = SignatureType(signatureTypeRaw);
77 |
78 | // Variables are not scoped in Solidity.
79 | uint8 v;
80 | bytes32 r;
81 | bytes32 s;
82 | address recovered;
83 |
84 | // Always illegal signature.
85 | // This is always an implicit option since a signer can create a
86 | // signature array with invalid type or length. We may as well make
87 | // it an explicit option. This aids testing and analysis. It is
88 | // also the initialization value for the enum type.
89 | if (signatureType == SignatureType.Illegal) {
90 | revert("SignatureValidator#isValidSignature: ILLEGAL_SIGNATURE");
91 |
92 |
93 | // Signature using EIP712
94 | } else if (signatureType == SignatureType.EIP712) {
95 | require(
96 | _sig.length == 65,
97 | "SignatureValidator#isValidSignature: LENGTH_65_REQUIRED"
98 | );
99 | r = _sig.readBytes32(0);
100 | s = _sig.readBytes32(32);
101 | v = uint8(_sig[64]);
102 | recovered = ecrecover(_hash, v, r, s);
103 | isValid = _signerAddress == recovered;
104 | return isValid;
105 |
106 |
107 | // Signed using web3.eth_sign
108 | } else if (signatureType == SignatureType.EthSign) {
109 | require(
110 | _sig.length == 65,
111 | "SignatureValidator#isValidSignature: LENGTH_65_REQUIRED"
112 | );
113 | r = _sig.readBytes32(0);
114 | s = _sig.readBytes32(32);
115 | v = uint8(_sig[64]);
116 | recovered = ecrecover(
117 | keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)),
118 | v,
119 | r,
120 | s
121 | );
122 | isValid = _signerAddress == recovered;
123 | return isValid;
124 |
125 |
126 | // Signature verified by wallet contract with data validation.
127 | } else if (signatureType == SignatureType.WalletBytes) {
128 | isValid = ERC1271_MAGICVALUE == IERC1271Wallet(_signerAddress).isValidSignature(_data, _sig);
129 | return isValid;
130 |
131 |
132 | // Signature verified by wallet contract without data validation.
133 | } else if (signatureType == SignatureType.WalletBytes32) {
134 | isValid = ERC1271_MAGICVALUE == IERC1271Wallet(_signerAddress).isValidSignature(_hash, _sig);
135 | return isValid;
136 | }
137 |
138 | // Anything else is illegal (We do not return false because
139 | // the signature may actually be valid, just not in a format
140 | // that we currently support. In this case returning false
141 | // may lead the caller to incorrectly believe that the
142 | // signature was invalid.)
143 | revert("SignatureValidator#isValidSignature: UNSUPPORTED_SIGNATURE");
144 | }
145 |
146 | }
--------------------------------------------------------------------------------
/typings/contracts/ERC1155PackedBalance.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155PackedBalanceInterface extends Interface {
14 | functions: {
15 | safeTransferFrom: TypedFunctionDescription<{
16 | encode([_from, _to, _id, _amount, _data]: [
17 | string,
18 | string,
19 | BigNumberish,
20 | BigNumberish,
21 | Arrayish
22 | ]): string;
23 | }>;
24 |
25 | safeBatchTransferFrom: TypedFunctionDescription<{
26 | encode([_from, _to, _ids, _amounts, _data]: [
27 | string,
28 | string,
29 | (BigNumberish)[],
30 | (BigNumberish)[],
31 | Arrayish
32 | ]): string;
33 | }>;
34 |
35 | setApprovalForAll: TypedFunctionDescription<{
36 | encode([_operator, _approved]: [string, boolean]): string;
37 | }>;
38 | };
39 |
40 | events: {
41 | ApprovalForAll: TypedEventDescription<{
42 | encodeTopics([_owner, _operator, _approved]: [
43 | string | null,
44 | string | null,
45 | null
46 | ]): string[];
47 | }>;
48 |
49 | TransferBatch: TypedEventDescription<{
50 | encodeTopics([_operator, _from, _to, _ids, _amounts]: [
51 | string | null,
52 | string | null,
53 | string | null,
54 | null,
55 | null
56 | ]): string[];
57 | }>;
58 |
59 | TransferSingle: TypedEventDescription<{
60 | encodeTopics([_operator, _from, _to, _id, _amount]: [
61 | string | null,
62 | string | null,
63 | string | null,
64 | null,
65 | null
66 | ]): string[];
67 | }>;
68 |
69 | URI: TypedEventDescription<{
70 | encodeTopics([_uri, _id]: [null, BigNumberish | null]): string[];
71 | }>;
72 | };
73 | }
74 |
75 | export class ERC1155PackedBalance extends Contract {
76 | connect(signerOrProvider: Signer | Provider | string): ERC1155PackedBalance;
77 | attach(addressOrName: string): ERC1155PackedBalance;
78 | deployed(): Promise;
79 |
80 | on(event: EventFilter | string, listener: Listener): ERC1155PackedBalance;
81 | once(event: EventFilter | string, listener: Listener): ERC1155PackedBalance;
82 | addListener(
83 | eventName: EventFilter | string,
84 | listener: Listener
85 | ): ERC1155PackedBalance;
86 | removeAllListeners(eventName: EventFilter | string): ERC1155PackedBalance;
87 | removeListener(eventName: any, listener: Listener): ERC1155PackedBalance;
88 |
89 | interface: ERC1155PackedBalanceInterface;
90 |
91 | functions: {
92 | isApprovedForAll(_owner: string, _operator: string): Promise;
93 |
94 | balanceOf(_owner: string, _id: BigNumberish): Promise;
95 |
96 | balanceOfBatch(
97 | _owners: (string)[],
98 | _ids: (BigNumberish)[]
99 | ): Promise<(BigNumber)[]>;
100 |
101 | getIDBinIndex(
102 | _id: BigNumberish
103 | ): Promise<{
104 | bin: BigNumber;
105 | index: BigNumber;
106 | 0: BigNumber;
107 | 1: BigNumber;
108 | }>;
109 |
110 | getValueInBin(
111 | _binAmount: BigNumberish,
112 | _index: BigNumberish
113 | ): Promise;
114 |
115 | supportsInterface(_interfaceID: Arrayish): Promise;
116 |
117 | safeTransferFrom(
118 | _from: string,
119 | _to: string,
120 | _id: BigNumberish,
121 | _amount: BigNumberish,
122 | _data: Arrayish,
123 | overrides?: TransactionOverrides
124 | ): Promise;
125 |
126 | safeBatchTransferFrom(
127 | _from: string,
128 | _to: string,
129 | _ids: (BigNumberish)[],
130 | _amounts: (BigNumberish)[],
131 | _data: Arrayish,
132 | overrides?: TransactionOverrides
133 | ): Promise;
134 |
135 | setApprovalForAll(
136 | _operator: string,
137 | _approved: boolean,
138 | overrides?: TransactionOverrides
139 | ): Promise;
140 | };
141 |
142 | filters: {
143 | ApprovalForAll(
144 | _owner: string | null,
145 | _operator: string | null,
146 | _approved: null
147 | ): EventFilter;
148 |
149 | TransferBatch(
150 | _operator: string | null,
151 | _from: string | null,
152 | _to: string | null,
153 | _ids: null,
154 | _amounts: null
155 | ): EventFilter;
156 |
157 | TransferSingle(
158 | _operator: string | null,
159 | _from: string | null,
160 | _to: string | null,
161 | _id: null,
162 | _amount: null
163 | ): EventFilter;
164 |
165 | URI(_uri: null, _id: BigNumberish | null): EventFilter;
166 | };
167 |
168 | estimate: {
169 | safeTransferFrom(
170 | _from: string,
171 | _to: string,
172 | _id: BigNumberish,
173 | _amount: BigNumberish,
174 | _data: Arrayish
175 | ): Promise;
176 |
177 | safeBatchTransferFrom(
178 | _from: string,
179 | _to: string,
180 | _ids: (BigNumberish)[],
181 | _amounts: (BigNumberish)[],
182 | _data: Arrayish
183 | ): Promise;
184 |
185 | setApprovalForAll(
186 | _operator: string,
187 | _approved: boolean
188 | ): Promise;
189 | };
190 | }
191 |
--------------------------------------------------------------------------------
/src/tests/utils/contract.ts:
--------------------------------------------------------------------------------
1 | // Build ethers.Contract instances from ABI JSON files generated by truffle.
2 | //
3 | // adapted this utility from the handy work by the counterfactual team at:
4 | // https://github.com/counterfactual/monorepo/blob/d9be8524a691c45b6aac1b5e1cf2ff81059203df/packages/contracts/utils/contract.ts
5 |
6 | import * as ethers from 'ethers'
7 |
8 | interface NetworkMapping {
9 | [networkId: number]: { address: string }
10 | }
11 |
12 | interface BuildArtifact {
13 | readonly contractName: string
14 | readonly abi: any[]
15 | readonly bytecode: string
16 | readonly networks: NetworkMapping
17 | }
18 |
19 | /**
20 | * Convenience class for an undeployed contract i.e. only the ABI and bytecode.
21 | */
22 | export class AbstractContract {
23 | /**
24 | * Load build artifact by name into an abstract contract
25 | * @example
26 | * const CountingApp = AbstractContract.fromArtifactName("CountingApp", { StaticCall })
27 | * @param artifactName The name of the artifact to load
28 | * @param links Optional AbstractContract libraries to link.
29 | * @returns Truffle artifact wrapped in an AbstractContract.
30 | */
31 | public static async fromArtifactName(
32 | artifactName: string,
33 | links?: { [name: string]: Promise }
34 | ): Promise {
35 | // these ABI JSON files are generated by truffle
36 | const contract: BuildArtifact = await import(`../../build/contracts/${artifactName}.json`)
37 | return AbstractContract.fromBuildArtifact(contract, links, artifactName)
38 | }
39 |
40 | /**
41 | * Wrap build artifact in abstract contract
42 | * @param buildArtifact Truffle contract to wrap
43 | * @param links Optional AbstractContract libraries to link.
44 | * @returns Truffle artifact wrapped in an AbstractContract.
45 | */
46 | public static async fromBuildArtifact(
47 | buildArtifact: BuildArtifact,
48 | links?: { [name: string]: Promise },
49 | artifactName: string = 'UntitledContract'
50 | ): Promise {
51 | return new AbstractContract(
52 | buildArtifact.abi,
53 | buildArtifact.bytecode,
54 | buildArtifact.networks,
55 | links,
56 | artifactName
57 | )
58 | }
59 |
60 | public static async getNetworkID(wallet: ethers.Wallet): Promise {
61 | return (await wallet.provider.getNetwork()).chainId
62 | }
63 |
64 | /**
65 | * @param abi ABI of the abstract contract
66 | * @param bytecode Binary of the abstract contract
67 | * @param networks Network mapping of deployed addresses
68 | * @param links
69 | * @param contractName
70 | */
71 | constructor(
72 | readonly abi: string[] | string,
73 | readonly bytecode: string,
74 | readonly networks: NetworkMapping,
75 | readonly links?: { [contractName: string]: Promise },
76 | readonly contractName?: string
77 | ) {}
78 |
79 | /**
80 | * Get the deployed singleton instance of this abstract contract, if it exists
81 | * @param Signer (with provider) to use for contract calls
82 | * @throws Error if AbstractContract has no deployed address
83 | */
84 | public async getDeployed(wallet: ethers.Wallet): Promise {
85 | if (!wallet.provider) {
86 | throw new Error('Signer requires provider')
87 | }
88 | const networkId = (await wallet.provider.getNetwork()).chainId
89 | const address = this.getDeployedAddress(networkId)
90 | return new ethers.Contract(address, this.abi, wallet)
91 | }
92 |
93 | /**
94 | * Deploy new instance of contract
95 | * @param wallet Wallet (with provider) to use for contract calls
96 | * @param args Optional arguments to pass to contract constructor
97 | * @returns New contract instance
98 | */
99 | public async deploy(wallet: ethers.Wallet, args?: any[]): Promise {
100 | if (!wallet.provider) {
101 | throw new Error('Signer requires provider')
102 | }
103 |
104 | const networkId = (await wallet.provider.getNetwork()).chainId
105 | const bytecode = (await this.links)
106 | ? await this.generateLinkedBytecode(networkId)
107 | : this.bytecode
108 | const contractFactory = new ethers.ContractFactory(
109 | this.abi,
110 | bytecode,
111 | wallet
112 | )
113 | return contractFactory.deploy(...(args || []))
114 | }
115 |
116 | /**
117 | * Connect to a deployed instance of this abstract contract
118 | * @param signer Signer (with provider) to use for contract calls
119 | * @param address Address of deployed instance to connect to
120 | * @returns Contract instance
121 | */
122 | public async connect(
123 | signer: ethers.Signer,
124 | address: string
125 | ): Promise {
126 | return new ethers.Contract(address, this.abi, signer)
127 | }
128 |
129 | public getDeployedAddress(networkId: number): string {
130 | const info = this.networks[networkId]
131 | if (!info) {
132 | throw new Error(
133 | `Abstract contract ${
134 | this.contractName
135 | } not deployed on network ${networkId}`
136 | )
137 | }
138 | return info.address
139 | }
140 |
141 | public async generateLinkedBytecode(networkId: number): Promise {
142 | if (this.links === undefined) {
143 | throw new Error('Nothing to link')
144 | }
145 | let bytecode = this.bytecode
146 | for (const name of Object.keys(this.links)) {
147 | const library = this.links[name]
148 | const regex = new RegExp(`__${name}_+`, 'g')
149 | const address = (await library).getDeployedAddress(networkId)
150 | const addressHex = address.replace('0x', '')
151 | bytecode = bytecode.replace(regex, addressHex)
152 | }
153 | return bytecode
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/typings/contracts/ERC1155MintBurnPackedBalance.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155MintBurnPackedBalanceInterface extends Interface {
14 | functions: {
15 | safeBatchTransferFrom: TypedFunctionDescription<{
16 | encode([_from, _to, _ids, _amounts, _data]: [
17 | string,
18 | string,
19 | (BigNumberish)[],
20 | (BigNumberish)[],
21 | Arrayish
22 | ]): string;
23 | }>;
24 |
25 | safeTransferFrom: TypedFunctionDescription<{
26 | encode([_from, _to, _id, _amount, _data]: [
27 | string,
28 | string,
29 | BigNumberish,
30 | BigNumberish,
31 | Arrayish
32 | ]): string;
33 | }>;
34 |
35 | setApprovalForAll: TypedFunctionDescription<{
36 | encode([_operator, _approved]: [string, boolean]): string;
37 | }>;
38 | };
39 |
40 | events: {
41 | ApprovalForAll: TypedEventDescription<{
42 | encodeTopics([_owner, _operator, _approved]: [
43 | string | null,
44 | string | null,
45 | null
46 | ]): string[];
47 | }>;
48 |
49 | TransferBatch: TypedEventDescription<{
50 | encodeTopics([_operator, _from, _to, _ids, _amounts]: [
51 | string | null,
52 | string | null,
53 | string | null,
54 | null,
55 | null
56 | ]): string[];
57 | }>;
58 |
59 | TransferSingle: TypedEventDescription<{
60 | encodeTopics([_operator, _from, _to, _id, _amount]: [
61 | string | null,
62 | string | null,
63 | string | null,
64 | null,
65 | null
66 | ]): string[];
67 | }>;
68 |
69 | URI: TypedEventDescription<{
70 | encodeTopics([_uri, _id]: [null, BigNumberish | null]): string[];
71 | }>;
72 | };
73 | }
74 |
75 | export class ERC1155MintBurnPackedBalance extends Contract {
76 | connect(
77 | signerOrProvider: Signer | Provider | string
78 | ): ERC1155MintBurnPackedBalance;
79 | attach(addressOrName: string): ERC1155MintBurnPackedBalance;
80 | deployed(): Promise;
81 |
82 | on(
83 | event: EventFilter | string,
84 | listener: Listener
85 | ): ERC1155MintBurnPackedBalance;
86 | once(
87 | event: EventFilter | string,
88 | listener: Listener
89 | ): ERC1155MintBurnPackedBalance;
90 | addListener(
91 | eventName: EventFilter | string,
92 | listener: Listener
93 | ): ERC1155MintBurnPackedBalance;
94 | removeAllListeners(
95 | eventName: EventFilter | string
96 | ): ERC1155MintBurnPackedBalance;
97 | removeListener(
98 | eventName: any,
99 | listener: Listener
100 | ): ERC1155MintBurnPackedBalance;
101 |
102 | interface: ERC1155MintBurnPackedBalanceInterface;
103 |
104 | functions: {
105 | balanceOf(_owner: string, _id: BigNumberish): Promise;
106 |
107 | balanceOfBatch(
108 | _owners: (string)[],
109 | _ids: (BigNumberish)[]
110 | ): Promise<(BigNumber)[]>;
111 |
112 | getIDBinIndex(
113 | _id: BigNumberish
114 | ): Promise<{
115 | bin: BigNumber;
116 | index: BigNumber;
117 | 0: BigNumber;
118 | 1: BigNumber;
119 | }>;
120 |
121 | getValueInBin(
122 | _binAmount: BigNumberish,
123 | _index: BigNumberish
124 | ): Promise;
125 |
126 | isApprovedForAll(_owner: string, _operator: string): Promise;
127 |
128 | supportsInterface(_interfaceID: Arrayish): Promise;
129 |
130 | safeBatchTransferFrom(
131 | _from: string,
132 | _to: string,
133 | _ids: (BigNumberish)[],
134 | _amounts: (BigNumberish)[],
135 | _data: Arrayish,
136 | overrides?: TransactionOverrides
137 | ): Promise;
138 |
139 | safeTransferFrom(
140 | _from: string,
141 | _to: string,
142 | _id: BigNumberish,
143 | _amount: BigNumberish,
144 | _data: Arrayish,
145 | overrides?: TransactionOverrides
146 | ): Promise;
147 |
148 | setApprovalForAll(
149 | _operator: string,
150 | _approved: boolean,
151 | overrides?: TransactionOverrides
152 | ): Promise;
153 | };
154 |
155 | filters: {
156 | ApprovalForAll(
157 | _owner: string | null,
158 | _operator: string | null,
159 | _approved: null
160 | ): EventFilter;
161 |
162 | TransferBatch(
163 | _operator: string | null,
164 | _from: string | null,
165 | _to: string | null,
166 | _ids: null,
167 | _amounts: null
168 | ): EventFilter;
169 |
170 | TransferSingle(
171 | _operator: string | null,
172 | _from: string | null,
173 | _to: string | null,
174 | _id: null,
175 | _amount: null
176 | ): EventFilter;
177 |
178 | URI(_uri: null, _id: BigNumberish | null): EventFilter;
179 | };
180 |
181 | estimate: {
182 | safeBatchTransferFrom(
183 | _from: string,
184 | _to: string,
185 | _ids: (BigNumberish)[],
186 | _amounts: (BigNumberish)[],
187 | _data: Arrayish
188 | ): Promise;
189 |
190 | safeTransferFrom(
191 | _from: string,
192 | _to: string,
193 | _id: BigNumberish,
194 | _amount: BigNumberish,
195 | _data: Arrayish
196 | ): Promise;
197 |
198 | setApprovalForAll(
199 | _operator: string,
200 | _approved: boolean
201 | ): Promise;
202 | };
203 | }
204 |
--------------------------------------------------------------------------------
/typings/contracts/ERC1155OperatorMock.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155OperatorMockInterface extends Interface {
14 | functions: {
15 | safeTransferFrom: TypedFunctionDescription<{
16 | encode([_tokenAddress, _from, _to, _id, _amount, _data]: [
17 | string,
18 | string,
19 | string,
20 | BigNumberish,
21 | BigNumberish,
22 | Arrayish
23 | ]): string;
24 | }>;
25 |
26 | safeBatchTransferFrom: TypedFunctionDescription<{
27 | encode([_tokenAddress, _from, _to, _ids, _amounts, _data]: [
28 | string,
29 | string,
30 | string,
31 | (BigNumberish)[],
32 | (BigNumberish)[],
33 | Arrayish
34 | ]): string;
35 | }>;
36 |
37 | metaSafeTransferFrom: TypedFunctionDescription<{
38 | encode([_tokenAddress, _from, _to, _id, _amount, _isGasFee, _data]: [
39 | string,
40 | string,
41 | string,
42 | BigNumberish,
43 | BigNumberish,
44 | boolean,
45 | Arrayish
46 | ]): string;
47 | }>;
48 |
49 | metaSafeBatchTransferFrom: TypedFunctionDescription<{
50 | encode([_tokenAddress, _from, _to, _ids, _amounts, _isGasFee, _data]: [
51 | string,
52 | string,
53 | string,
54 | (BigNumberish)[],
55 | (BigNumberish)[],
56 | boolean,
57 | Arrayish
58 | ]): string;
59 | }>;
60 |
61 | metaSetApprovalForAll: TypedFunctionDescription<{
62 | encode([_tokenAddress, _owner, _operator, _approved, _isGasFee, _data]: [
63 | string,
64 | string,
65 | string,
66 | boolean,
67 | boolean,
68 | Arrayish
69 | ]): string;
70 | }>;
71 | };
72 |
73 | events: {};
74 | }
75 |
76 | export class ERC1155OperatorMock extends Contract {
77 | connect(signerOrProvider: Signer | Provider | string): ERC1155OperatorMock;
78 | attach(addressOrName: string): ERC1155OperatorMock;
79 | deployed(): Promise;
80 |
81 | on(event: EventFilter | string, listener: Listener): ERC1155OperatorMock;
82 | once(event: EventFilter | string, listener: Listener): ERC1155OperatorMock;
83 | addListener(
84 | eventName: EventFilter | string,
85 | listener: Listener
86 | ): ERC1155OperatorMock;
87 | removeAllListeners(eventName: EventFilter | string): ERC1155OperatorMock;
88 | removeListener(eventName: any, listener: Listener): ERC1155OperatorMock;
89 |
90 | interface: ERC1155OperatorMockInterface;
91 |
92 | functions: {
93 | safeTransferFrom(
94 | _tokenAddress: string,
95 | _from: string,
96 | _to: string,
97 | _id: BigNumberish,
98 | _amount: BigNumberish,
99 | _data: Arrayish,
100 | overrides?: TransactionOverrides
101 | ): Promise;
102 |
103 | safeBatchTransferFrom(
104 | _tokenAddress: string,
105 | _from: string,
106 | _to: string,
107 | _ids: (BigNumberish)[],
108 | _amounts: (BigNumberish)[],
109 | _data: Arrayish,
110 | overrides?: TransactionOverrides
111 | ): Promise;
112 |
113 | metaSafeTransferFrom(
114 | _tokenAddress: string,
115 | _from: string,
116 | _to: string,
117 | _id: BigNumberish,
118 | _amount: BigNumberish,
119 | _isGasFee: boolean,
120 | _data: Arrayish,
121 | overrides?: TransactionOverrides
122 | ): Promise;
123 |
124 | metaSafeBatchTransferFrom(
125 | _tokenAddress: string,
126 | _from: string,
127 | _to: string,
128 | _ids: (BigNumberish)[],
129 | _amounts: (BigNumberish)[],
130 | _isGasFee: boolean,
131 | _data: Arrayish,
132 | overrides?: TransactionOverrides
133 | ): Promise;
134 |
135 | metaSetApprovalForAll(
136 | _tokenAddress: string,
137 | _owner: string,
138 | _operator: string,
139 | _approved: boolean,
140 | _isGasFee: boolean,
141 | _data: Arrayish,
142 | overrides?: TransactionOverrides
143 | ): Promise;
144 | };
145 |
146 | filters: {};
147 |
148 | estimate: {
149 | safeTransferFrom(
150 | _tokenAddress: string,
151 | _from: string,
152 | _to: string,
153 | _id: BigNumberish,
154 | _amount: BigNumberish,
155 | _data: Arrayish
156 | ): Promise;
157 |
158 | safeBatchTransferFrom(
159 | _tokenAddress: string,
160 | _from: string,
161 | _to: string,
162 | _ids: (BigNumberish)[],
163 | _amounts: (BigNumberish)[],
164 | _data: Arrayish
165 | ): Promise;
166 |
167 | metaSafeTransferFrom(
168 | _tokenAddress: string,
169 | _from: string,
170 | _to: string,
171 | _id: BigNumberish,
172 | _amount: BigNumberish,
173 | _isGasFee: boolean,
174 | _data: Arrayish
175 | ): Promise;
176 |
177 | metaSafeBatchTransferFrom(
178 | _tokenAddress: string,
179 | _from: string,
180 | _to: string,
181 | _ids: (BigNumberish)[],
182 | _amounts: (BigNumberish)[],
183 | _isGasFee: boolean,
184 | _data: Arrayish
185 | ): Promise;
186 |
187 | metaSetApprovalForAll(
188 | _tokenAddress: string,
189 | _owner: string,
190 | _operator: string,
191 | _approved: boolean,
192 | _isGasFee: boolean,
193 | _data: Arrayish
194 | ): Promise;
195 | };
196 | }
197 |
--------------------------------------------------------------------------------
/contracts/mocks/ERC1155OperatorMock.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | import "../interfaces/IERC1155.sol";
4 | import "../interfaces/IERC1155Meta.sol";
5 |
6 |
7 | /**
8 | * @dev Contract that acts as an operator contract.
9 | */
10 | contract ERC1155OperatorMock {
11 |
12 | /****************************************|
13 | | Public Regular Transfer Functions |
14 | |_______________________________________*/
15 |
16 | /**
17 | * @dev Allow _from or an operator to transfer tokens from one address to another
18 | * @param _tokenAddress The address of the token contract to call
19 | * @param _from The address which you want to send tokens from
20 | * @param _to The address which you want to transfer to
21 | * @param _id token id to update balance of
22 | * @param _amount The amount of tokens of provided token ID to be transferred
23 | * @param _data Data to pass to onERC1155Received() function if recipient is contract
24 | */
25 | function safeTransferFrom(
26 | address _tokenAddress,
27 | address _from,
28 | address _to,
29 | uint256 _id,
30 | uint256 _amount,
31 | bytes memory _data)
32 | public
33 | {
34 | IERC1155(_tokenAddress).safeTransferFrom(_from, _to, _id, _amount, _data);
35 | }
36 |
37 | /**
38 | * @dev transfer objects from different ids to specified address
39 | * @param _tokenAddress The address of the token contract to call
40 | * @param _from The address to batchTransfer objects from.
41 | * @param _to The address to batchTransfer objects to.
42 | * @param _ids Array of ids to update balance of
43 | * @param _amounts Array of amount of object per id to be transferred.
44 | * @param _data Data to pass to onERC1155Received() function if recipient is contract
45 | * Note: Arrays should be sorted so that all ids in a same bin are adjacent (more efficient).
46 | */
47 | function safeBatchTransferFrom(
48 | address _tokenAddress,
49 | address _from,
50 | address _to,
51 | uint256[] memory _ids,
52 | uint256[] memory _amounts,
53 | bytes memory _data)
54 | public
55 | {
56 | IERC1155(_tokenAddress).safeBatchTransferFrom(_from, _to, _ids, _amounts, _data);
57 | }
58 |
59 | /****************************************|
60 | | Public Meta Transfer Functions |
61 | |_______________________________________*/
62 |
63 | /**
64 | * @notice Allows anyone with a valid signature to transfer _amount amount of a token _id on the bahalf of _from
65 | * @param _tokenAddress The address of the token contract to call
66 | * @param _from Source address
67 | * @param _to Target address
68 | * @param _id ID of the token type
69 | * @param _amount Transfered amount
70 | * @param _isGasFee Whether gas is reimbursed to executor or not
71 | * @param _data Encodes a meta transfer indicator, signature, gas payment receipt and extra transfer data
72 | * _data should be encoded as ((bytes32 r, bytes32 s, uint8 v, SignatureType sigType), (GasReceipt g, bytes data))
73 | * i.e. high level encoding should be (bytes, bytes), where the latter bytes array is a nested bytes array
74 | */
75 | function metaSafeTransferFrom(
76 | address _tokenAddress,
77 | address _from,
78 | address _to,
79 | uint256 _id,
80 | uint256 _amount,
81 | bool _isGasFee,
82 | bytes memory _data)
83 | public
84 | {
85 | IERC1155Meta(_tokenAddress).metaSafeTransferFrom(_from, _to, _id, _amount, _isGasFee, _data);
86 | }
87 |
88 |
89 | /**
90 | * @notice Allows anyone with a valid signature to transfer multiple types of tokens on the bahalf of _from
91 | * @param _tokenAddress The address of the token contract to call
92 | * @param _from Source addresses
93 | * @param _to Target addresses
94 | * @param _ids IDs of each token type
95 | * @param _amounts Transfer amounts per token type
96 | * @param _data Encodes a meta transfer indicator, signature, gas payment receipt and extra transfer data
97 | * _data should be encoded as ((bytes32 r, bytes32 s, uint8 v, SignatureType sigType), (GasReceipt g, bytes data))
98 | * i.e. high level encoding should be (bytes, bytes), where the latter bytes array is a nested bytes array
99 | */
100 | function metaSafeBatchTransferFrom(
101 | address _tokenAddress,
102 | address _from,
103 | address _to,
104 | uint256[] memory _ids,
105 | uint256[] memory _amounts,
106 | bool _isGasFee,
107 | bytes memory _data)
108 | public
109 | {
110 | IERC1155Meta(_tokenAddress).metaSafeBatchTransferFrom(_from, _to, _ids, _amounts, _isGasFee, _data);
111 | }
112 |
113 |
114 | /***********************************|
115 | | Operator Functions |
116 | |__________________________________*/
117 |
118 | /**
119 | * @notice Approve the passed address to spend on behalf of _from if valid signature is provided
120 | * @param _tokenAddress The address of the token contract to call
121 | * @param _owner Address that wants to set operator status _spender
122 | * @param _operator Address to add to the set of authorized operators
123 | * @param _approved True if the operator is approved, false to revoke approval
124 | * @param _isGasFee Whether gas will be reimbursed or not, with vlid signature
125 | * @param _data Encodes signature and gas payment receipt
126 | * _data should be encoded as ((bytes32 r, bytes32 s, uint8 v, SignatureType sigType), (GasReceipt g))
127 | * i.e. high level encoding should be (bytes, bytes), where the latter bytes array is a nested bytes array
128 | */
129 | function metaSetApprovalForAll(
130 | address _tokenAddress,
131 | address _owner,
132 | address _operator,
133 | bool _approved,
134 | bool _isGasFee,
135 | bytes memory _data)
136 | public
137 | {
138 | IERC1155Meta(_tokenAddress).metaSetApprovalForAll(_owner, _operator, _approved, _isGasFee, _data);
139 | }
140 |
141 | }
--------------------------------------------------------------------------------
/contracts/mocks/ERC1155ReceiverMock.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | import '../interfaces/IERC1155.sol';
4 |
5 |
6 | // Contract to test safe transfer behavior.
7 | contract ERC1155ReceiverMock {
8 | bytes4 constant internal ERC1155_RECEIVED_SIG = 0xf23a6e61;
9 | bytes4 constant internal ERC1155_BATCH_RECEIVED_SIG = 0xbc197c81;
10 | bytes4 constant internal ERC1155_RECEIVED_INVALID = 0xdeadbeef;
11 | bytes4 constant internal IS_ERC1155_RECEIVER = 0x0d912442; //bytes4(keccak256("isERC1155TokenReceiver()"));
12 |
13 | // Keep values from last received contract.
14 | bool public shouldReject;
15 |
16 | bytes public lastData;
17 | address public lastOperator;
18 | uint256 public lastId;
19 | uint256 public lastValue;
20 |
21 | //Debug event
22 | event TransferSingleReceiver(address _from, address _to, uint256 _fromBalance, uint256 _toBalance);
23 | event TransferBatchReceiver(address _from, address _to, uint256[] _fromBalances, uint256[] _toBalances);
24 |
25 | function setShouldReject(bool _value) public {
26 | shouldReject = _value;
27 | }
28 |
29 | /**
30 | * @notice Handle the receipt of a single ERC1155 token type.
31 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated.
32 | * This function MAY throw to revert and reject the transfer.
33 | * Return of other than the magic value MUST result in the transaction being reverted.
34 | * Note: The contract address is always the message sender.
35 | * @param _operator The address which called the `safeTransferFrom` function
36 | * @param _from The address which previously owned the token
37 | * @param _id The id of the token being transferred
38 | * @param _value The amount of tokens being transferred
39 | * @param _data Additional data with no specified format
40 | * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
41 | */
42 | function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes memory _data)
43 | public returns(bytes4)
44 | {
45 | // To check the following conditions;
46 | // All the balances in the transfer MUST have been updated to match the senders intent before any hook is called on a recipient.
47 | // All the transfer events for the transfer MUST have been emitted to reflect the balance changes before any hook is called on a recipient.
48 | uint256 fromBalance = IERC1155(msg.sender).balanceOf(_from, _id);
49 | uint256 toBalance = IERC1155(msg.sender).balanceOf(address(this), _id);
50 | emit TransferSingleReceiver(_from, address(this), fromBalance, toBalance);
51 |
52 | if (shouldReject == true) {
53 | return ERC1155_RECEIVED_INVALID; // Some random value
54 | } else {
55 | return ERC1155_RECEIVED_SIG;
56 | }
57 | }
58 |
59 | /**
60 | * @notice Handle the receipt of multiple ERC1155 token types.
61 | * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated.
62 | * This function MAY throw to revert and reject the transfer.
63 | * Return of other than the magic value WILL result in the transaction being reverted.
64 | * Note: The contract address is always the message sender.
65 | * @param _operator The address which called the `safeBatchTransferFrom` function
66 | * @param _from The address which previously owned the token
67 | * @param _ids An array containing ids of each token being transferred
68 | * @param _values An array containing amounts of each token being transferred
69 | * @param _data Additional data with no specified format
70 | * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
71 | */
72 | function onERC1155BatchReceived(address _operator, address _from, uint256[] memory _ids, uint256[] memory _values, bytes memory _data)
73 | public returns(bytes4)
74 | {
75 | // To check the following conditions;
76 | // All the balances in the transfer MUST have been updated to match the senders intent before any hook is called on a recipient.
77 | // All the transfer events for the transfer MUST have been emitted to reflect the balance changes before any hook is called on a recipient.
78 | address[] memory fromAddressArray = new address[](_ids.length);
79 | address[] memory toAddressArray = new address[](_ids.length);
80 | for (uint i = 0; i < _ids.length; i++ ) {
81 | fromAddressArray[i] = _from;
82 | toAddressArray[i] = (address(this));
83 | }
84 | uint256[] memory fromBalances = IERC1155(msg.sender).balanceOfBatch(fromAddressArray, _ids);
85 | uint256[] memory toBalances = IERC1155(msg.sender).balanceOfBatch(toAddressArray, _ids);
86 | emit TransferBatchReceiver(_from, address(this), fromBalances, toBalances);
87 |
88 | if (shouldReject == true) {
89 | return ERC1155_RECEIVED_INVALID; // Some random value
90 | } else {
91 | return ERC1155_BATCH_RECEIVED_SIG;
92 | }
93 | }
94 |
95 | /**
96 | * @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types.
97 | * @param interfaceID The ERC-165 interface ID that is queried for support.s
98 | * @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface.
99 | * This function MUST NOT consume more than 5,000 gas.
100 | * @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported.
101 | */
102 | function supportsInterface(bytes4 interfaceID) external view returns (bool) {
103 | return interfaceID == 0x01ffc9a7 || // ERC-165 support (i.e. `bytes4(keccak256('supportsInterface(bytes4)'))`).
104 | interfaceID == 0x4e2312e0; // ERC-1155 `ERC1155TokenReceiver` support (i.e. `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)")) ^ bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`).
105 | }
106 |
107 | }
--------------------------------------------------------------------------------
/contracts/interfaces/IERC1155.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 |
4 | interface IERC1155 {
5 | // Events
6 |
7 | /**
8 | * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
9 | * Operator MUST be msg.sender
10 | * When minting/creating tokens, the `_from` field MUST be set to `0x0`
11 | * When burning/destroying tokens, the `_to` field MUST be set to `0x0`
12 | * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
13 | * To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
14 | */
15 | event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount);
16 |
17 | /**
18 | * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
19 | * Operator MUST be msg.sender
20 | * When minting/creating tokens, the `_from` field MUST be set to `0x0`
21 | * When burning/destroying tokens, the `_to` field MUST be set to `0x0`
22 | * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
23 | * To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
24 | */
25 | event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts);
26 |
27 | /**
28 | * @dev MUST emit when an approval is updated
29 | */
30 | event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
31 |
32 | /**
33 | * @dev MUST emit when the URI is updated for a token ID
34 | * URIs are defined in RFC 3986
35 | * The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema"
36 | */
37 | event URI(string _amount, uint256 indexed _id);
38 |
39 | /**
40 | * @notice Transfers amount of an _id from the _from address to the _to address specified
41 | * @dev MUST emit TransferSingle event on success
42 | * Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
43 | * MUST throw if `_to` is the zero address
44 | * MUST throw if balance of sender for token `_id` is lower than the `_amount` sent
45 | * MUST throw on any other error
46 | * When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155Received` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
47 | * @param _from Source address
48 | * @param _to Target address
49 | * @param _id ID of the token type
50 | * @param _amount Transfered amount
51 | * @param _data Additional data with no specified format, sent in call to `_to`
52 | */
53 | function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;
54 |
55 | /**
56 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
57 | * @dev MUST emit TransferBatch event on success
58 | * Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
59 | * MUST throw if `_to` is the zero address
60 | * MUST throw if length of `_ids` is not the same as length of `_amounts`
61 | * MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent
62 | * MUST throw on any other error
63 | * When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
64 | * Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc)
65 | * @param _from Source addresses
66 | * @param _to Target addresses
67 | * @param _ids IDs of each token type
68 | * @param _amounts Transfer amounts per token type
69 | * @param _data Additional data with no specified format, sent in call to `_to`
70 | */
71 | function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;
72 |
73 | /**
74 | * @notice Get the balance of an account's Tokens
75 | * @param _owner The address of the token holder
76 | * @param _id ID of the Token
77 | * @return The _owner's balance of the Token type requested
78 | */
79 | function balanceOf(address _owner, uint256 _id) external view returns (uint256);
80 |
81 | /**
82 | * @notice Get the balance of multiple account/token pairs
83 | * @param _owners The addresses of the token holders
84 | * @param _ids ID of the Tokens
85 | * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
86 | */
87 | function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);
88 |
89 | /**
90 | * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
91 | * @dev MUST emit the ApprovalForAll event on success
92 | * @param _operator Address to add to the set of authorized operators
93 | * @param _approved True if the operator is approved, false to revoke approval
94 | */
95 | function setApprovalForAll(address _operator, bool _approved) external;
96 |
97 | /**
98 | * @notice Queries the approval status of an operator for a given owner
99 | * @param _owner The owner of the Tokens
100 | * @param _operator Address of authorized operator
101 | * @return True if the operator is approved, false if not
102 | */
103 | function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator);
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/src/tests/SignatureValidator.spec.ts:
--------------------------------------------------------------------------------
1 | import * as ethers from 'ethers'
2 |
3 | import { AbstractContract, expect, RevertError, ethSign, eip712Sign } from './utils'
4 | import * as utils from './utils'
5 |
6 | import { SignatureValidator } from 'typings/contracts/SignatureValidator'
7 | import { ERC1271WalletMock } from 'typings/contracts/ERC1271WalletMock'
8 | import { AddressZero } from 'ethers/constants';
9 |
10 | // init test wallets from package.json mnemonic
11 | const web3 = (global as any).web3
12 |
13 | const {
14 | wallet: signerWallet,
15 | provider: signerProvider,
16 | signer: signerSigner
17 | } = utils.createTestWallet(web3, 0)
18 |
19 | contract('SignatureValidator Contract', (accounts: string[]) => {
20 |
21 | let signerAddress: string
22 | let signatureValidatorAbstract: AbstractContract
23 | let ERC1271WalletMockAbstract: AbstractContract
24 | let signatureValidatorContract: SignatureValidator
25 | let erc1271WalletMockContract: ERC1271WalletMock
26 |
27 | // load contract abi and deploy to test server
28 | before(async () => {
29 | signerAddress = await signerWallet.getAddress()
30 | signatureValidatorAbstract = await AbstractContract.fromArtifactName('SignatureValidator')
31 | })
32 |
33 | // deploy before each test, to reset state of contract
34 | beforeEach(async () => {
35 | signatureValidatorContract = await signatureValidatorAbstract.deploy(signerWallet) as SignatureValidator
36 | })
37 |
38 | describe('isValidSignature() Function', () => {
39 |
40 | let data = ethers.utils.toUtf8Bytes('Did the Ethereum blockchain reach 1TB yet? No.')
41 | let dataHash = ethers.utils.keccak256(data)
42 | let ethsig: string
43 | let eip712sig: string
44 |
45 | beforeEach(async () => {
46 | ethsig = await ethSign(signerWallet, data)
47 | })
48 |
49 | it('should REVERT if signature is of length 0', async () => {
50 | // @ts-ignore
51 | const tx = signatureValidatorContract.functions.isValidSignature(signerAddress, dataHash, data, [])
52 | await expect(tx).to.be.rejectedWith( RevertError("SignatureValidator#isValidSignature: LENGTH_GREATER_THAN_0_REQUIRED") )
53 | })
54 |
55 | it('should REVERT if expected signer is 0x0', async () => {
56 | // @ts-ignore
57 | const tx = signatureValidatorContract.functions.isValidSignature(AddressZero, dataHash, data, ethsig)
58 | await expect(tx).to.be.rejectedWith( RevertError("SignatureValidator#isValidSignature: INVALID_SIGNER") )
59 | })
60 |
61 | it('should REVERT if signature is illigal (SignatureType: 0x0)', async () => {
62 | // @ts-ignore
63 | const tx = signatureValidatorContract.functions.isValidSignature(signerAddress, dataHash, data, ethsig.slice(0, -2) + '00')
64 | await expect(tx).to.be.rejectedWith( RevertError("SignatureValidator#isValidSignature: ILLEGAL_SIGNATURE") )
65 | })
66 |
67 | it('should REVERT if signatureType is above 05', async () => {
68 | // @ts-ignore
69 | const tx = signatureValidatorContract.functions.isValidSignature(signerAddress, dataHash, data, ethsig.slice(0, -2) + '06')
70 | await expect(tx).to.be.rejectedWith( RevertError("SignatureValidator#isValidSignature: UNSUPPORTED_SIGNATURE") )
71 | })
72 |
73 | describe(`EIP-712 signatures`, () => {
74 |
75 | beforeEach(async () => {
76 | eip712sig = await eip712Sign(signerWallet, data)
77 | })
78 |
79 | it('should REVERT if signature length is not 65', async () => {
80 | // @ts-ignore
81 | const tx = signatureValidatorContract.functions.isValidSignature(signerAddress, dataHash, data, '0x1234' + eip712sig.slice(2) )
82 | await expect(tx).to.be.rejectedWith( RevertError("SignatureValidator#isValidSignature: LENGTH_65_REQUIRED") )
83 | })
84 |
85 | it('should return TRUE if signature is valid', async () => {
86 | // @ts-ignore
87 | let isValid = await signatureValidatorContract.functions.isValidSignature(signerAddress, dataHash, data, eip712sig)
88 | await expect(isValid).to.be.equal(true);
89 | })
90 |
91 | })
92 |
93 | describe(`ETH_SIGN signatures`, () => {
94 |
95 | it('should REVERT if signature length is not 65', async () => {
96 | // @ts-ignore
97 | const tx = signatureValidatorContract.functions.isValidSignature(signerAddress, dataHash, data, '0x1234' + ethsig.slice(2))
98 | await expect(tx).to.be.rejectedWith( RevertError("SignatureValidator#isValidSignature: LENGTH_65_REQUIRED") )
99 | })
100 |
101 | it('should return TRUE if signature is valid', async () => {
102 | // @ts-ignore
103 | let isValid = await signatureValidatorContract.functions.isValidSignature(signerAddress, dataHash, data, ethsig)
104 | expect(isValid).to.be.equal(true);
105 | })
106 |
107 | })
108 |
109 | describe(`EIP-1271 (bytes) signatures (03)`, () => {
110 | let erc1271WalletAddress;
111 |
112 | beforeEach( async () => {
113 | ERC1271WalletMockAbstract = await AbstractContract.fromArtifactName('ERC1271WalletMock')
114 | erc1271WalletMockContract = await ERC1271WalletMockAbstract.deploy(signerWallet) as ERC1271WalletMock
115 | erc1271WalletAddress = erc1271WalletMockContract.address;
116 | })
117 |
118 | it('should return FALSE if contract returns incorrect magic value', async () => {
119 | // @ts-ignore
120 | let isValid = await signatureValidatorContract.functions.isValidSignature(erc1271WalletAddress, dataHash, data, ethsig + '03')
121 | expect(isValid).to.be.equal(false)
122 | })
123 |
124 | it('should return TRUE if contract returns correct magic value', async () => {
125 | await erc1271WalletMockContract.functions.setShouldReject(false)
126 |
127 | // @ts-ignore
128 | let isValid = await signatureValidatorContract.functions.isValidSignature(erc1271WalletAddress, dataHash, data, ethsig + '03')
129 | await expect(isValid).to.be.equal(true);
130 | })
131 | })
132 |
133 | describe(`EIP-1271 (bytes32) signatures (04)`, () => {
134 | let erc1271WalletAddress;
135 |
136 | beforeEach( async () => {
137 | ERC1271WalletMockAbstract = await AbstractContract.fromArtifactName('ERC1271WalletMock')
138 | erc1271WalletMockContract = await ERC1271WalletMockAbstract.deploy(signerWallet) as ERC1271WalletMock
139 | erc1271WalletAddress = erc1271WalletMockContract.address;
140 | })
141 |
142 | it('should return FALSE if contract returns incorrect magic value', async () => {
143 | // @ts-ignore
144 | let isValid = await signatureValidatorContract.functions.isValidSignature(erc1271WalletAddress, dataHash, data, ethsig + '04')
145 | expect(isValid).to.be.equal(false)
146 | })
147 |
148 | it('should return TRUE if contract returns correct magic value', async () => {
149 | await erc1271WalletMockContract.functions.setShouldReject(false)
150 |
151 | // @ts-ignore
152 | let isValid = await signatureValidatorContract.functions.isValidSignature(erc1271WalletAddress, dataHash, data, ethsig + '04')
153 | await expect(isValid).to.be.equal(true);
154 | })
155 | })
156 |
157 |
158 | })
159 | })
--------------------------------------------------------------------------------
/typings/contracts/ERC1155Meta.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155MetaInterface extends Interface {
14 | functions: {
15 | safeBatchTransferFrom: TypedFunctionDescription<{
16 | encode([_from, _to, _ids, _amounts, _data]: [
17 | string,
18 | string,
19 | (BigNumberish)[],
20 | (BigNumberish)[],
21 | Arrayish
22 | ]): string;
23 | }>;
24 |
25 | safeTransferFrom: TypedFunctionDescription<{
26 | encode([_from, _to, _id, _amount, _data]: [
27 | string,
28 | string,
29 | BigNumberish,
30 | BigNumberish,
31 | Arrayish
32 | ]): string;
33 | }>;
34 |
35 | setApprovalForAll: TypedFunctionDescription<{
36 | encode([_operator, _approved]: [string, boolean]): string;
37 | }>;
38 |
39 | metaSafeTransferFrom: TypedFunctionDescription<{
40 | encode([_from, _to, _id, _amount, _isGasFee, _data]: [
41 | string,
42 | string,
43 | BigNumberish,
44 | BigNumberish,
45 | boolean,
46 | Arrayish
47 | ]): string;
48 | }>;
49 |
50 | metaSafeBatchTransferFrom: TypedFunctionDescription<{
51 | encode([_from, _to, _ids, _amounts, _isGasFee, _data]: [
52 | string,
53 | string,
54 | (BigNumberish)[],
55 | (BigNumberish)[],
56 | boolean,
57 | Arrayish
58 | ]): string;
59 | }>;
60 |
61 | metaSetApprovalForAll: TypedFunctionDescription<{
62 | encode([_owner, _operator, _approved, _isGasFee, _data]: [
63 | string,
64 | string,
65 | boolean,
66 | boolean,
67 | Arrayish
68 | ]): string;
69 | }>;
70 | };
71 |
72 | events: {
73 | ApprovalForAll: TypedEventDescription<{
74 | encodeTopics([_owner, _operator, _approved]: [
75 | string | null,
76 | string | null,
77 | null
78 | ]): string[];
79 | }>;
80 |
81 | TransferBatch: TypedEventDescription<{
82 | encodeTopics([_operator, _from, _to, _ids, _amounts]: [
83 | string | null,
84 | string | null,
85 | string | null,
86 | null,
87 | null
88 | ]): string[];
89 | }>;
90 |
91 | TransferSingle: TypedEventDescription<{
92 | encodeTopics([_operator, _from, _to, _id, _amount]: [
93 | string | null,
94 | string | null,
95 | string | null,
96 | null,
97 | null
98 | ]): string[];
99 | }>;
100 |
101 | URI: TypedEventDescription<{
102 | encodeTopics([_uri, _id]: [null, BigNumberish | null]): string[];
103 | }>;
104 | };
105 | }
106 |
107 | export class ERC1155Meta extends Contract {
108 | connect(signerOrProvider: Signer | Provider | string): ERC1155Meta;
109 | attach(addressOrName: string): ERC1155Meta;
110 | deployed(): Promise;
111 |
112 | on(event: EventFilter | string, listener: Listener): ERC1155Meta;
113 | once(event: EventFilter | string, listener: Listener): ERC1155Meta;
114 | addListener(eventName: EventFilter | string, listener: Listener): ERC1155Meta;
115 | removeAllListeners(eventName: EventFilter | string): ERC1155Meta;
116 | removeListener(eventName: any, listener: Listener): ERC1155Meta;
117 |
118 | interface: ERC1155MetaInterface;
119 |
120 | functions: {
121 | balanceOf(_owner: string, _id: BigNumberish): Promise;
122 |
123 | balanceOfBatch(
124 | _owners: (string)[],
125 | _ids: (BigNumberish)[]
126 | ): Promise<(BigNumber)[]>;
127 |
128 | isApprovedForAll(_owner: string, _operator: string): Promise;
129 |
130 | isValidSignature(
131 | _signerAddress: string,
132 | _hash: Arrayish,
133 | _data: Arrayish,
134 | _sig: Arrayish
135 | ): Promise;
136 |
137 | supportsInterface(_interfaceID: Arrayish): Promise;
138 |
139 | getNonce(_signer: string): Promise;
140 |
141 | safeBatchTransferFrom(
142 | _from: string,
143 | _to: string,
144 | _ids: (BigNumberish)[],
145 | _amounts: (BigNumberish)[],
146 | _data: Arrayish,
147 | overrides?: TransactionOverrides
148 | ): Promise;
149 |
150 | safeTransferFrom(
151 | _from: string,
152 | _to: string,
153 | _id: BigNumberish,
154 | _amount: BigNumberish,
155 | _data: Arrayish,
156 | overrides?: TransactionOverrides
157 | ): Promise;
158 |
159 | setApprovalForAll(
160 | _operator: string,
161 | _approved: boolean,
162 | overrides?: TransactionOverrides
163 | ): Promise;
164 |
165 | metaSafeTransferFrom(
166 | _from: string,
167 | _to: string,
168 | _id: BigNumberish,
169 | _amount: BigNumberish,
170 | _isGasFee: boolean,
171 | _data: Arrayish,
172 | overrides?: TransactionOverrides
173 | ): Promise;
174 |
175 | metaSafeBatchTransferFrom(
176 | _from: string,
177 | _to: string,
178 | _ids: (BigNumberish)[],
179 | _amounts: (BigNumberish)[],
180 | _isGasFee: boolean,
181 | _data: Arrayish,
182 | overrides?: TransactionOverrides
183 | ): Promise;
184 |
185 | metaSetApprovalForAll(
186 | _owner: string,
187 | _operator: string,
188 | _approved: boolean,
189 | _isGasFee: boolean,
190 | _data: Arrayish,
191 | overrides?: TransactionOverrides
192 | ): Promise;
193 | };
194 |
195 | filters: {
196 | ApprovalForAll(
197 | _owner: string | null,
198 | _operator: string | null,
199 | _approved: null
200 | ): EventFilter;
201 |
202 | TransferBatch(
203 | _operator: string | null,
204 | _from: string | null,
205 | _to: string | null,
206 | _ids: null,
207 | _amounts: null
208 | ): EventFilter;
209 |
210 | TransferSingle(
211 | _operator: string | null,
212 | _from: string | null,
213 | _to: string | null,
214 | _id: null,
215 | _amount: null
216 | ): EventFilter;
217 |
218 | URI(_uri: null, _id: BigNumberish | null): EventFilter;
219 | };
220 |
221 | estimate: {
222 | safeBatchTransferFrom(
223 | _from: string,
224 | _to: string,
225 | _ids: (BigNumberish)[],
226 | _amounts: (BigNumberish)[],
227 | _data: Arrayish
228 | ): Promise;
229 |
230 | safeTransferFrom(
231 | _from: string,
232 | _to: string,
233 | _id: BigNumberish,
234 | _amount: BigNumberish,
235 | _data: Arrayish
236 | ): Promise;
237 |
238 | setApprovalForAll(
239 | _operator: string,
240 | _approved: boolean
241 | ): Promise;
242 |
243 | metaSafeTransferFrom(
244 | _from: string,
245 | _to: string,
246 | _id: BigNumberish,
247 | _amount: BigNumberish,
248 | _isGasFee: boolean,
249 | _data: Arrayish
250 | ): Promise;
251 |
252 | metaSafeBatchTransferFrom(
253 | _from: string,
254 | _to: string,
255 | _ids: (BigNumberish)[],
256 | _amounts: (BigNumberish)[],
257 | _isGasFee: boolean,
258 | _data: Arrayish
259 | ): Promise;
260 |
261 | metaSetApprovalForAll(
262 | _owner: string,
263 | _operator: string,
264 | _approved: boolean,
265 | _isGasFee: boolean,
266 | _data: Arrayish
267 | ): Promise;
268 | };
269 | }
270 |
--------------------------------------------------------------------------------
/typings/contracts/ERC1155MetaPackedBalance.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155MetaPackedBalanceInterface extends Interface {
14 | functions: {
15 | safeBatchTransferFrom: TypedFunctionDescription<{
16 | encode([_from, _to, _ids, _amounts, _data]: [
17 | string,
18 | string,
19 | (BigNumberish)[],
20 | (BigNumberish)[],
21 | Arrayish
22 | ]): string;
23 | }>;
24 |
25 | safeTransferFrom: TypedFunctionDescription<{
26 | encode([_from, _to, _id, _amount, _data]: [
27 | string,
28 | string,
29 | BigNumberish,
30 | BigNumberish,
31 | Arrayish
32 | ]): string;
33 | }>;
34 |
35 | setApprovalForAll: TypedFunctionDescription<{
36 | encode([_operator, _approved]: [string, boolean]): string;
37 | }>;
38 |
39 | metaSafeTransferFrom: TypedFunctionDescription<{
40 | encode([_from, _to, _id, _amount, _isGasFee, _data]: [
41 | string,
42 | string,
43 | BigNumberish,
44 | BigNumberish,
45 | boolean,
46 | Arrayish
47 | ]): string;
48 | }>;
49 |
50 | metaSafeBatchTransferFrom: TypedFunctionDescription<{
51 | encode([_from, _to, _ids, _amounts, _isGasFee, _data]: [
52 | string,
53 | string,
54 | (BigNumberish)[],
55 | (BigNumberish)[],
56 | boolean,
57 | Arrayish
58 | ]): string;
59 | }>;
60 |
61 | metaSetApprovalForAll: TypedFunctionDescription<{
62 | encode([_owner, _operator, _approved, _isGasFee, _data]: [
63 | string,
64 | string,
65 | boolean,
66 | boolean,
67 | Arrayish
68 | ]): string;
69 | }>;
70 | };
71 |
72 | events: {
73 | ApprovalForAll: TypedEventDescription<{
74 | encodeTopics([_owner, _operator, _approved]: [
75 | string | null,
76 | string | null,
77 | null
78 | ]): string[];
79 | }>;
80 |
81 | TransferBatch: TypedEventDescription<{
82 | encodeTopics([_operator, _from, _to, _ids, _amounts]: [
83 | string | null,
84 | string | null,
85 | string | null,
86 | null,
87 | null
88 | ]): string[];
89 | }>;
90 |
91 | TransferSingle: TypedEventDescription<{
92 | encodeTopics([_operator, _from, _to, _id, _amount]: [
93 | string | null,
94 | string | null,
95 | string | null,
96 | null,
97 | null
98 | ]): string[];
99 | }>;
100 |
101 | URI: TypedEventDescription<{
102 | encodeTopics([_uri, _id]: [null, BigNumberish | null]): string[];
103 | }>;
104 | };
105 | }
106 |
107 | export class ERC1155MetaPackedBalance extends Contract {
108 | connect(
109 | signerOrProvider: Signer | Provider | string
110 | ): ERC1155MetaPackedBalance;
111 | attach(addressOrName: string): ERC1155MetaPackedBalance;
112 | deployed(): Promise;
113 |
114 | on(event: EventFilter | string, listener: Listener): ERC1155MetaPackedBalance;
115 | once(
116 | event: EventFilter | string,
117 | listener: Listener
118 | ): ERC1155MetaPackedBalance;
119 | addListener(
120 | eventName: EventFilter | string,
121 | listener: Listener
122 | ): ERC1155MetaPackedBalance;
123 | removeAllListeners(eventName: EventFilter | string): ERC1155MetaPackedBalance;
124 | removeListener(eventName: any, listener: Listener): ERC1155MetaPackedBalance;
125 |
126 | interface: ERC1155MetaPackedBalanceInterface;
127 |
128 | functions: {
129 | balanceOf(_owner: string, _id: BigNumberish): Promise;
130 |
131 | balanceOfBatch(
132 | _owners: (string)[],
133 | _ids: (BigNumberish)[]
134 | ): Promise<(BigNumber)[]>;
135 |
136 | getIDBinIndex(
137 | _id: BigNumberish
138 | ): Promise<{
139 | bin: BigNumber;
140 | index: BigNumber;
141 | 0: BigNumber;
142 | 1: BigNumber;
143 | }>;
144 |
145 | getValueInBin(
146 | _binAmount: BigNumberish,
147 | _index: BigNumberish
148 | ): Promise;
149 |
150 | isApprovedForAll(_owner: string, _operator: string): Promise;
151 |
152 | isValidSignature(
153 | _signerAddress: string,
154 | _hash: Arrayish,
155 | _data: Arrayish,
156 | _sig: Arrayish
157 | ): Promise;
158 |
159 | supportsInterface(_interfaceID: Arrayish): Promise;
160 |
161 | getNonce(_signer: string): Promise;
162 |
163 | safeBatchTransferFrom(
164 | _from: string,
165 | _to: string,
166 | _ids: (BigNumberish)[],
167 | _amounts: (BigNumberish)[],
168 | _data: Arrayish,
169 | overrides?: TransactionOverrides
170 | ): Promise;
171 |
172 | safeTransferFrom(
173 | _from: string,
174 | _to: string,
175 | _id: BigNumberish,
176 | _amount: BigNumberish,
177 | _data: Arrayish,
178 | overrides?: TransactionOverrides
179 | ): Promise;
180 |
181 | setApprovalForAll(
182 | _operator: string,
183 | _approved: boolean,
184 | overrides?: TransactionOverrides
185 | ): Promise;
186 |
187 | metaSafeTransferFrom(
188 | _from: string,
189 | _to: string,
190 | _id: BigNumberish,
191 | _amount: BigNumberish,
192 | _isGasFee: boolean,
193 | _data: Arrayish,
194 | overrides?: TransactionOverrides
195 | ): Promise;
196 |
197 | metaSafeBatchTransferFrom(
198 | _from: string,
199 | _to: string,
200 | _ids: (BigNumberish)[],
201 | _amounts: (BigNumberish)[],
202 | _isGasFee: boolean,
203 | _data: Arrayish,
204 | overrides?: TransactionOverrides
205 | ): Promise;
206 |
207 | metaSetApprovalForAll(
208 | _owner: string,
209 | _operator: string,
210 | _approved: boolean,
211 | _isGasFee: boolean,
212 | _data: Arrayish,
213 | overrides?: TransactionOverrides
214 | ): Promise;
215 | };
216 |
217 | filters: {
218 | ApprovalForAll(
219 | _owner: string | null,
220 | _operator: string | null,
221 | _approved: null
222 | ): EventFilter;
223 |
224 | TransferBatch(
225 | _operator: string | null,
226 | _from: string | null,
227 | _to: string | null,
228 | _ids: null,
229 | _amounts: null
230 | ): EventFilter;
231 |
232 | TransferSingle(
233 | _operator: string | null,
234 | _from: string | null,
235 | _to: string | null,
236 | _id: null,
237 | _amount: null
238 | ): EventFilter;
239 |
240 | URI(_uri: null, _id: BigNumberish | null): EventFilter;
241 | };
242 |
243 | estimate: {
244 | safeBatchTransferFrom(
245 | _from: string,
246 | _to: string,
247 | _ids: (BigNumberish)[],
248 | _amounts: (BigNumberish)[],
249 | _data: Arrayish
250 | ): Promise;
251 |
252 | safeTransferFrom(
253 | _from: string,
254 | _to: string,
255 | _id: BigNumberish,
256 | _amount: BigNumberish,
257 | _data: Arrayish
258 | ): Promise;
259 |
260 | setApprovalForAll(
261 | _operator: string,
262 | _approved: boolean
263 | ): Promise;
264 |
265 | metaSafeTransferFrom(
266 | _from: string,
267 | _to: string,
268 | _id: BigNumberish,
269 | _amount: BigNumberish,
270 | _isGasFee: boolean,
271 | _data: Arrayish
272 | ): Promise;
273 |
274 | metaSafeBatchTransferFrom(
275 | _from: string,
276 | _to: string,
277 | _ids: (BigNumberish)[],
278 | _amounts: (BigNumberish)[],
279 | _isGasFee: boolean,
280 | _data: Arrayish
281 | ): Promise;
282 |
283 | metaSetApprovalForAll(
284 | _owner: string,
285 | _operator: string,
286 | _approved: boolean,
287 | _isGasFee: boolean,
288 | _data: Arrayish
289 | ): Promise;
290 | };
291 | }
292 |
--------------------------------------------------------------------------------
/contracts/mocks/ERC20Mock.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | import "../interfaces/IERC20.sol";
4 | import "../utils/SafeMath.sol";
5 |
6 |
7 | /**
8 | * @title Standard ERC20 token
9 | *
10 | * @dev Implementation of the basic standard token.
11 | * https://eips.ethereum.org/EIPS/eip-20
12 | * Originally based on code by FirstBlood:
13 | * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
14 | *
15 | * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
16 | * all accounts just by listening to said events. Note that this isn't required by the specification, and other
17 | * compliant implementations may not do it.
18 | */
19 | contract ERC20 is IERC20 {
20 | using SafeMath for uint256;
21 |
22 | mapping (address => uint256) private _balances;
23 |
24 | mapping (address => mapping (address => uint256)) private _allowed;
25 |
26 | uint256 private _totalSupply;
27 |
28 | /**
29 | * @dev Total number of tokens in existence
30 | */
31 | function totalSupply() public view returns (uint256) {
32 | return _totalSupply;
33 | }
34 |
35 | /**
36 | * @dev Gets the balance of the specified address.
37 | * @param owner The address to query the balance of.
38 | * @return A uint256 representing the amount owned by the passed address.
39 | */
40 | function balanceOf(address owner) public view returns (uint256) {
41 | return _balances[owner];
42 | }
43 |
44 | /**
45 | * @dev Function to check the amount of tokens that an owner allowed to a spender.
46 | * @param owner address The address which owns the funds.
47 | * @param spender address The address which will spend the funds.
48 | * @return A uint256 specifying the amount of tokens still available for the spender.
49 | */
50 | function allowance(address owner, address spender) public view returns (uint256) {
51 | return _allowed[owner][spender];
52 | }
53 |
54 | /**
55 | * @dev Transfer token to a specified address
56 | * @param to The address to transfer to.
57 | * @param value The amount to be transferred.
58 | */
59 | function transfer(address to, uint256 value) public returns (bool) {
60 | _transfer(msg.sender, to, value);
61 | return true;
62 | }
63 |
64 | /**
65 | * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
66 | * Beware that changing an allowance with this method brings the risk that someone may use both the old
67 | * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
68 | * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
69 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
70 | * @param spender The address which will spend the funds.
71 | * @param value The amount of tokens to be spent.
72 | */
73 | function approve(address spender, uint256 value) public returns (bool) {
74 | _approve(msg.sender, spender, value);
75 | return true;
76 | }
77 |
78 | /**
79 | * @dev Transfer tokens from one address to another.
80 | * Note that while this function emits an Approval event, this is not required as per the specification,
81 | * and other compliant implementations may not emit the event.
82 | * @param from address The address which you want to send tokens from
83 | * @param to address The address which you want to transfer to
84 | * @param value uint256 the amount of tokens to be transferred
85 | */
86 | function transferFrom(address from, address to, uint256 value) public returns (bool) {
87 | _transfer(from, to, value);
88 | _approve(from, msg.sender, _allowed[from][msg.sender].sub(value));
89 | return true;
90 | }
91 |
92 | /**
93 | * @dev Increase the amount of tokens that an owner allowed to a spender.
94 | * approve should be called when _allowed[msg.sender][spender] == 0. To increment
95 | * allowed value is better to use this function to avoid 2 calls (and wait until
96 | * the first transaction is mined)
97 | * From MonolithDAO Token.sol
98 | * Emits an Approval event.
99 | * @param spender The address which will spend the funds.
100 | * @param addedValue The amount of tokens to increase the allowance by.
101 | */
102 | function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
103 | _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue));
104 | return true;
105 | }
106 |
107 | /**
108 | * @dev Decrease the amount of tokens that an owner allowed to a spender.
109 | * approve should be called when _allowed[msg.sender][spender] == 0. To decrement
110 | * allowed value is better to use this function to avoid 2 calls (and wait until
111 | * the first transaction is mined)
112 | * From MonolithDAO Token.sol
113 | * Emits an Approval event.
114 | * @param spender The address which will spend the funds.
115 | * @param subtractedValue The amount of tokens to decrease the allowance by.
116 | */
117 | function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
118 | _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue));
119 | return true;
120 | }
121 |
122 | /**
123 | * @dev Transfer token for a specified addresses
124 | * @param from The address to transfer from.
125 | * @param to The address to transfer to.
126 | * @param value The amount to be transferred.
127 | */
128 | function _transfer(address from, address to, uint256 value) internal {
129 | require(to != address(0));
130 |
131 | _balances[from] = _balances[from].sub(value);
132 | _balances[to] = _balances[to].add(value);
133 | emit Transfer(from, to, value);
134 | }
135 |
136 | /**
137 | * @dev Internal function that mints an amount of the token and assigns it to
138 | * an account. This encapsulates the modification of balances such that the
139 | * proper events are emitted.
140 | * @param account The account that will receive the created tokens.
141 | * @param value The amount that will be created.
142 | */
143 | function _mint(address account, uint256 value) internal {
144 | require(account != address(0));
145 |
146 | _totalSupply = _totalSupply.add(value);
147 | _balances[account] = _balances[account].add(value);
148 | emit Transfer(address(0), account, value);
149 | }
150 |
151 | /**
152 | * @dev Internal function that burns an amount of the token of a given
153 | * account.
154 | * @param account The account whose tokens will be burnt.
155 | * @param value The amount that will be burnt.
156 | */
157 | function _burn(address account, uint256 value) internal {
158 | require(account != address(0));
159 |
160 | _totalSupply = _totalSupply.sub(value);
161 | _balances[account] = _balances[account].sub(value);
162 | emit Transfer(account, address(0), value);
163 | }
164 |
165 | /**
166 | * @dev Approve an address to spend another addresses' tokens.
167 | * @param owner The address that owns the tokens.
168 | * @param spender The address that will spend the tokens.
169 | * @param value The number of tokens that can be spent.
170 | */
171 | function _approve(address owner, address spender, uint256 value) internal {
172 | require(spender != address(0));
173 | require(owner != address(0));
174 |
175 | _allowed[owner][spender] = value;
176 | emit Approval(owner, spender, value);
177 | }
178 |
179 | /**
180 | * @dev Internal function that burns an amount of the token of a given
181 | * account, deducting from the sender's allowance for said account. Uses the
182 | * internal burn function.
183 | * Emits an Approval event (reflecting the reduced allowance).
184 | * @param account The account whose tokens will be burnt.
185 | * @param value The amount that will be burnt.
186 | */
187 | function _burnFrom(address account, uint256 value) internal {
188 | _burn(account, value);
189 | _approve(account, msg.sender, _allowed[account][msg.sender].sub(value));
190 | }
191 |
192 | }
193 |
194 | contract ERC20Mock is ERC20 {
195 |
196 | constructor() public { }
197 |
198 | function mockMint(address _address, uint256 _amount) public {
199 | _mint(_address, _amount);
200 | }
201 |
202 | function batchTransfer(address[] calldata _tokens, address _to, uint256[] calldata _amounts) external {
203 | for (uint256 i = 0; i < _amounts.length; i++){
204 | ERC20(_tokens[i]).transfer(_to, _amounts[i]);
205 | }
206 | }
207 |
208 | }
209 |
210 |
211 |
--------------------------------------------------------------------------------
/src/tests/ERC1155Metadata.spec.ts:
--------------------------------------------------------------------------------
1 | import * as ethers from 'ethers'
2 |
3 | import { AbstractContract, assert, expect, RevertError, BigNumber } from './utils'
4 | import * as utils from './utils'
5 |
6 | import { ERC1155MetadataMock } from 'typings/contracts/ERC1155MetadataMock'
7 |
8 | // init test wallets from package.json mnemonic
9 | const web3 = (global as any).web3
10 |
11 | const {
12 | wallet: ownerWallet,
13 | provider: ownerProvider,
14 | signer: ownerSigner
15 | } = utils.createTestWallet(web3, 0)
16 |
17 | const {
18 | wallet: receiverWallet,
19 | provider: receiverProvider,
20 | signer: receiverSigner
21 | } = utils.createTestWallet(web3, 2)
22 |
23 | const {
24 | wallet: anyoneWallet,
25 | provider: anyoneProvider,
26 | signer: anyoneSigner
27 | } = utils.createTestWallet(web3, 3)
28 |
29 | const {
30 | wallet: operatorWallet,
31 | provider: operatorProvider,
32 | signer: operatorSigner
33 | } = utils.createTestWallet(web3, 4)
34 |
35 |
36 | contract('ERC1155Metadata', (accounts: string[]) => {
37 |
38 | const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
39 |
40 | let ownerAddress: string
41 | let receiverAddress: string
42 | let anyoneAddress: string
43 | let operatorAddress: string
44 |
45 | let erc1155MetadataContract: ERC1155MetadataMock
46 | let anyoneERC1155MetadataContract;
47 |
48 | context('When ERC1155MetadataMock contract is deployed', () => {
49 | const BASE_URI = 'https://assets.skyweaver.net/c679a6577c12c47948084dd61a79b9598db17cc5/full-cards/'
50 |
51 | before(async () => {
52 | ownerAddress = await ownerWallet.getAddress()
53 | receiverAddress = await receiverWallet.getAddress()
54 | anyoneAddress = await anyoneWallet.getAddress()
55 | operatorAddress = await operatorWallet.getAddress()
56 | })
57 |
58 | beforeEach(async () => {
59 | let abstract = await AbstractContract.fromArtifactName('ERC1155MetadataMock')
60 | erc1155MetadataContract = await abstract.deploy(ownerWallet) as ERC1155MetadataMock
61 | anyoneERC1155MetadataContract = await erc1155MetadataContract.connect(anyoneSigner) as ERC1155MetadataMock
62 |
63 | await erc1155MetadataContract.functions.setBaseMetadataURI(BASE_URI);
64 | })
65 |
66 | describe('_updateBaseMetadataURL() function', () => {
67 |
68 | it('should ALLOW inheriting contract to call _updateBaseMetadataURL()', async () => {
69 | const tx = erc1155MetadataContract.functions.setBaseMetadataURI('HELLOTEST/');
70 | await expect(tx).to.be.fulfilled
71 | })
72 |
73 | it('should update baseMetadataURI when successful', async () => {
74 | const URI1 = await erc1155MetadataContract.functions.uri(1928374)
75 | await erc1155MetadataContract.functions.setBaseMetadataURI('HELLOTEST/');
76 | const URI2 = await erc1155MetadataContract.functions.uri(1928374)
77 | expect(URI1).to.be.equal(BASE_URI + '1928374.json')
78 | expect(URI2).to.be.equal('HELLOTEST/1928374.json')
79 | })
80 |
81 | it('Should revert if called directly by non-parent contract', async () => {
82 | const transaction = {
83 | to: erc1155MetadataContract.address,
84 | data: '0x122f94bf00000000000000000000000000000000000000000000000000000000000000' +
85 | '20000000000000000000000000000000000000000000000000000000000000000a48454c' +
86 | '4c4f544553542f00000000000000000000000000000000000000000000'
87 | }
88 | const tx = ownerWallet.sendTransaction(transaction)
89 | await expect(tx).to.be.rejectedWith(RevertError('ERC1155MetadataMock: INVALID_METHOD'))
90 | })
91 |
92 | })
93 |
94 | describe('_logURIs(uint256[]) function', () => {
95 | const ids = [1, 44, 19283091823]
96 |
97 | it('should ALLOW inheriting contract to call _logURIs()', async () => {
98 | const tx = erc1155MetadataContract.functions.logURIsMock(ids);
99 | await expect(tx).to.be.fulfilled
100 | })
101 |
102 | it('Should revert if called directly by non-parent contract', async () => {
103 | const transaction = {
104 | to: erc1155MetadataContract.address,
105 | data: '0x78d76ac2000000000000000000000000000000000000000000000000000000000000002' +
106 | '0000000000000000000000000000000000000000000000000000000000000000300000000000000' +
107 | '0000000000000000000000000000000000000000000000000100000000000000000000000000000' +
108 | '0000000000000000000000000000000002c00000000000000000000000000000000000000000000' +
109 | '0000000000047d5ca16f'
110 | }
111 | const tx = ownerWallet.sendTransaction(transaction)
112 | await expect(tx).to.be.rejectedWith(RevertError('ERC1155MetadataMock: INVALID_METHOD'))
113 | })
114 |
115 | it('should emit N URI events', async () => {
116 | const tx = await erc1155MetadataContract.functions.logURIsMock(ids) as ethers.ContractTransaction
117 | const receipt = await tx.wait(1)
118 | const URIevents = receipt.events!.filter(uri => uri.event === 'URI')
119 | expect(receipt.events!.length == ids.length)
120 | })
121 |
122 | it('should emit URI events with correct information', async () => {
123 | const tx = await erc1155MetadataContract.functions.logURIsMock(ids) as ethers.ContractTransaction
124 | const receipt = await tx.wait(1)
125 | receipt.events!
126 | .filter(uri => uri.event === 'URI')
127 | .forEach(ev => {
128 | let args = erc1155MetadataContract.interface.events.URI.decode(ev.data, ev.topics)
129 | expect(args._uri).to.be.equal(BASE_URI + args._id + '.json')
130 | })
131 | })
132 | })
133 |
134 | describe('_logURIs(uint256[],string[]) function', () => {
135 | const ids = [1, 44, 19283091823]
136 | const URIs = ids.map(id => BASE_URI + id + '.json')
137 |
138 | it('should ALLOW inheriting contract to call _logURIs()', async () => {
139 | const tx = erc1155MetadataContract.functions.logURIsMock2(ids, URIs);
140 | await expect(tx).to.be.fulfilled
141 | })
142 |
143 | it('Should revert if called directly by non-parent contract', async () => {
144 | const transaction = {
145 | to: erc1155MetadataContract.address,
146 | data: '0xb7fc7804000000000000000000000000000000000000000000000000000000000000004' +
147 | '000000000000000000000000000000000000000000000000000000000000000c000000000000000' +
148 | '0000000000000000000000000000000000000000000000000300000000000000000000000000000' +
149 | '0000000000000000000000000000000000100000000000000000000000000000000000000000000' +
150 | '0000000000000000002c000000000000000000000000000000000000000000000000000000047d5' +
151 | 'ca16f00000000000000000000000000000000000000000000000000000000000000030000000000' +
152 | '0000000000000000000000000000000000000000000000000000600000000000000000000000000' +
153 | '0000000000000000000000000000000000000e00000000000000000000000000000000000000000' +
154 | '0000000000000000000001600000000000000000000000000000000000000000000000000000000' +
155 | '00000005768747470733a2f2f6173736574732e736b797765617665722e6e65742f633637396136' +
156 | '353737633132633437393438303834646436316137396239353938646231376363352f66756c6c2' +
157 | 'd63617264732f312e6a736f6e000000000000000000000000000000000000000000000000000000' +
158 | '000000000000000000000000005868747470733a2f2f6173736574732e736b797765617665722e6' +
159 | 'e65742f633637396136353737633132633437393438303834646436316137396239353938646231' +
160 | '376363352f66756c6c2d63617264732f34342e6a736f6e000000000000000000000000000000000' +
161 | '0000000000000000000000000000000000000000000006168747470733a2f2f6173736574732e73' +
162 | '6b797765617665722e6e65742f63363739613635373763313263343739343830383464643631613' +
163 | '7396239353938646231376363352f66756c6c2d63617264732f31393238333039313832332e6a73' +
164 | '6f6e00000000000000000000000000000000000000000000000000000000000000'
165 | }
166 | const tx = ownerWallet.sendTransaction(transaction)
167 | await expect(tx).to.be.rejectedWith(RevertError('ERC1155MetadataMock: INVALID_METHOD'))
168 | })
169 |
170 | it('should emit N URI events', async () => {
171 | const tx = await erc1155MetadataContract.functions.logURIsMock2(ids, URIs)
172 | const receipt = await tx.wait(1)
173 | const URIevents = receipt.events!.filter(uri => uri.event === 'URI')
174 | expect(receipt.events!.length == ids.length)
175 | })
176 |
177 | it('should emit URI events with correct information', async () => {
178 | const tx = await erc1155MetadataContract.functions.logURIsMock2(ids, URIs)
179 | const receipt = await tx.wait(1)
180 | receipt.events!
181 | .filter(uri => uri.event === 'URI')
182 | .forEach(ev => {
183 | let args = erc1155MetadataContract.interface.events.URI.decode(ev.data, ev.topics)
184 | expect(args._uri).to.be.equal(BASE_URI + args._id + '.json')
185 | })
186 | })
187 | })
188 |
189 | })
190 | })
191 |
--------------------------------------------------------------------------------
/typings/contracts/ERC1155MetaMintBurnMock.d.ts:
--------------------------------------------------------------------------------
1 | /* Generated by ts-generator ver. 0.0.8 */
2 | /* tslint:disable */
3 |
4 | import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
5 | import { Listener, Provider } from "ethers/providers";
6 | import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
7 | import {
8 | TransactionOverrides,
9 | TypedEventDescription,
10 | TypedFunctionDescription
11 | } from ".";
12 |
13 | interface ERC1155MetaMintBurnMockInterface extends Interface {
14 | functions: {
15 | metaSafeBatchTransferFrom: TypedFunctionDescription<{
16 | encode([_from, _to, _ids, _amounts, _isGasFee, _data]: [
17 | string,
18 | string,
19 | (BigNumberish)[],
20 | (BigNumberish)[],
21 | boolean,
22 | Arrayish
23 | ]): string;
24 | }>;
25 |
26 | metaSafeTransferFrom: TypedFunctionDescription<{
27 | encode([_from, _to, _id, _amount, _isGasFee, _data]: [
28 | string,
29 | string,
30 | BigNumberish,
31 | BigNumberish,
32 | boolean,
33 | Arrayish
34 | ]): string;
35 | }>;
36 |
37 | metaSetApprovalForAll: TypedFunctionDescription<{
38 | encode([_owner, _operator, _approved, _isGasFee, _data]: [
39 | string,
40 | string,
41 | boolean,
42 | boolean,
43 | Arrayish
44 | ]): string;
45 | }>;
46 |
47 | safeBatchTransferFrom: TypedFunctionDescription<{
48 | encode([_from, _to, _ids, _amounts, _data]: [
49 | string,
50 | string,
51 | (BigNumberish)[],
52 | (BigNumberish)[],
53 | Arrayish
54 | ]): string;
55 | }>;
56 |
57 | safeTransferFrom: TypedFunctionDescription<{
58 | encode([_from, _to, _id, _amount, _data]: [
59 | string,
60 | string,
61 | BigNumberish,
62 | BigNumberish,
63 | Arrayish
64 | ]): string;
65 | }>;
66 |
67 | setApprovalForAll: TypedFunctionDescription<{
68 | encode([_operator, _approved]: [string, boolean]): string;
69 | }>;
70 |
71 | mintMock: TypedFunctionDescription<{
72 | encode([_to, _id, _value, _data]: [
73 | string,
74 | BigNumberish,
75 | BigNumberish,
76 | Arrayish
77 | ]): string;
78 | }>;
79 |
80 | batchMintMock: TypedFunctionDescription<{
81 | encode([_to, _ids, _values, _data]: [
82 | string,
83 | (BigNumberish)[],
84 | (BigNumberish)[],
85 | Arrayish
86 | ]): string;
87 | }>;
88 |
89 | burnMock: TypedFunctionDescription<{
90 | encode([_from, _id, _value]: [
91 | string,
92 | BigNumberish,
93 | BigNumberish
94 | ]): string;
95 | }>;
96 |
97 | batchBurnMock: TypedFunctionDescription<{
98 | encode([_from, _ids, _values]: [
99 | string,
100 | (BigNumberish)[],
101 | (BigNumberish)[]
102 | ]): string;
103 | }>;
104 | };
105 |
106 | events: {
107 | ApprovalForAll: TypedEventDescription<{
108 | encodeTopics([_owner, _operator, _approved]: [
109 | string | null,
110 | string | null,
111 | null
112 | ]): string[];
113 | }>;
114 |
115 | TransferBatch: TypedEventDescription<{
116 | encodeTopics([_operator, _from, _to, _ids, _amounts]: [
117 | string | null,
118 | string | null,
119 | string | null,
120 | null,
121 | null
122 | ]): string[];
123 | }>;
124 |
125 | TransferSingle: TypedEventDescription<{
126 | encodeTopics([_operator, _from, _to, _id, _amount]: [
127 | string | null,
128 | string | null,
129 | string | null,
130 | null,
131 | null
132 | ]): string[];
133 | }>;
134 |
135 | URI: TypedEventDescription<{
136 | encodeTopics([_uri, _id]: [null, BigNumberish | null]): string[];
137 | }>;
138 | };
139 | }
140 |
141 | export class ERC1155MetaMintBurnMock extends Contract {
142 | connect(
143 | signerOrProvider: Signer | Provider | string
144 | ): ERC1155MetaMintBurnMock;
145 | attach(addressOrName: string): ERC1155MetaMintBurnMock;
146 | deployed(): Promise;
147 |
148 | on(event: EventFilter | string, listener: Listener): ERC1155MetaMintBurnMock;
149 | once(
150 | event: EventFilter | string,
151 | listener: Listener
152 | ): ERC1155MetaMintBurnMock;
153 | addListener(
154 | eventName: EventFilter | string,
155 | listener: Listener
156 | ): ERC1155MetaMintBurnMock;
157 | removeAllListeners(eventName: EventFilter | string): ERC1155MetaMintBurnMock;
158 | removeListener(eventName: any, listener: Listener): ERC1155MetaMintBurnMock;
159 |
160 | interface: ERC1155MetaMintBurnMockInterface;
161 |
162 | functions: {
163 | balanceOf(_owner: string, _id: BigNumberish): Promise;
164 |
165 | balanceOfBatch(
166 | _owners: (string)[],
167 | _ids: (BigNumberish)[]
168 | ): Promise<(BigNumber)[]>;
169 |
170 | getNonce(_signer: string): Promise;
171 |
172 | isApprovedForAll(_owner: string, _operator: string): Promise;
173 |
174 | isValidSignature(
175 | _signerAddress: string,
176 | _hash: Arrayish,
177 | _data: Arrayish,
178 | _sig: Arrayish
179 | ): Promise;
180 |
181 | supportsInterface(_interfaceID: Arrayish): Promise;
182 |
183 | uri(_id: BigNumberish): Promise;
184 |
185 | metaSafeBatchTransferFrom(
186 | _from: string,
187 | _to: string,
188 | _ids: (BigNumberish)[],
189 | _amounts: (BigNumberish)[],
190 | _isGasFee: boolean,
191 | _data: Arrayish,
192 | overrides?: TransactionOverrides
193 | ): Promise;
194 |
195 | metaSafeTransferFrom(
196 | _from: string,
197 | _to: string,
198 | _id: BigNumberish,
199 | _amount: BigNumberish,
200 | _isGasFee: boolean,
201 | _data: Arrayish,
202 | overrides?: TransactionOverrides
203 | ): Promise;
204 |
205 | metaSetApprovalForAll(
206 | _owner: string,
207 | _operator: string,
208 | _approved: boolean,
209 | _isGasFee: boolean,
210 | _data: Arrayish,
211 | overrides?: TransactionOverrides
212 | ): Promise;
213 |
214 | safeBatchTransferFrom(
215 | _from: string,
216 | _to: string,
217 | _ids: (BigNumberish)[],
218 | _amounts: (BigNumberish)[],
219 | _data: Arrayish,
220 | overrides?: TransactionOverrides
221 | ): Promise;
222 |
223 | safeTransferFrom(
224 | _from: string,
225 | _to: string,
226 | _id: BigNumberish,
227 | _amount: BigNumberish,
228 | _data: Arrayish,
229 | overrides?: TransactionOverrides
230 | ): Promise;
231 |
232 | setApprovalForAll(
233 | _operator: string,
234 | _approved: boolean,
235 | overrides?: TransactionOverrides
236 | ): Promise;
237 |
238 | mintMock(
239 | _to: string,
240 | _id: BigNumberish,
241 | _value: BigNumberish,
242 | _data: Arrayish,
243 | overrides?: TransactionOverrides
244 | ): Promise;
245 |
246 | batchMintMock(
247 | _to: string,
248 | _ids: (BigNumberish)[],
249 | _values: (BigNumberish)[],
250 | _data: Arrayish,
251 | overrides?: TransactionOverrides
252 | ): Promise;
253 |
254 | burnMock(
255 | _from: string,
256 | _id: BigNumberish,
257 | _value: BigNumberish,
258 | overrides?: TransactionOverrides
259 | ): Promise;
260 |
261 | batchBurnMock(
262 | _from: string,
263 | _ids: (BigNumberish)[],
264 | _values: (BigNumberish)[],
265 | overrides?: TransactionOverrides
266 | ): Promise;
267 | };
268 |
269 | filters: {
270 | ApprovalForAll(
271 | _owner: string | null,
272 | _operator: string | null,
273 | _approved: null
274 | ): EventFilter;
275 |
276 | TransferBatch(
277 | _operator: string | null,
278 | _from: string | null,
279 | _to: string | null,
280 | _ids: null,
281 | _amounts: null
282 | ): EventFilter;
283 |
284 | TransferSingle(
285 | _operator: string | null,
286 | _from: string | null,
287 | _to: string | null,
288 | _id: null,
289 | _amount: null
290 | ): EventFilter;
291 |
292 | URI(_uri: null, _id: BigNumberish | null): EventFilter;
293 | };
294 |
295 | estimate: {
296 | metaSafeBatchTransferFrom(
297 | _from: string,
298 | _to: string,
299 | _ids: (BigNumberish)[],
300 | _amounts: (BigNumberish)[],
301 | _isGasFee: boolean,
302 | _data: Arrayish
303 | ): Promise;
304 |
305 | metaSafeTransferFrom(
306 | _from: string,
307 | _to: string,
308 | _id: BigNumberish,
309 | _amount: BigNumberish,
310 | _isGasFee: boolean,
311 | _data: Arrayish
312 | ): Promise;
313 |
314 | metaSetApprovalForAll(
315 | _owner: string,
316 | _operator: string,
317 | _approved: boolean,
318 | _isGasFee: boolean,
319 | _data: Arrayish
320 | ): Promise;
321 |
322 | safeBatchTransferFrom(
323 | _from: string,
324 | _to: string,
325 | _ids: (BigNumberish)[],
326 | _amounts: (BigNumberish)[],
327 | _data: Arrayish
328 | ): Promise;
329 |
330 | safeTransferFrom(
331 | _from: string,
332 | _to: string,
333 | _id: BigNumberish,
334 | _amount: BigNumberish,
335 | _data: Arrayish
336 | ): Promise;
337 |
338 | setApprovalForAll(
339 | _operator: string,
340 | _approved: boolean
341 | ): Promise;
342 |
343 | mintMock(
344 | _to: string,
345 | _id: BigNumberish,
346 | _value: BigNumberish,
347 | _data: Arrayish
348 | ): Promise;
349 |
350 | batchMintMock(
351 | _to: string,
352 | _ids: (BigNumberish)[],
353 | _values: (BigNumberish)[],
354 | _data: Arrayish
355 | ): Promise;
356 |
357 | burnMock(
358 | _from: string,
359 | _id: BigNumberish,
360 | _value: BigNumberish
361 | ): Promise;
362 |
363 | batchBurnMock(
364 | _from: string,
365 | _ids: (BigNumberish)[],
366 | _values: (BigNumberish)[]
367 | ): Promise;
368 | };
369 | }
370 |
--------------------------------------------------------------------------------
/contracts/tokens/ERC1155/ERC1155.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.12;
2 |
3 | import "../../interfaces/IERC165.sol";
4 | import "../../utils/SafeMath.sol";
5 | import "../../interfaces/IERC1155TokenReceiver.sol";
6 | import "../../interfaces/IERC1155.sol";
7 | import "../../utils/Address.sol";
8 |
9 |
10 | /**
11 | * @dev Implementation of Multi-Token Standard contract
12 | */
13 | contract ERC1155 is IERC165 {
14 | using SafeMath for uint256;
15 | using Address for address;
16 |
17 |
18 | /***********************************|
19 | | Variables and Events |
20 | |__________________________________*/
21 |
22 | // onReceive function signatures
23 | bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
24 | bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;
25 |
26 | // Objects balances
27 | mapping (address => mapping(uint256 => uint256)) internal balances;
28 |
29 | // Operator Functions
30 | mapping (address => mapping(address => bool)) internal operators;
31 |
32 | // Events
33 | event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount);
34 | event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts);
35 | event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
36 | event URI(string _uri, uint256 indexed _id);
37 |
38 |
39 | /***********************************|
40 | | Public Transfer Functions |
41 | |__________________________________*/
42 |
43 | /**
44 | * @notice Transfers amount amount of an _id from the _from address to the _to address specified
45 | * @param _from Source address
46 | * @param _to Target address
47 | * @param _id ID of the token type
48 | * @param _amount Transfered amount
49 | * @param _data Additional data with no specified format, sent in call to `_to`
50 | */
51 | function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data)
52 | public
53 | {
54 | require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR");
55 | require(_to != address(0),"ERC1155#safeTransferFrom: INVALID_RECIPIENT");
56 | // require(_amount >= balances[_from][_id]) is not necessary since checked with safemath operations
57 |
58 | _safeTransferFrom(_from, _to, _id, _amount);
59 | _callonERC1155Received(_from, _to, _id, _amount, _data);
60 | }
61 |
62 | /**
63 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
64 | * @param _from Source addresses
65 | * @param _to Target addresses
66 | * @param _ids IDs of each token type
67 | * @param _amounts Transfer amounts per token type
68 | * @param _data Additional data with no specified format, sent in call to `_to`
69 | */
70 | function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
71 | public
72 | {
73 | // Requirements
74 | require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR");
75 | require(_to != address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT");
76 |
77 | _safeBatchTransferFrom(_from, _to, _ids, _amounts);
78 | _callonERC1155BatchReceived(_from, _to, _ids, _amounts, _data);
79 | }
80 |
81 |
82 | /***********************************|
83 | | Internal Transfer Functions |
84 | |__________________________________*/
85 |
86 | /**
87 | * @notice Transfers amount amount of an _id from the _from address to the _to address specified
88 | * @param _from Source address
89 | * @param _to Target address
90 | * @param _id ID of the token type
91 | * @param _amount Transfered amount
92 | */
93 | function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount)
94 | internal
95 | {
96 | // Update balances
97 | balances[_from][_id] = balances[_from][_id].sub(_amount); // Subtract amount
98 | balances[_to][_id] = balances[_to][_id].add(_amount); // Add amount
99 |
100 | // Emit event
101 | emit TransferSingle(msg.sender, _from, _to, _id, _amount);
102 | }
103 |
104 | /**
105 | * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...)
106 | */
107 | function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data)
108 | internal
109 | {
110 | // Check if recipient is contract
111 | if (_to.isContract()) {
112 | bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received(msg.sender, _from, _id, _amount, _data);
113 | require(retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE");
114 | }
115 | }
116 |
117 | /**
118 | * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
119 | * @param _from Source addresses
120 | * @param _to Target addresses
121 | * @param _ids IDs of each token type
122 | * @param _amounts Transfer amounts per token type
123 | */
124 | function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts)
125 | internal
126 | {
127 | require(_ids.length == _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH");
128 |
129 | // Number of transfer to execute
130 | uint256 nTransfer = _ids.length;
131 |
132 | // Executing all transfers
133 | for (uint256 i = 0; i < nTransfer; i++) {
134 | // Update storage balance of previous bin
135 | balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]);
136 | balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]);
137 | }
138 |
139 | // Emit event
140 | emit TransferBatch(msg.sender, _from, _to, _ids, _amounts);
141 | }
142 |
143 | /**
144 | * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...)
145 | */
146 | function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
147 | internal
148 | {
149 | // Pass data if recipient is contract
150 | if (_to.isContract()) {
151 | bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived(msg.sender, _from, _ids, _amounts, _data);
152 | require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE");
153 | }
154 | }
155 |
156 |
157 | /***********************************|
158 | | Operator Functions |
159 | |__________________________________*/
160 |
161 | /**
162 | * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
163 | * @param _operator Address to add to the set of authorized operators
164 | * @param _approved True if the operator is approved, false to revoke approval
165 | */
166 | function setApprovalForAll(address _operator, bool _approved)
167 | external
168 | {
169 | // Update operator status
170 | operators[msg.sender][_operator] = _approved;
171 | emit ApprovalForAll(msg.sender, _operator, _approved);
172 | }
173 |
174 | /**
175 | * @notice Queries the approval status of an operator for a given owner
176 | * @param _owner The owner of the Tokens
177 | * @param _operator Address of authorized operator
178 | * @return True if the operator is approved, false if not
179 | */
180 | function isApprovedForAll(address _owner, address _operator)
181 | public view returns (bool isOperator)
182 | {
183 | return operators[_owner][_operator];
184 | }
185 |
186 |
187 | /***********************************|
188 | | Balance Functions |
189 | |__________________________________*/
190 |
191 | /**
192 | * @notice Get the balance of an account's Tokens
193 | * @param _owner The address of the token holder
194 | * @param _id ID of the Token
195 | * @return The _owner's balance of the Token type requested
196 | */
197 | function balanceOf(address _owner, uint256 _id)
198 | public view returns (uint256)
199 | {
200 | return balances[_owner][_id];
201 | }
202 |
203 | /**
204 | * @notice Get the balance of multiple account/token pairs
205 | * @param _owners The addresses of the token holders
206 | * @param _ids ID of the Tokens
207 | * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
208 | */
209 | function balanceOfBatch(address[] memory _owners, uint256[] memory _ids)
210 | public view returns (uint256[] memory)
211 | {
212 | require(_owners.length == _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH");
213 |
214 | // Variables
215 | uint256[] memory batchBalances = new uint256[](_owners.length);
216 |
217 | // Iterate over each owner and token ID
218 | for (uint256 i = 0; i < _owners.length; i++) {
219 | batchBalances[i] = balances[_owners[i]][_ids[i]];
220 | }
221 |
222 | return batchBalances;
223 | }
224 |
225 |
226 | /***********************************|
227 | | ERC165 Functions |
228 | |__________________________________*/
229 |
230 | /**
231 | * INTERFACE_SIGNATURE_ERC165 = bytes4(keccak256("supportsInterface(bytes4)"));
232 | */
233 | bytes4 constant private INTERFACE_SIGNATURE_ERC165 = 0x01ffc9a7;
234 |
235 | /**
236 | * INTERFACE_SIGNATURE_ERC1155 =
237 | * bytes4(keccak256("safeTransferFrom(address,address,uint256,uint256,bytes)")) ^
238 | * bytes4(keccak256("safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)")) ^
239 | * bytes4(keccak256("balanceOf(address,uint256)")) ^
240 | * bytes4(keccak256("balanceOfBatch(address[],uint256[])")) ^
241 | * bytes4(keccak256("setApprovalForAll(address,bool)")) ^
242 | * bytes4(keccak256("isApprovedForAll(address,address)"));
243 | */
244 | bytes4 constant private INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;
245 |
246 | /**
247 | * @notice Query if a contract implements an interface
248 | * @param _interfaceID The interface identifier, as specified in ERC-165
249 | * @return `true` if the contract implements `_interfaceID` and
250 | */
251 | function supportsInterface(bytes4 _interfaceID) external view returns (bool) {
252 | if (_interfaceID == INTERFACE_SIGNATURE_ERC165 ||
253 | _interfaceID == INTERFACE_SIGNATURE_ERC1155) {
254 | return true;
255 | }
256 | return false;
257 | }
258 |
259 | }
260 |
--------------------------------------------------------------------------------