Repository: hyperledger/firefly
Pull request #1131 (2023-01-06 20:01:25)

Add docs on passing ABI info to token pools
Part of [FIR-16](https://github.com/hyperledger/firefly-fir/pull/16).

This links out to the READMEs of both token connectors for "more details", so these PRs are relevant to be merged alongside this one:
https://github.com/hyperledger/firefly-tokens-erc20-erc721/pull/108
https://github.com/hyperledger/firefly-tokens-erc1155/pull/107


Patch:
diff --git a/db/migrations/postgres/000104_add_tokenpool_interface.down.sql b/db/migrations/postgres/000104_add_tokenpool_interface.down.sql
deleted file mode 100644
index 5904ab788..000000000
--- a/db/migrations/postgres/000104_add_tokenpool_interface.down.sql
+++ /dev/null
@@ -1,5 +0,0 @@
-BEGIN;
-ALTER TABLE tokenpool DROP COLUMN interface;
-ALTER TABLE tokenpool DROP COLUMN interface_format;
-ALTER TABLE tokenpool DROP COLUMN methods;
-COMMIT;
diff --git a/db/migrations/postgres/000104_add_tokenpool_interface.up.sql b/db/migrations/postgres/000104_add_tokenpool_interface.up.sql
deleted file mode 100644
index e9cde90ab..000000000
--- a/db/migrations/postgres/000104_add_tokenpool_interface.up.sql
+++ /dev/null
@@ -1,5 +0,0 @@
-BEGIN;
-ALTER TABLE tokenpool ADD COLUMN interface UUID;
-ALTER TABLE tokenpool ADD COLUMN interface_format VARCHAR(64);
-ALTER TABLE tokenpool ADD COLUMN methods TEXT;
-COMMIT;
diff --git a/db/migrations/sqlite/000104_add_tokenpool_interface.down.sql b/db/migrations/sqlite/000104_add_tokenpool_interface.down.sql
deleted file mode 100644
index 5fb099251..000000000
--- a/db/migrations/sqlite/000104_add_tokenpool_interface.down.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-ALTER TABLE tokenpool DROP COLUMN interface;
-ALTER TABLE tokenpool DROP COLUMN interface_format;
-ALTER TABLE tokenpool DROP COLUMN methods;
diff --git a/db/migrations/sqlite/000104_add_tokenpool_interface.up.sql b/db/migrations/sqlite/000104_add_tokenpool_interface.up.sql
deleted file mode 100644
index 9df94d535..000000000
--- a/db/migrations/sqlite/000104_add_tokenpool_interface.up.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-ALTER TABLE tokenpool ADD COLUMN interface UUID;
-ALTER TABLE tokenpool ADD COLUMN interface_format VARCHAR(64);
-ALTER TABLE tokenpool ADD COLUMN methods TEXT;
diff --git a/docs/reference/types/tokenpool.md b/docs/reference/types/tokenpool.md
index ba20c576d..8dfd14c52 100644
--- a/docs/reference/types/tokenpool.md
+++ b/docs/reference/types/tokenpool.md
@@ -67,9 +67,6 @@ nav_order: 10
 | `config` | Input only field, with token connector specific configuration of the pool, such as an existing Ethereum address and block number to used to index the pool. See your chosen token connector documentation for details | [`JSONObject`](simpletypes#jsonobject) |
 | `info` | Token connector specific information about the pool. See your chosen token connector documentation for details | [`JSONObject`](simpletypes#jsonobject) |
 | `tx` | Reference to the FireFly transaction used to create and broadcast this pool to the network | [`TransactionRef`](#transactionref) |
-| `interface` | A reference to an existing FFI, containing pre-registered type information for the token contract | [`FFIReference`](#ffireference) |
-| `interfaceFormat` | The interface encoding format supported by the connector for this token pool | `FFEnum`:<br/>`"abi"`<br/>`"ffi"` |
-| `methods` | The method definitions resolved by the token connector to be used by each token operation | [`JSONAny`](simpletypes#jsonany) |
 
 ## TransactionRef
 
@@ -79,12 +76,3 @@ nav_order: 10
 | `id` | The UUID of the FireFly transaction | [`UUID`](simpletypes#uuid) |
 
 
-## FFIReference
-
-| Field Name | Description | Type |
-|------------|-------------|------|
-| `id` | The UUID of the FireFly interface | [`UUID`](simpletypes#uuid) |
-| `name` | The name of the FireFly interface | `string` |
-| `version` | The version of the FireFly interface | `string` |
-
-
diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml
index 11d18379e..c0640c9f5 100644
--- a/docs/swagger/swagger.yaml
+++ b/docs/swagger/swagger.yaml
@@ -26238,16 +26238,6 @@ paths:
         name: id
         schema:
           type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: interface
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: interfaceformat
-        schema:
-          type: string
       - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
         in: query
         name: locator
@@ -26359,28 +26349,6 @@ paths:
                       description: Token connector specific information about the
                         pool. See your chosen token connector documentation for details
                       type: object
-                    interface:
-                      description: A reference to an existing FFI, containing pre-registered
-                        type information for the token contract
-                      properties:
-                        id:
-                          description: The UUID of the FireFly interface
-                          format: uuid
-                          type: string
-                        name:
-                          description: The name of the FireFly interface
-                          type: string
-                        version:
-                          description: The version of the FireFly interface
-                          type: string
-                      type: object
-                    interfaceFormat:
-                      description: The interface encoding format supported by the
-                        connector for this token pool
-                      enum:
-                      - abi
-                      - ffi
-                      type: string
                     key:
                       description: The signing key used to create the token pool.
                         On input for token connectors that support on-chain deployment
@@ -26396,9 +26364,6 @@ paths:
                         the network to index this pool
                       format: uuid
                       type: string
-                    methods:
-                      description: The method definitions resolved by the token connector
-                        to be used by each token operation
                     name:
                       description: The name of the token pool. Note the name is not
                         validated against the description of the token on the blockchain
@@ -26493,21 +26458,6 @@ paths:
                   description: An optional identifier to allow idempotent submission
                     of requests. Stored on the transaction uniquely within a namespace
                   type: string
-                interface:
-                  description: A reference to an existing FFI, containing pre-registered
-                    type information for the token contract
-                  properties:
-                    id:
-                      description: The UUID of the FireFly interface
-                      format: uuid
-                      type: string
-                    name:
-                      description: The name of the FireFly interface
-                      type: string
-                    version:
-                      description: The version of the FireFly interface
-                      type: string
-                  type: object
                 key:
                   description: The signing key used to create the token pool. On input
                     for token connectors that support on-chain deployment of new tokens
@@ -26559,28 +26509,6 @@ paths:
                     description: Token connector specific information about the pool.
                       See your chosen token connector documentation for details
                     type: object
-                  interface:
-                    description: A reference to an existing FFI, containing pre-registered
-                      type information for the token contract
-                    properties:
-                      id:
-                        description: The UUID of the FireFly interface
-                        format: uuid
-                        type: string
-                      name:
-                        description: The name of the FireFly interface
-                        type: string
-                      version:
-                        description: The version of the FireFly interface
-                        type: string
-                    type: object
-                  interfaceFormat:
-                    description: The interface encoding format supported by the connector
-                      for this token pool
-                    enum:
-                    - abi
-                    - ffi
-                    type: string
                   key:
                     description: The signing key used to create the token pool. On
                       input for token connectors that support on-chain deployment
@@ -26596,9 +26524,6 @@ paths:
                       the network to index this pool
                     format: uuid
                     type: string
-                  methods:
-                    description: The method definitions resolved by the token connector
-                      to be used by each token operation
                   name:
                     description: The name of the token pool. Note the name is not
                       validated against the description of the token on the blockchain
@@ -26669,28 +26594,6 @@ paths:
                     description: Token connector specific information about the pool.
                       See your chosen token connector documentation for details
                     type: object
-                  interface:
-                    description: A reference to an existing FFI, containing pre-registered
-                      type information for the token contract
-                    properties:
-                      id:
-                        description: The UUID of the FireFly interface
-                        format: uuid
-                        type: string
-                      name:
-                        description: The name of the FireFly interface
-                        type: string
-                      version:
-                        description: The version of the FireFly interface
-                        type: string
-                    type: object
-                  interfaceFormat:
-                    description: The interface encoding format supported by the connector
-                      for this token pool
-                    enum:
-                    - abi
-                    - ffi
-                    type: string
                   key:
                     description: The signing key used to create the token pool. On
                       input for token connectors that support on-chain deployment
@@ -26706,9 +26609,6 @@ paths:
                       the network to index this pool
                     format: uuid
                     type: string
-                  methods:
-                    description: The method definitions resolved by the token connector
-                      to be used by each token operation
                   name:
                     description: The name of the token pool. Note the name is not
                       validated against the description of the token on the blockchain
@@ -26809,28 +26709,6 @@ paths:
                     description: Token connector specific information about the pool.
                       See your chosen token connector documentation for details
                     type: object
-                  interface:
-                    description: A reference to an existing FFI, containing pre-registered
-                      type information for the token contract
-                    properties:
-                      id:
-                        description: The UUID of the FireFly interface
-                        format: uuid
-                        type: string
-                      name:
-                        description: The name of the FireFly interface
-                        type: string
-                      version:
-                        description: The version of the FireFly interface
-                        type: string
-                    type: object
-                  interfaceFormat:
-                    description: The interface encoding format supported by the connector
-                      for this token pool
-                    enum:
-                    - abi
-                    - ffi
-                    type: string
                   key:
                     description: The signing key used to create the token pool. On
                       input for token connectors that support on-chain deployment
@@ -26846,9 +26724,6 @@ paths:
                       the network to index this pool
                     format: uuid
                     type: string
-                  methods:
-                    description: The method definitions resolved by the token connector
-                      to be used by each token operation
                   name:
                     description: The name of the token pool. Note the name is not
                       validated against the description of the token on the blockchain
@@ -33657,16 +33532,6 @@ paths:
         name: id
         schema:
           type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: interface
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: interfaceformat
-        schema:
-          type: string
       - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
         in: query
         name: locator
@@ -33778,28 +33643,6 @@ paths:
                       description: Token connector specific information about the
                         pool. See your chosen token connector documentation for details
                       type: object
-                    interface:
-                      description: A reference to an existing FFI, containing pre-registered
-                        type information for the token contract
-                      properties:
-                        id:
-                          description: The UUID of the FireFly interface
-                          format: uuid
-                          type: string
-                        name:
-                          description: The name of the FireFly interface
-                          type: string
-                        version:
-                          description: The version of the FireFly interface
-                          type: string
-                      type: object
-                    interfaceFormat:
-                      description: The interface encoding format supported by the
-                        connector for this token pool
-                      enum:
-                      - abi
-                      - ffi
-                      type: string
                     key:
                       description: The signing key used to create the token pool.
                         On input for token connectors that support on-chain deployment
@@ -33815,9 +33658,6 @@ paths:
                         the network to index this pool
                       format: uuid
                       type: string
-                    methods:
-                      description: The method definitions resolved by the token connector
-                        to be used by each token operation
                     name:
                       description: The name of the token pool. Note the name is not
                         validated against the description of the token on the blockchain
@@ -33905,21 +33745,6 @@ paths:
                   description: An optional identifier to allow idempotent submission
                     of requests. Stored on the transaction uniquely within a namespace
                   type: string
-                interface:
-                  description: A reference to an existing FFI, containing pre-registered
-                    type information for the token contract
-                  properties:
-                    id:
-                      description: The UUID of the FireFly interface
-                      format: uuid
-                      type: string
-                    name:
-                      description: The name of the FireFly interface
-                      type: string
-                    version:
-                      description: The version of the FireFly interface
-                      type: string
-                  type: object
                 key:
                   description: The signing key used to create the token pool. On input
                     for token connectors that support on-chain deployment of new tokens
@@ -33971,28 +33796,6 @@ paths:
                     description: Token connector specific information about the pool.
                       See your chosen token connector documentation for details
                     type: object
-                  interface:
-                    description: A reference to an existing FFI, containing pre-registered
-                      type information for the token contract
-                    properties:
-                      id:
-                        description: The UUID of the FireFly interface
-                        format: uuid
-                        type: string
-                      name:
-                        description: The name of the FireFly interface
-                        type: string
-                      version:
-                        description: The version of the FireFly interface
-                        type: string
-                    type: object
-                  interfaceFormat:
-                    description: The interface encoding format supported by the connector
-                      for this token pool
-                    enum:
-                    - abi
-                    - ffi
-                    type: string
                   key:
                     description: The signing key used to create the token pool. On
                       input for token connectors that support on-chain deployment
@@ -34008,9 +33811,6 @@ paths:
                       the network to index this pool
                     format: uuid
                     type: string
-                  methods:
-                    description: The method definitions resolved by the token connector
-                      to be used by each token operation
                   name:
                     description: The name of the token pool. Note the name is not
                       validated against the description of the token on the blockchain
@@ -34081,28 +33881,6 @@ paths:
                     description: Token connector specific information about the pool.
                       See your chosen token connector documentation for details
                     type: object
-                  interface:
-                    description: A reference to an existing FFI, containing pre-registered
-                      type information for the token contract
-                    properties:
-                      id:
-                        description: The UUID of the FireFly interface
-                        format: uuid
-                        type: string
-                      name:
-                        description: The name of the FireFly interface
-                        type: string
-                      version:
-                        description: The version of the FireFly interface
-                        type: string
-                    type: object
-                  interfaceFormat:
-                    description: The interface encoding format supported by the connector
-                      for this token pool
-                    enum:
-                    - abi
-                    - ffi
-                    type: string
                   key:
                     description: The signing key used to create the token pool. On
                       input for token connectors that support on-chain deployment
@@ -34118,9 +33896,6 @@ paths:
                       the network to index this pool
                     format: uuid
                     type: string
-                  methods:
-                    description: The method definitions resolved by the token connector
-                      to be used by each token operation
                   name:
                     description: The name of the token pool. Note the name is not
                       validated against the description of the token on the blockchain
@@ -34214,28 +33989,6 @@ paths:
                     description: Token connector specific information about the pool.
                       See your chosen token connector documentation for details
                     type: object
-                  interface:
-                    description: A reference to an existing FFI, containing pre-registered
-                      type information for the token contract
-                    properties:
-                      id:
-                        description: The UUID of the FireFly interface
-                        format: uuid
-                        type: string
-                      name:
-                        description: The name of the FireFly interface
-                        type: string
-                      version:
-                        description: The version of the FireFly interface
-                        type: string
-                    type: object
-                  interfaceFormat:
-                    description: The interface encoding format supported by the connector
-                      for this token pool
-                    enum:
-                    - abi
-                    - ffi
-                    type: string
                   key:
                     description: The signing key used to create the token pool. On
                       input for token connectors that support on-chain deployment
@@ -34251,9 +34004,6 @@ paths:
                       the network to index this pool
                     format: uuid
                     type: string
-                  methods:
-                    description: The method definitions resolved by the token connector
-                      to be used by each token operation
                   name:
                     description: The name of the token pool. Note the name is not
                       validated against the description of the token on the blockchain
diff --git a/docs/tutorials/tokens/erc1155.md b/docs/tutorials/tokens/erc1155.md
index 342a25f4f..537c6ed7b 100644
--- a/docs/tutorials/tokens/erc1155.md
+++ b/docs/tutorials/tokens/erc1155.md
@@ -24,7 +24,7 @@ If you haven't set up the FireFly CLI already, please go back to the Getting Sta
 [← ① Install the FireFly CLI](../../gettingstarted/firefly_cli.md){: .btn .btn-purple .mb-5}
 
 ## Create a stack with an ERC-1155 connector
-The default Token Connector that the FireFly CLI sets up is for ERC-20 and ERC-721. If you would like to work with ERC-1155 tokens, you need to create a stack that is configured to use that Token Connector. To do that, run:
+The default token connector that the FireFly CLI sets up is for ERC-20 and ERC-721. If you would like to work with ERC-1155 tokens, you need to create a stack that is configured to use that token connector. To do that, run:
 ```
 ff init -t erc1155
 ```
@@ -34,13 +34,17 @@ Then run:
 ff start <your_stack_name>
 ```
 
+## About the sample token contract
+When the FireFly CLI set up your FireFly stack, it also deployed a sample ERC-1155 contract that conforms to the expectations of the token connector. When you create a token pool through FireFly's token APIs, that contract will be used by default.
+
+<div style="color: #ffffff; background: #ff7700; padding: 1em; border-radius: 5px;">⚠️ <span style="font-weight: bold;">WARNING</span>: The default token contract that was deployed by the FireFly CLI is only provided for the purpose of learning about FireFly. It is <span style="font-weight: bold;">not</span> a production grade contract. If you intend to deploy a production application using tokens on FireFly, you should research token contract best practices. For details, <a style="color: #ffffff;" href="https://github.com/hyperledger/firefly-tokens-erc1155/blob/main/samples/solidity/contracts/ERC1155MixedFungible.sol">please see the source code</a> for the contract that was deployed.</div>
+
 ## Use the Sandbox (optional)
-At this point you could open the Sandbox to http://localhost:3000/home?action=tokens.pools and perform the functions outlined in the rest of this guide. Or you can keep reading to learn how to build HTTP requests to work with tokens in FireFly.
+At this point you could open the Sandbox at [http://127.0.0.1:5109/home?action=tokens.pools](http://127.0.0.1:5109/home?action=tokens.pools) and perform the functions outlined in the rest of this guide. Or you can keep reading to learn how to build HTTP requests to work with tokens in FireFly.
 ![Tokens Sandbox](../../images/sandbox/sandbox_token_pool.png) 
 
-## Create a pool
-After you stack is up and running, the first thing you need to do is create a Token Pool. Every application will need at least one Token Pool. At a minimum, you must always
-specify a `name` and `type` (`fungible` or `nonfungible`) for the pool.
+## Create a pool (using default token contract)
+After your stack is up and running, the first thing you need to do is create a token pool. Every application will need at least one token pool. At a minimum, you must always specify a `name` and `type` (`fungible` or `nonfungible`) for the pool.
 
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/pools`
 
@@ -56,10 +60,32 @@ Other parameters:
 - You may pass through a `config` object of additional parameters, if supported by your token connector
 - You may specify a `key` understood by the connector (i.e. an Ethereum address) if you'd like to use a non-default signing identity
 
+## Create a pool (from a deployed token contract)
+If you wish to use a contract that is already on the chain, it is recommended that you first upload the ABI for your specific contract by [creating a FireFly contract interface](../custom_contracts/ethereum.md). This step is optional if you're certain that your ERC-1155 ABI conforms to the default expectations of the token connector, but is generally recommended.
+
+See the [README](https://github.com/hyperledger/firefly-tokens-erc1155/blob/main/README.md) of the token connector for details on what contract variants can currently be understood.
+
+You can pass a `config` object with an `address` when you make the request to create the token pool, and if you created a contract interface, you can include the `interface` ID as well.
+
+`POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/pools`
+
+```json
+{
+  "name": "testpool",
+  "type": "fungible",
+  "interface": {
+    "id": "b9e5e1ce-97bb-4a35-a25c-52c7c3f523d8"
+  },
+  "config": {
+    "address": "0xb1C845D32966c79E23f733742Ed7fCe4B41901FC"
+  }
+}
+```
+
 ## Mint tokens
 
-Once you have a token pool, you can mint tokens within it. With the default `firefly-tokens-erc1155` connector,
-only the creator of a pool is allowed to mint - but each connector may define its own permission model.
+Once you have a token pool, you can mint tokens within it. With the default sample contract,
+only the creator of a pool is allowed to mint - but each contract may define its own permission model.
 
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/mint`
 
@@ -77,7 +103,7 @@ Other parameters:
 ## Transfer tokens
 
 You may transfer tokens within a pool by specifying an amount and a destination understood by the connector (i.e. an Ethereum address).
-With the default `firefly-tokens-erc1155` connector, only the owner of a token may transfer it away - but each connector may define its
+With the default sample contract, only the owner of a token or another approved account may transfer it away - but each contract may define its
 own permission model.
 
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/transfers`
@@ -147,7 +173,7 @@ the recipients of the message will be able to view the actual message data.
 
 ## Burn tokens
 
-You may burn tokens by simply specifying an amount. With the default `firefly-tokens-erc1155` connector, only the owner of a token may
+You may burn tokens by simply specifying an amount. With the default sample contract, only the owner of a token or another approved account may
 burn it - but each connector may define its own permission model.
 
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/burn`
diff --git a/docs/tutorials/tokens/erc20.md b/docs/tutorials/tokens/erc20.md
index 5f045531e..3953b7c4d 100644
--- a/docs/tutorials/tokens/erc20.md
+++ b/docs/tutorials/tokens/erc20.md
@@ -22,21 +22,19 @@ If you haven't started a FireFly stack already, please go to the Getting Started
 
 [← ② Start your environment](../../gettingstarted/setup_env.md){: .btn .btn-purple .mb-5}
 
-## Use the built in sample token factory
-
+## About the sample token contracts
 If you are using the default ERC-20 / ERC-721 token connector, when the FireFly CLI set up your FireFly stack, it also deployed a token factory contract. When you create a token pool through FireFly's token APIs, the token factory contract will automatically deploy an ERC-20 or ERC-721 contract, based on the pool `type` in the API request.
 
-<div style="color: #ffffff; background: #ff7700; padding: 1em; border-radius: 5px;">⚠️ <span style="font-weight: bold;">WARNING</span>: The default token contract that was deployed by the FireFly CLI is only provided for the purpose of learning about FireFly. It is <span style="font-weight: bold;">not</span> a production grade contract. If you intend to deploy a production application using tokens FireFly you should research token contract best practices. For details, <a style="color: #ffffff;" href="https://github.com/hyperledger/firefly-tokens-erc20-erc721/blob/main/samples/solidity/contracts/TokenFactory.sol">please see the source code</a> for the contract that was deployed.</div>
+<div style="color: #ffffff; background: #ff7700; padding: 1em; border-radius: 5px;">⚠️ <span style="font-weight: bold;">WARNING</span>: The default token contract that was deployed by the FireFly CLI is only provided for the purpose of learning about FireFly. It is <span style="font-weight: bold;">not</span> a production grade contract. If you intend to deploy a production application using tokens on FireFly, you should research token contract best practices. For details, <a style="color: #ffffff;" href="https://github.com/hyperledger/firefly-tokens-erc20-erc721/blob/main/samples/solidity/contracts/TokenFactory.sol">please see the source code</a> for the contract that was deployed.</div>
 
 ## Use the Sandbox (optional)
 At this point you could open the Sandbox at [http://127.0.0.1:5109/home?action=tokens.pools](http://127.0.0.1:5109/home?action=tokens.pools) and perform the functions outlined in the rest of this guide. Or you can keep reading to learn how to build HTTP requests to work with tokens in FireFly.
 ![Tokens Sandbox](../../images/sandbox/sandbox_token_pool.png) 
 
-## Create a pool
-After your stack is up and running, the first thing you need to do is create a Token Pool. Every application will need at least one Token Pool. At a minimum, you must always
-specify a `name` and `type` for the pool.
+## Create a pool (using default token factory)
+After your stack is up and running, the first thing you need to do is create a token pool. Every application will need at least one token pool. At a minimum, you must always specify a `name` and `type` for the pool.
 
-If you're using the default ERC-20 / ERC-721 token connector and its sample token factory, it will automatically deploy a new token contract, based on the `type` in the request to create the token pool.
+If you're using the default ERC-20 / ERC-721 token connector and its sample token factory, it will automatically deploy a new ERC-20 contract instance.
 
 #### Request
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/pools`
@@ -71,7 +69,7 @@ Other parameters:
 
 ### Get the address of the deployed contract
 
-To lookup the address of the new contract, you can lookup the Token Pool by its ID on the API. Creating the token pool will also emit an event which will contain the address. To query the token pool you can make a `GET` request to the pool's ID:
+To lookup the address of the new contract, you can lookup the token pool by its ID on the API. Creating the token pool will also emit an event which will contain the address. To query the token pool you can make a `GET` request to the pool's ID:
 
 #### Request
 `GET` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/pools/5811e8d5-52d0-44b1-8b75-73f5ff88f598`
@@ -102,26 +100,35 @@ To lookup the address of the new contract, you can lookup the Token Pool by its
 }
 ```
 
-### Create a pool for an existing contract
-If you wish to use a contract that is already on the chain, you can pass the address in a `config` object with an `address` when you make the request to create the Token Pool.
+## Create a pool (from a deployed token contract)
+If you wish to index and use a contract that is already on the chain, it is recommended that you first upload the ABI for your specific contract by [creating a FireFly contract interface](../custom_contracts/ethereum.md). This step is optional if you're certain that your ERC-20 ABI conforms to the default expectations of the token connector, but is generally recommended.
+
+See the [README](https://github.com/hyperledger/firefly-tokens-erc20-erc721/blob/main/README.md) of the token connector for details on what contract variants can currently be understood.
+
+You can pass a `config` object with an `address` and `blockNumber` when you make the request to create the token pool, and if you created a contract interface, you can include the `interface` ID as well.
 
+#### Request
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/pools`
 
 ```json
 {
   "name": "testpool",
   "type": "fungible",
+  "interface": {
+    "id": "b9e5e1ce-97bb-4a35-a25c-52c7c3f523d8"
+  },
   "config": {
-    "address": "0xb1C845D32966c79E23f733742Ed7fCe4B41901FC"
+    "address": "0xb1C845D32966c79E23f733742Ed7fCe4B41901FC",
+    "blockNumber": "0"
   }
 }
 ```
 
 ## Mint tokens
 
-Once you have a token pool, you can mint tokens within it. With a token contract deployed by the default token factory, only the creator of a pool is allowed to mint, but a different contract may define its own permission model.
+Once you have a token pool, you can mint tokens within it. When using the sample contract deployed by the CLI, only the creator of a pool is allowed to mint, but a different contract may define its own permission model.
 
-> **NOTE:** The default token factory creates an ERC-20 with 18 decimal places. This means that if you want to create 100 tokens, the number submitted to the API / blockchain should actually be 100×10<sup>18</sup> = `100000000000000000000`. This allows users to work with "fractional" tokens even though Ethereum virtual machines only support integer arithmetic.
+> **NOTE:** The default sample contract uses 18 decimal places. This means that if you want to create 100 tokens, the number submitted to the API / blockchain should actually be 100×10<sup>18</sup> = `100000000000000000000`. This allows users to work with "fractional" tokens even though Ethereum virtual machines only support integer arithmetic.
 
 #### Request
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/mint`
@@ -156,7 +163,7 @@ Other parameters:
 
 ## Transfer tokens
 
-You may transfer tokens within a pool by specifying an amount and a destination understood by the connector (i.e. an Ethereum address). With a token contract deployed by the default token factory, only the owner of the tokens or another approved account may transfer their tokens, but a different contract may define its own permission model.
+You may transfer tokens within a pool by specifying an amount and a destination understood by the connector (i.e. an Ethereum address). With the default sample contract, only the owner of the tokens or another approved account may transfer their tokens, but a different contract may define its own permission model.
 
 #### Request
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/transfers`
@@ -241,8 +248,8 @@ the recipients of the message will be able to view the actual message data.
 
 ## Burn tokens
 
-You may burn tokens by simply specifying an amount. With a token contract deployed by the default token factory, only the owner of a token may
-burn it, but a different contract may define its own permission model.
+You may burn tokens by simply specifying an amount. With the default sample contract, only the owner of a token or
+another approved account may burn it, but a different contract may define its own permission model.
 
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/burn`
 
@@ -259,12 +266,13 @@ Other parameters:
 
 
 ## Token approvals
+
 You can also approve other wallets to transfer tokens on your behalf with the `/approvals` API. The important fields in a token approval API request are as follows:
 
 - `approved`: Sets whether another account is allowed to transfer tokens out of this wallet or not. If not specified, will default to `true`. Setting to `false` can revoke an existing approval.
-- `operator`: The other account that is allowed to transfer tokens out of the wallet specified in the `key` field
+- `operator`: The other account that is allowed to transfer tokens out of the wallet specified in the `key` field.
 - `config.allowance`: The number of tokens the other account is allowed to transfer. If `0` or not set, the approval is valid for any number.
-- `key`: The wallet address for the approval. If not set, it defaults to the address of the FireFly node submitting the transaction
+- `key`: The wallet address for the approval. If not set, it defaults to the address of the FireFly node submitting the transaction.
 
 Here is an example request that would let the signing account `0x634ee8c7d0894d086c7af1fc8514736aed251528` transfer up to 10×10<sup>18</sup> (`10000000000000000000`) tokens from my wallet
 
diff --git a/docs/tutorials/tokens/erc721.md b/docs/tutorials/tokens/erc721.md
index 7998744e2..403144c69 100644
--- a/docs/tutorials/tokens/erc721.md
+++ b/docs/tutorials/tokens/erc721.md
@@ -22,21 +22,19 @@ If you haven't started a FireFly stack already, please go to the Getting Started
 
 [← ② Start your environment](../../gettingstarted/setup_env.md){: .btn .btn-purple .mb-5}
 
-## Use the built in sample token factory
-
+## About the sample token contracts
 If you are using the default ERC-20 / ERC-721 token connector, when the FireFly CLI set up your FireFly stack, it also deployed a token factory contract. When you create a token pool through FireFly's token APIs, the token factory contract will automatically deploy an ERC-20 or ERC-721 contract, based on the pool `type` in the API request.
 
-<div style="color: #ffffff; background: #ff7700; padding: 1em; border-radius: 5px;">⚠️ <span style="font-weight: bold;">WARNING</span>: The default token contract that was deployed by the FireFly CLI is only provided for the purpose of learning about FireFly. It is <span style="font-weight: bold;">not</span> a production grade contract. If you intend to deploy a production application using tokens FireFly you should research token contract best practices. For details, <a style="color: #ffffff;" href="https://github.com/hyperledger/firefly-tokens-erc20-erc721/blob/main/samples/solidity/contracts/TokenFactory.sol">please see the source code</a> for the contract that was deployed.</div>
+<div style="color: #ffffff; background: #ff7700; padding: 1em; border-radius: 5px;">⚠️ <span style="font-weight: bold;">WARNING</span>: The default token contract that was deployed by the FireFly CLI is only provided for the purpose of learning about FireFly. It is <span style="font-weight: bold;">not</span> a production grade contract. If you intend to deploy a production application using tokens on FireFly, you should research token contract best practices. For details, <a style="color: #ffffff;" href="https://github.com/hyperledger/firefly-tokens-erc20-erc721/blob/main/samples/solidity/contracts/TokenFactory.sol">please see the source code</a> for the contract that was deployed.</div>
 
 ## Use the Sandbox (optional)
 At this point you could open the Sandbox at [http://127.0.0.1:5109/home?action=tokens.pools](http://127.0.0.1:5109/home?action=tokens.pools) and perform the functions outlined in the rest of this guide. Or you can keep reading to learn how to build HTTP requests to work with tokens in FireFly.
 ![Tokens Sandbox](../../images/sandbox/sandbox_token_pool.png) 
 
-## Create a pool
-After you stack is up and running, the first thing you need to do is create a Token Pool. Every application will need at least one Token Pool. At a minimum, you must always
-specify a `name` and `type` for the pool.
+## Create a pool (using default token factory)
+After your stack is up and running, the first thing you need to do is create a token pool. Every application will need at least one token pool. At a minimum, you must always specify a `name` and `type` for the pool.
 
-If you're using the default ERC-20 / ERC-721 token connector and its sample token factory, it will automatically deploy a new token contract, based on the `type` in the request to create the token pool.
+If you're using the default ERC-20 / ERC-721 token connector and its sample token factory, it will automatically deploy a new ERC-721 contract instance.
 
 #### Request
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/pools`
@@ -71,7 +69,7 @@ Other parameters:
 
 ### Get the address of the deployed contract
 
-To lookup the address of the new contract, you can lookup the Token Pool by its ID on the API. Creating the token pool will also emit an event which will contain the address. To query the token pool you can make a `GET` request to the pool's ID:
+To lookup the address of the new contract, you can lookup the token pool by its ID on the API. Creating the token pool will also emit an event which will contain the address. To query the token pool you can make a `GET` request to the pool's ID:
 
 #### Request
 `GET` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/pools/5811e8d5-52d0-44b1-8b75-73f5ff88f598`
@@ -101,26 +99,38 @@ To lookup the address of the new contract, you can lookup the Token Pool by its
 }
 ```
 
-### Create a pool for an existing contract
-If you wish to use a contract that is already on the chain, you can pass the address in a `config` object with an `address` when you make the request to create the Token Pool.
+## Create a pool (from a deployed token contract)
+If you wish to index and use a contract that is already on the chain, it is recommended that you first upload the ABI for your specific contract by [creating a FireFly contract interface](../custom_contracts/ethereum.md). This step is optional if you're certain that your ERC-721 ABI conforms to the default expectations of the token connector, but is generally recommended.
+
+See the [README](https://github.com/hyperledger/firefly-tokens-erc20-erc721/blob/main/README.md) of the token connector for details on what contract variants can currently be understood.
 
+You can pass a `config` object with an `address` and `blockNumber` when you make the request to create the token pool, and if you created a contract interface, you can include the `interface` ID as well.
+
+#### Request
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/pools`
 
 ```json
 {
   "name": "testpool",
   "type": "fungible",
+  "interface": {
+    "id": "b9e5e1ce-97bb-4a35-a25c-52c7c3f523d8"
+  },
   "config": {
-    "address": "0xb1C845D32966c79E23f733742Ed7fCe4B41901FC"
+    "address": "0xb1C845D32966c79E23f733742Ed7fCe4B41901FC",
+    "blockNumber": "0"
   }
 }
 ```
 
 ## Mint a token
 
-Once you have a token pool, you can mint tokens within it. With a token contract deployed by the default token factory, only the creator of a pool is allowed to mint, but a different contract may define its own permission model. With the default ERC-20 / ERC-721 token connector, the `tokenIndex` field must be set when minting an NFT. This is the unique index within the pool for the specific token that you are minting.
+Once you have a token pool, you can mint tokens within it. When using the sample contract deployed by the CLI, the following are true:
+* only the creator of a pool is allowed to mint within that pool
+* the `tokenIndex` must be set to a unique value
+* the `amount` must be `1`
 
-> **NOTE:** When minting NFTs the `amount` must be `1`. If you wish to mint more NFTs, simply call the endpoint multiple times.
+A different ERC-721 contract may define its own requirements.
 
 #### Request
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/mint`
@@ -156,7 +166,7 @@ Other parameters:
 
 ## Transfer a token
 
-You may transfer tokens within a pool by specifying an amount and a destination understood by the connector (i.e. an Ethereum address). With a token contract deployed by the default token factory, only the owner of the tokens or another approved account may transfer their tokens, but a different contract may define its own permission model.
+You may transfer tokens within a pool by specifying an amount and a destination understood by the connector (i.e. an Ethereum address). With the default sample contract, only the owner of the tokens or another approved account may transfer their tokens, but a different contract may define its own permission model.
 
 When transferring an NFT, you must also specify the `tokenIndex` that you wish to transfer. The `tokenIndex` is simply the ID of the specific NFT within the pool that you wish to transfer.
 
@@ -248,8 +258,7 @@ Note that all parties in the network will be able to see the transfer (including
 the recipients of the message will be able to view the actual message data.
 
 ## Burn tokens
-You may burn a token by specifying the token's `tokenIndex`. With a token contract deployed by the default token factory, only the owner of a token may
-burn it, but a different contract may define its own permission model.
+You may burn a token by specifying the token's `tokenIndex`. With the default sample contract, only the owner of a token or another approved account may burn it, but a different contract may define its own permission model.
 
 `POST` `http://127.0.0.1:5000/api/v1/namespaces/default/tokens/burn`
 
diff --git a/internal/assets/manager.go b/internal/assets/manager.go
index b16ddb606..1d292ce27 100644
--- a/internal/assets/manager.go
+++ b/internal/assets/manager.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -23,7 +23,6 @@ import (
 	"github.com/hyperledger/firefly-common/pkg/fftypes"
 	"github.com/hyperledger/firefly-common/pkg/i18n"
 	"github.com/hyperledger/firefly/internal/broadcast"
-	"github.com/hyperledger/firefly/internal/contracts"
 	"github.com/hyperledger/firefly/internal/coremsgs"
 	"github.com/hyperledger/firefly/internal/identity"
 	"github.com/hyperledger/firefly/internal/metrics"
@@ -44,7 +43,6 @@ type Manager interface {
 	GetTokenPools(ctx context.Context, filter ffapi.AndFilter) ([]*core.TokenPool, *ffapi.FilterResult, error)
 	GetTokenPool(ctx context.Context, connector, poolName string) (*core.TokenPool, error)
 	GetTokenPoolByNameOrID(ctx context.Context, poolNameOrID string) (*core.TokenPool, error)
-	ResolvePoolMethods(ctx context.Context, pool *core.TokenPool) error
 
 	GetTokenBalances(ctx context.Context, filter ffapi.AndFilter) ([]*core.TokenBalance, *ffapi.FilterResult, error)
 	GetTokenAccounts(ctx context.Context, filter ffapi.AndFilter) ([]*core.TokenAccount, *ffapi.FilterResult, error)
@@ -81,11 +79,10 @@ type assetManager struct {
 	tokens           map[string]tokens.Plugin
 	metrics          metrics.Manager
 	operations       operations.Manager
-	contracts        contracts.Manager
 	keyNormalization int
 }
 
-func NewAssetManager(ctx context.Context, ns, keyNormalization string, di database.Plugin, ti map[string]tokens.Plugin, im identity.Manager, sa syncasync.Bridge, bm broadcast.Manager, pm privatemessaging.Manager, mm metrics.Manager, om operations.Manager, cm contracts.Manager, txHelper txcommon.Helper) (Manager, error) {
+func NewAssetManager(ctx context.Context, ns, keyNormalization string, di database.Plugin, ti map[string]tokens.Plugin, im identity.Manager, sa syncasync.Bridge, bm broadcast.Manager, pm privatemessaging.Manager, mm metrics.Manager, om operations.Manager, txHelper txcommon.Helper) (Manager, error) {
 	if di == nil || im == nil || sa == nil || ti == nil || mm == nil || om == nil {
 		return nil, i18n.NewError(ctx, coremsgs.MsgInitializationNilDepError, "AssetManager")
 	}
@@ -102,7 +99,6 @@ func NewAssetManager(ctx context.Context, ns, keyNormalization string, di databa
 		keyNormalization: identity.ParseKeyNormalizationConfig(keyNormalization),
 		metrics:          mm,
 		operations:       om,
-		contracts:        cm,
 	}
 	om.RegisterHandler(ctx, am, []core.OpType{
 		core.OpTypeTokenCreatePool,
diff --git a/internal/assets/operations.go b/internal/assets/operations.go
index 5d7fb415e..d3015fa46 100644
--- a/internal/assets/operations.go
+++ b/internal/assets/operations.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -124,11 +124,11 @@ func (am *assetManager) RunOperation(ctx context.Context, op *core.PreparedOpera
 		}
 		switch data.Transfer.Type {
 		case core.TokenTransferTypeMint:
-			return nil, false, plugin.MintTokens(ctx, op.NamespacedIDString(), data.Pool.Locator, data.Transfer, data.Pool.Methods)
+			return nil, false, plugin.MintTokens(ctx, op.NamespacedIDString(), data.Pool.Locator, data.Transfer)
 		case core.TokenTransferTypeTransfer:
-			return nil, false, plugin.TransferTokens(ctx, op.NamespacedIDString(), data.Pool.Locator, data.Transfer, data.Pool.Methods)
+			return nil, false, plugin.TransferTokens(ctx, op.NamespacedIDString(), data.Pool.Locator, data.Transfer)
 		case core.TokenTransferTypeBurn:
-			return nil, false, plugin.BurnTokens(ctx, op.NamespacedIDString(), data.Pool.Locator, data.Transfer, data.Pool.Methods)
+			return nil, false, plugin.BurnTokens(ctx, op.NamespacedIDString(), data.Pool.Locator, data.Transfer)
 		default:
 			panic(fmt.Sprintf("unknown transfer type: %v", data.Transfer.Type))
 		}
@@ -138,7 +138,7 @@ func (am *assetManager) RunOperation(ctx context.Context, op *core.PreparedOpera
 		if err != nil {
 			return nil, false, err
 		}
-		return nil, false, plugin.TokensApproval(ctx, op.NamespacedIDString(), data.Pool.Locator, data.Approval, data.Pool.Methods)
+		return nil, false, plugin.TokensApproval(ctx, op.NamespacedIDString(), data.Pool.Locator, data.Approval)
 
 	default:
 		return nil, false, i18n.NewError(ctx, coremsgs.MsgOperationDataIncorrect, op.Data)
diff --git a/internal/assets/token_pool.go b/internal/assets/token_pool.go
index 93644430c..9cd1b436e 100644
--- a/internal/assets/token_pool.go
+++ b/internal/assets/token_pool.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -49,12 +49,6 @@ func (am *assetManager) CreateTokenPool(ctx context.Context, pool *core.TokenPoo
 		pool.Connector = connector
 	}
 
-	if pool.Interface != nil {
-		if err := am.contracts.ResolveFFIReference(ctx, pool.Interface); err != nil {
-			return nil, err
-		}
-	}
-
 	var err error
 	pool.Key, err = am.identity.NormalizeSigningKey(ctx, pool.Key, am.keyNormalization)
 	if err != nil {
@@ -180,15 +174,3 @@ func (am *assetManager) GetTokenPoolByNameOrID(ctx context.Context, poolNameOrID
 	}
 	return pool, nil
 }
-
-func (am *assetManager) ResolvePoolMethods(ctx context.Context, pool *core.TokenPool) error {
-	plugin, err := am.selectTokenPlugin(ctx, pool.Connector)
-	if err == nil && pool.Interface != nil && pool.Interface.ID != nil && am.contracts != nil {
-		var methods []*fftypes.FFIMethod
-		methods, err = am.contracts.GetFFIMethods(ctx, pool.Interface.ID)
-		if err == nil {
-			pool.Methods, err = plugin.CheckInterface(ctx, pool, methods)
-		}
-	}
-	return err
-}
diff --git a/internal/contracts/manager.go b/internal/contracts/manager.go
index fe7af4489..0219e2543 100644
--- a/internal/contracts/manager.go
+++ b/internal/contracts/manager.go
@@ -42,11 +42,8 @@ type Manager interface {
 	GetFFIWithChildren(ctx context.Context, name, version string) (*fftypes.FFI, error)
 	GetFFIByID(ctx context.Context, id *fftypes.UUID) (*fftypes.FFI, error)
 	GetFFIByIDWithChildren(ctx context.Context, id *fftypes.UUID) (*fftypes.FFI, error)
-	GetFFIMethods(ctx context.Context, id *fftypes.UUID) ([]*fftypes.FFIMethod, error)
-	GetFFIEvents(ctx context.Context, id *fftypes.UUID) ([]*fftypes.FFIEvent, error)
 	GetFFIs(ctx context.Context, filter ffapi.AndFilter) ([]*fftypes.FFI, *ffapi.FilterResult, error)
 	ResolveFFI(ctx context.Context, ffi *fftypes.FFI) error
-	ResolveFFIReference(ctx context.Context, ref *fftypes.FFIReference) error
 
 	DeployContract(ctx context.Context, req *core.ContractDeployRequest, waitConfirm bool) (interface{}, error)
 	InvokeContract(ctx context.Context, req *core.ContractCallRequest, waitConfirm bool) (interface{}, error)
@@ -137,30 +134,15 @@ func (cm *contractManager) GetFFIByID(ctx context.Context, id *fftypes.UUID) (*f
 	return cm.database.GetFFIByID(ctx, cm.namespace, id)
 }
 
-func (cm *contractManager) GetFFIMethods(ctx context.Context, id *fftypes.UUID) ([]*fftypes.FFIMethod, error) {
-	fb := database.FFIMethodQueryFactory.NewFilter(ctx)
-	methods, _, err := cm.database.GetFFIMethods(ctx, cm.namespace, fb.Eq("interface", id))
-	return methods, err
-}
-
-func (cm *contractManager) GetFFIEvents(ctx context.Context, id *fftypes.UUID) ([]*fftypes.FFIEvent, error) {
-	fb := database.FFIMethodQueryFactory.NewFilter(ctx)
-	events, _, err := cm.database.GetFFIEvents(ctx, cm.namespace, fb.Eq("interface", id))
-	if err == nil {
-		for _, event := range events {
-			event.Signature = cm.blockchain.GenerateEventSignature(ctx, &event.FFIEventDefinition)
-		}
-	}
-	return events, err
-}
-
 func (cm *contractManager) getFFIChildren(ctx context.Context, ffi *fftypes.FFI) (err error) {
-	ffi.Methods, err = cm.GetFFIMethods(ctx, ffi.ID)
+	mfb := database.FFIMethodQueryFactory.NewFilter(ctx)
+	ffi.Methods, _, err = cm.database.GetFFIMethods(ctx, cm.namespace, mfb.Eq("interface", ffi.ID))
 	if err != nil {
 		return err
 	}
 
-	ffi.Events, err = cm.GetFFIEvents(ctx, ffi.ID)
+	efb := database.FFIEventQueryFactory.NewFilter(ctx)
+	ffi.Events, _, err = cm.database.GetFFIEvents(ctx, cm.namespace, efb.Eq("interface", ffi.ID))
 	if err != nil {
 		return err
 	}
@@ -380,7 +362,7 @@ func (cm *contractManager) ResolveContractAPI(ctx context.Context, httpServerURL
 			}
 		}
 
-		if err := cm.ResolveFFIReference(ctx, api.Interface); err != nil {
+		if err := cm.resolveFFIReference(ctx, api.Interface); err != nil {
 			return err
 		}
 		return nil
@@ -395,7 +377,7 @@ func (cm *contractManager) ResolveContractAPI(ctx context.Context, httpServerURL
 	return nil
 }
 
-func (cm *contractManager) ResolveFFIReference(ctx context.Context, ref *fftypes.FFIReference) error {
+func (cm *contractManager) resolveFFIReference(ctx context.Context, ref *fftypes.FFIReference) error {
 	switch {
 	case ref == nil:
 		return i18n.NewError(ctx, coremsgs.MsgContractInterfaceNotFound, "")
@@ -549,7 +531,7 @@ func (cm *contractManager) validateInvokeContractRequest(ctx context.Context, re
 }
 
 func (cm *contractManager) resolveEvent(ctx context.Context, ffi *fftypes.FFIReference, eventPath string) (*core.FFISerializedEvent, error) {
-	if err := cm.ResolveFFIReference(ctx, ffi); err != nil {
+	if err := cm.resolveFFIReference(ctx, ffi); err != nil {
 		return nil, err
 	}
 	event, err := cm.database.GetFFIEvent(ctx, cm.namespace, ffi.ID, eventPath)
diff --git a/internal/coremsgs/en_error_messages.go b/internal/coremsgs/en_error_messages.go
index 4d38d05b9..99548e9c9 100644
--- a/internal/coremsgs/en_error_messages.go
+++ b/internal/coremsgs/en_error_messages.go
@@ -273,5 +273,4 @@ var (
 	MsgNonIdempotencyKeyConflictTxInsert  = ffe("FF10432", "Conflict on insert of transaction '%s'. No existing transaction matching idempotency key '%s' found", 409)
 	MsgErrorNameMustBeSet                 = ffe("FF10433", "The name of the error must be set", 400)
 	MsgContractErrorsResolveError         = ffe("FF10434", "Unable to resolve contract errors: %s", 400)
-	MsgUnknownInterfaceFormat             = ffe("FF10435", "Unknown interface format: %s", 400)
 )
diff --git a/internal/coremsgs/en_struct_descriptions.go b/internal/coremsgs/en_struct_descriptions.go
index 78049c8c1..3090dacd5 100644
--- a/internal/coremsgs/en_struct_descriptions.go
+++ b/internal/coremsgs/en_struct_descriptions.go
@@ -557,25 +557,22 @@ var (
 	TokenConnectorName = ffm("TokenConnector.name", "The name of the token connector, as configured in the FireFly core configuration file")
 
 	// TokenPool field descriptions
-	TokenPoolID              = ffm("TokenPool.id", "The UUID of the token pool")
-	TokenPoolType            = ffm("TokenPool.type", "The type of token the pool contains, such as fungible/non-fungible")
-	TokenPoolNamespace       = ffm("TokenPool.namespace", "The namespace for the token pool")
-	TokenPoolName            = ffm("TokenPool.name", "The name of the token pool. Note the name is not validated against the description of the token on the blockchain")
-	TokenPoolStandard        = ffm("TokenPool.standard", "The ERC standard the token pool conforms to, as reported by the token connector")
-	TokenPoolLocator         = ffm("TokenPool.locator", "A unique identifier for the pool, as provided by the token connector")
-	TokenPoolKey             = ffm("TokenPool.key", "The signing key used to create the token pool. On input for token connectors that support on-chain deployment of new tokens (vs. only index existing ones) this determines the signing key used to create the token on-chain")
-	TokenPoolSymbol          = ffm("TokenPool.symbol", "The token symbol. If supplied on input for an existing on-chain token, this must match the on-chain information")
-	TokenPoolDecimals        = ffm("TokenPool.decimals", "Number of decimal places that this token has")
-	TokenPoolConnector       = ffm("TokenPool.connector", "The name of the token connector, as specified in the FireFly core configuration file that is responsible for the token pool. Required on input when multiple token connectors are configured")
-	TokenPoolMessage         = ffm("TokenPool.message", "The UUID of the broadcast message used to inform the network to index this pool")
-	TokenPoolState           = ffm("TokenPool.state", "The current state of the token pool")
-	TokenPoolCreated         = ffm("TokenPool.created", "The creation time of the pool")
-	TokenPoolConfig          = ffm("TokenPool.config", "Input only field, with token connector specific configuration of the pool, such as an existing Ethereum address and block number to used to index the pool. See your chosen token connector documentation for details")
-	TokenPoolInfo            = ffm("TokenPool.info", "Token connector specific information about the pool. See your chosen token connector documentation for details")
-	TokenPoolTX              = ffm("TokenPool.tx", "Reference to the FireFly transaction used to create and broadcast this pool to the network")
-	TokenPoolInterface       = ffm("TokenPool.interface", "A reference to an existing FFI, containing pre-registered type information for the token contract")
-	TokenPoolInterfaceFormat = ffm("TokenPool.interfaceFormat", "The interface encoding format supported by the connector for this token pool")
-	TokenPoolMethods         = ffm("TokenPool.methods", "The method definitions resolved by the token connector to be used by each token operation")
+	TokenPoolID        = ffm("TokenPool.id", "The UUID of the token pool")
+	TokenPoolType      = ffm("TokenPool.type", "The type of token the pool contains, such as fungible/non-fungible")
+	TokenPoolNamespace = ffm("TokenPool.namespace", "The namespace for the token pool")
+	TokenPoolName      = ffm("TokenPool.name", "The name of the token pool. Note the name is not validated against the description of the token on the blockchain")
+	TokenPoolStandard  = ffm("TokenPool.standard", "The ERC standard the token pool conforms to, as reported by the token connector")
+	TokenPoolLocator   = ffm("TokenPool.locator", "A unique identifier for the pool, as provided by the token connector")
+	TokenPoolKey       = ffm("TokenPool.key", "The signing key used to create the token pool. On input for token connectors that support on-chain deployment of new tokens (vs. only index existing ones) this determines the signing key used to create the token on-chain")
+	TokenPoolSymbol    = ffm("TokenPool.symbol", "The token symbol. If supplied on input for an existing on-chain token, this must match the on-chain information")
+	TokenPoolDecimals  = ffm("TokenPool.decimals", "Number of decimal places that this token has")
+	TokenPoolConnector = ffm("TokenPool.connector", "The name of the token connector, as specified in the FireFly core configuration file that is responsible for the token pool. Required on input when multiple token connectors are configured")
+	TokenPoolMessage   = ffm("TokenPool.message", "The UUID of the broadcast message used to inform the network to index this pool")
+	TokenPoolState     = ffm("TokenPool.state", "The current state of the token pool")
+	TokenPoolCreated   = ffm("TokenPool.created", "The creation time of the pool")
+	TokenPoolConfig    = ffm("TokenPool.config", "Input only field, with token connector specific configuration of the pool, such as an existing Ethereum address and block number to used to index the pool. See your chosen token connector documentation for details")
+	TokenPoolInfo      = ffm("TokenPool.info", "Token connector specific information about the pool. See your chosen token connector documentation for details")
+	TokenPoolTX        = ffm("TokenPool.tx", "Reference to the FireFly transaction used to create and broadcast this pool to the network")
 
 	// TokenPoolInput field descriptions
 	TokenPoolInputIdempotencyKey = ffm("TokenPoolInput.idempotencyKey", "An optional identifier to allow idempotent submission of requests. Stored on the transaction uniquely within a namespace")
diff --git a/internal/database/sqlcommon/tokenpool_sql.go b/internal/database/sqlcommon/tokenpool_sql.go
index 6778b80ad..b06e32d1b 100644
--- a/internal/database/sqlcommon/tokenpool_sql.go
+++ b/internal/database/sqlcommon/tokenpool_sql.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -47,15 +47,11 @@ var (
 		"tx_type",
 		"tx_id",
 		"info",
-		"interface",
-		"interface_format",
-		"methods",
 	}
 	tokenPoolFilterFieldMap = map[string]string{
-		"message":         "message_id",
-		"tx.type":         "tx_type",
-		"tx.id":           "tx_id",
-		"interfaceformat": "interface_format",
+		"message": "message_id",
+		"tx.type": "tx_type",
+		"tx.id":   "tx_id",
 	}
 )
 
@@ -92,11 +88,6 @@ func (s *SQLCommon) UpsertTokenPool(ctx context.Context, pool *core.TokenPool) (
 	}
 	rows.Close()
 
-	var interfaceID *fftypes.UUID
-	if pool.Interface != nil {
-		interfaceID = pool.Interface.ID
-	}
-
 	if existing {
 		if _, err = s.UpdateTx(ctx, tokenpoolTable, tx,
 			sq.Update(tokenpoolTable).
@@ -112,9 +103,6 @@ func (s *SQLCommon) UpsertTokenPool(ctx context.Context, pool *core.TokenPool) (
 				Set("tx_type", pool.TX.Type).
 				Set("tx_id", pool.TX.ID).
 				Set("info", pool.Info).
-				Set("interface", interfaceID).
-				Set("interface_format", pool.InterfaceFormat).
-				Set("methods", pool.Methods).
 				Where(sq.Eq{"id": pool.ID}),
 			func() {
 				s.callbacks.UUIDCollectionNSEvent(database.CollectionTokenPools, core.ChangeEventTypeUpdated, pool.Namespace, pool.ID)
@@ -143,9 +131,6 @@ func (s *SQLCommon) UpsertTokenPool(ctx context.Context, pool *core.TokenPool) (
 					pool.TX.Type,
 					pool.TX.ID,
 					pool.Info,
-					interfaceID,
-					pool.InterfaceFormat,
-					pool.Methods,
 				),
 			func() {
 				s.callbacks.UUIDCollectionNSEvent(database.CollectionTokenPools, core.ChangeEventTypeCreated, pool.Namespace, pool.ID)
@@ -160,7 +145,6 @@ func (s *SQLCommon) UpsertTokenPool(ctx context.Context, pool *core.TokenPool) (
 
 func (s *SQLCommon) tokenPoolResult(ctx context.Context, row *sql.Rows) (*core.TokenPool, error) {
 	pool := core.TokenPool{}
-	iface := fftypes.FFIReference{}
 	err := row.Scan(
 		&pool.ID,
 		&pool.Namespace,
@@ -177,13 +161,7 @@ func (s *SQLCommon) tokenPoolResult(ctx context.Context, row *sql.Rows) (*core.T
 		&pool.TX.Type,
 		&pool.TX.ID,
 		&pool.Info,
-		&iface.ID,
-		&pool.InterfaceFormat,
-		&pool.Methods,
 	)
-	if iface.ID != nil {
-		pool.Interface = &iface
-	}
 	if err != nil {
 		return nil, i18n.WrapError(ctx, err, coremsgs.MsgDBReadErr, tokenpoolTable)
 	}
diff --git a/internal/events/token_pool_created.go b/internal/events/token_pool_created.go
index 7d06b835c..627f4491f 100644
--- a/internal/events/token_pool_created.go
+++ b/internal/events/token_pool_created.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -34,7 +34,6 @@ func addPoolDetailsFromPlugin(ffPool *core.TokenPool, pluginPool *tokens.TokenPo
 	ffPool.Locator = pluginPool.PoolLocator
 	ffPool.Connector = pluginPool.Connector
 	ffPool.Standard = pluginPool.Standard
-	ffPool.InterfaceFormat = (core.TokenInterfaceFormat)(pluginPool.InterfaceFormat)
 	ffPool.Decimals = pluginPool.Decimals
 	if pluginPool.TX.ID != nil {
 		ffPool.TX = pluginPool.TX
@@ -181,17 +180,9 @@ func (em *eventManager) TokenPoolCreated(ti tokens.Plugin, pool *tokens.TokenPoo
 			em.aggregator.queueMessageRewind(msgIDforRewind)
 		}
 
+		// Announce the details of the new token pool
+		// Other nodes will pass these details to their own token connector for validation/activation of the pool
 		if announcePool != nil {
-			// If the pool is tied to a contract interface, resolve the methods to be used for later operations
-			if announcePool.Interface != nil && announcePool.Interface.ID != nil && announcePool.InterfaceFormat != "" {
-				log.L(em.ctx).Infof("Querying token connector interface, id=%s", announcePool.ID)
-				if err := em.assets.ResolvePoolMethods(em.ctx, announcePool); err != nil {
-					return err
-				}
-			}
-
-			// Announce the details of the new token pool
-			// Other nodes will pass these details to their own token connector for validation/activation of the pool
 			log.L(em.ctx).Infof("Announcing token pool, id=%s", announcePool.ID)
 			err = em.defsender.DefineTokenPool(em.ctx, &core.TokenPoolAnnouncement{
 				Pool: announcePool,
diff --git a/internal/orchestrator/orchestrator.go b/internal/orchestrator/orchestrator.go
index 7b463445d..3f6f5c164 100644
--- a/internal/orchestrator/orchestrator.go
+++ b/internal/orchestrator/orchestrator.go
@@ -473,6 +473,13 @@ func (or *orchestrator) initManagers(ctx context.Context) (err error) {
 		}
 	}
 
+	if or.assets == nil {
+		or.assets, err = assets.NewAssetManager(ctx, or.namespace.Name, or.config.KeyNormalization, or.database(), or.tokens(), or.identity, or.syncasync, or.broadcast, or.messaging, or.metrics, or.operations, or.txHelper)
+		if err != nil {
+			return err
+		}
+	}
+
 	if or.blockchain() != nil {
 		if or.contracts == nil {
 			or.contracts, err = contracts.NewContractManager(ctx, or.namespace.Name, or.database(), or.blockchain(), or.identity, or.operations, or.txHelper, or.syncasync)
@@ -482,13 +489,6 @@ func (or *orchestrator) initManagers(ctx context.Context) (err error) {
 		}
 	}
 
-	if or.assets == nil {
-		or.assets, err = assets.NewAssetManager(ctx, or.namespace.Name, or.config.KeyNormalization, or.database(), or.tokens(), or.identity, or.syncasync, or.broadcast, or.messaging, or.metrics, or.operations, or.contracts, or.txHelper)
-		if err != nil {
-			return err
-		}
-	}
-
 	if or.defsender == nil {
 		or.defsender, or.defhandler, err = definitions.NewDefinitionSender(ctx, or.namespace, or.config.Multiparty.Enabled, or.database(), or.blockchain(), or.dataexchange(), or.broadcast, or.identity, or.data, or.assets, or.contracts, or.config.TokenBroadcastNames)
 		if err != nil {
diff --git a/internal/tokens/fftokens/fftokens.go b/internal/tokens/fftokens/fftokens.go
index adc1ebefb..33763d40c 100644
--- a/internal/tokens/fftokens/fftokens.go
+++ b/internal/tokens/fftokens/fftokens.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -27,8 +27,6 @@ import (
 	"github.com/hyperledger/firefly-common/pkg/i18n"
 	"github.com/hyperledger/firefly-common/pkg/log"
 	"github.com/hyperledger/firefly-common/pkg/wsclient"
-	"github.com/hyperledger/firefly-signer/pkg/abi"
-	"github.com/hyperledger/firefly-signer/pkg/ffi2abi"
 	"github.com/hyperledger/firefly/internal/coremsgs"
 	"github.com/hyperledger/firefly/pkg/blockchain"
 	"github.com/hyperledger/firefly/pkg/core"
@@ -153,16 +151,6 @@ type activatePool struct {
 	RequestID   string             `json:"requestId,omitempty"`
 }
 
-type tokenInterface struct {
-	Format  core.TokenInterfaceFormat `json:"format"`
-	Methods interface{}               `json:"methods,omitempty"`
-}
-
-type checkInterface struct {
-	tokenInterface
-	PoolLocator string `json:"poolLocator"`
-}
-
 type mintTokens struct {
 	PoolLocator string             `json:"poolLocator"`
 	TokenIndex  string             `json:"tokenIndex,omitempty"`
@@ -173,7 +161,6 @@ type mintTokens struct {
 	Data        string             `json:"data,omitempty"`
 	URI         string             `json:"uri,omitempty"`
 	Config      fftypes.JSONObject `json:"config"`
-	Interface   interface{}        `json:"interface,omitempty"`
 }
 
 type burnTokens struct {
@@ -185,7 +172,6 @@ type burnTokens struct {
 	Signer      string             `json:"signer"`
 	Data        string             `json:"data,omitempty"`
 	Config      fftypes.JSONObject `json:"config"`
-	Interface   interface{}        `json:"interface,omitempty"`
 }
 
 type transferTokens struct {
@@ -198,7 +184,6 @@ type transferTokens struct {
 	Signer      string             `json:"signer"`
 	Data        string             `json:"data,omitempty"`
 	Config      fftypes.JSONObject `json:"config"`
-	Interface   interface{}        `json:"interface,omitempty"`
 }
 
 type tokenApproval struct {
@@ -209,7 +194,6 @@ type tokenApproval struct {
 	RequestID   string             `json:"requestId,omitempty"`
 	Data        string             `json:"data,omitempty"`
 	Config      fftypes.JSONObject `json:"config"`
-	Interface   interface{}        `json:"interface,omitempty"`
 }
 
 type tokenError struct {
@@ -333,7 +317,6 @@ func (ft *FFTokens) handleTokenPoolCreate(ctx context.Context, data fftypes.JSON
 
 	// These fields are optional
 	standard := data.GetString("standard")
-	interfaceFormat := data.GetString("interfaceFormat")
 	symbol := data.GetString("symbol")
 	decimals := data.GetInt64("decimals")
 	info := data.GetObject("info")
@@ -361,13 +344,12 @@ func (ft *FFTokens) handleTokenPoolCreate(ctx context.Context, data fftypes.JSON
 			ID:   poolData.TX,
 			Type: txType,
 		},
-		Connector:       ft.configuredName,
-		Standard:        standard,
-		InterfaceFormat: interfaceFormat,
-		Symbol:          symbol,
-		Decimals:        int(decimals),
-		Info:            info,
-		Event:           ft.buildBlockchainEvent(blockchainEvent),
+		Connector: ft.configuredName,
+		Standard:  standard,
+		Symbol:    symbol,
+		Decimals:  int(decimals),
+		Info:      info,
+		Event:     ft.buildBlockchainEvent(blockchainEvent),
 	}
 
 	// If there's an error dispatching the event, we must return the error and shutdown
@@ -661,68 +643,13 @@ func (ft *FFTokens) ActivateTokenPool(ctx context.Context, nsOpID string, pool *
 	return false, nil
 }
 
-func (ft *FFTokens) prepareABI(ctx context.Context, methods []*fftypes.FFIMethod) ([]*abi.Entry, error) {
-	abiMethods := make([]*abi.Entry, len(methods))
-	for i, method := range methods {
-		abi, err := ffi2abi.ConvertFFIMethodToABI(ctx, method)
-		if err != nil {
-			return nil, err
-		}
-		abiMethods[i] = abi
-	}
-	return abiMethods, nil
-}
-
-func (ft *FFTokens) CheckInterface(ctx context.Context, pool *core.TokenPool, methods []*fftypes.FFIMethod) (*fftypes.JSONAny, error) {
-	body := checkInterface{
-		PoolLocator: pool.Locator,
-		tokenInterface: tokenInterface{
-			Format: pool.InterfaceFormat,
-		},
-	}
-
-	switch pool.InterfaceFormat {
-	case core.TokenInterfaceFormatFFI:
-		body.tokenInterface.Methods = methods
-	case core.TokenInterfaceFormatABI:
-		abi, err := ft.prepareABI(ctx, methods)
-		if err != nil {
-			return nil, err
-		}
-		body.tokenInterface.Methods = abi
-	default:
-		return nil, i18n.NewError(ctx, coremsgs.MsgUnknownInterfaceFormat, pool.InterfaceFormat)
-	}
-
-	var errRes tokenError
-	res, err := ft.client.R().SetContext(ctx).
-		SetBody(&body).
-		SetError(&errRes).
-		Post("/api/v1/checkinterface")
-	if err != nil || !res.IsSuccess() {
-		return nil, wrapError(ctx, &errRes, res, err)
-	}
-
-	var obj tokens.TokenPoolMethods
-	if err := json.Unmarshal(res.Body(), &obj); err != nil {
-		return nil, i18n.WrapError(ctx, err, i18n.MsgJSONObjectParseFailed, res.Body())
-	}
-	return fftypes.JSONAnyPtrBytes(res.Body()), nil
-}
-
-func (ft *FFTokens) MintTokens(ctx context.Context, nsOpID string, poolLocator string, mint *core.TokenTransfer, methods *fftypes.JSONAny) error {
+func (ft *FFTokens) MintTokens(ctx context.Context, nsOpID string, poolLocator string, mint *core.TokenTransfer) error {
 	data, _ := json.Marshal(tokenData{
 		TX:          mint.TX.ID,
 		TXType:      mint.TX.Type,
 		Message:     mint.Message,
 		MessageHash: mint.MessageHash,
 	})
-
-	var iface interface{}
-	if methods != nil {
-		iface = methods.JSONObject()["mint"]
-	}
-
 	var errRes tokenError
 	res, err := ft.client.R().SetContext(ctx).
 		SetBody(&mintTokens{
@@ -735,7 +662,6 @@ func (ft *FFTokens) MintTokens(ctx context.Context, nsOpID string, poolLocator s
 			Data:        string(data),
 			URI:         mint.URI,
 			Config:      mint.Config,
-			Interface:   iface,
 		}).
 		SetError(&errRes).
 		Post("/api/v1/mint")
@@ -745,19 +671,13 @@ func (ft *FFTokens) MintTokens(ctx context.Context, nsOpID string, poolLocator s
 	return nil
 }
 
-func (ft *FFTokens) BurnTokens(ctx context.Context, nsOpID string, poolLocator string, burn *core.TokenTransfer, methods *fftypes.JSONAny) error {
+func (ft *FFTokens) BurnTokens(ctx context.Context, nsOpID string, poolLocator string, burn *core.TokenTransfer) error {
 	data, _ := json.Marshal(tokenData{
 		TX:          burn.TX.ID,
 		TXType:      burn.TX.Type,
 		Message:     burn.Message,
 		MessageHash: burn.MessageHash,
 	})
-
-	var iface interface{}
-	if methods != nil {
-		iface = methods.JSONObject()["burn"]
-	}
-
 	var errRes tokenError
 	res, err := ft.client.R().SetContext(ctx).
 		SetBody(&burnTokens{
@@ -769,7 +689,6 @@ func (ft *FFTokens) BurnTokens(ctx context.Context, nsOpID string, poolLocator s
 			Signer:      burn.Key,
 			Data:        string(data),
 			Config:      burn.Config,
-			Interface:   iface,
 		}).
 		SetError(&errRes).
 		Post("/api/v1/burn")
@@ -779,19 +698,13 @@ func (ft *FFTokens) BurnTokens(ctx context.Context, nsOpID string, poolLocator s
 	return nil
 }
 
-func (ft *FFTokens) TransferTokens(ctx context.Context, nsOpID string, poolLocator string, transfer *core.TokenTransfer, methods *fftypes.JSONAny) error {
+func (ft *FFTokens) TransferTokens(ctx context.Context, nsOpID string, poolLocator string, transfer *core.TokenTransfer) error {
 	data, _ := json.Marshal(tokenData{
 		TX:          transfer.TX.ID,
 		TXType:      transfer.TX.Type,
 		Message:     transfer.Message,
 		MessageHash: transfer.MessageHash,
 	})
-
-	var iface interface{}
-	if methods != nil {
-		iface = methods.JSONObject()["transfer"]
-	}
-
 	var errRes tokenError
 	res, err := ft.client.R().SetContext(ctx).
 		SetBody(&transferTokens{
@@ -804,7 +717,6 @@ func (ft *FFTokens) TransferTokens(ctx context.Context, nsOpID string, poolLocat
 			Signer:      transfer.Key,
 			Data:        string(data),
 			Config:      transfer.Config,
-			Interface:   iface,
 		}).
 		SetError(&errRes).
 		Post("/api/v1/transfer")
@@ -814,19 +726,13 @@ func (ft *FFTokens) TransferTokens(ctx context.Context, nsOpID string, poolLocat
 	return nil
 }
 
-func (ft *FFTokens) TokensApproval(ctx context.Context, nsOpID string, poolLocator string, approval *core.TokenApproval, methods *fftypes.JSONAny) error {
+func (ft *FFTokens) TokensApproval(ctx context.Context, nsOpID string, poolLocator string, approval *core.TokenApproval) error {
 	data, _ := json.Marshal(tokenData{
 		TX:          approval.TX.ID,
 		TXType:      approval.TX.Type,
 		Message:     approval.Message,
 		MessageHash: approval.MessageHash,
 	})
-
-	var iface interface{}
-	if methods != nil {
-		iface = methods.JSONObject()["approval"]
-	}
-
 	var errRes tokenError
 	res, err := ft.client.R().SetContext(ctx).
 		SetBody(&tokenApproval{
@@ -837,7 +743,6 @@ func (ft *FFTokens) TokensApproval(ctx context.Context, nsOpID string, poolLocat
 			RequestID:   nsOpID,
 			Data:        string(data),
 			Config:      approval.Config,
-			Interface:   iface,
 		}).
 		SetError(&errRes).
 		Post("/api/v1/approval")
diff --git a/manifest.json b/manifest.json
index b70fe1450..6350410cc 100644
--- a/manifest.json
+++ b/manifest.json
@@ -21,13 +21,13 @@
   },
   "tokens-erc1155": {
     "image": "ghcr.io/hyperledger/firefly-tokens-erc1155",
-    "tag": "v1.2.0",
-    "sha": "9a7135b4d3352992832629ff644cf1a6526fef9de716711dbf00a7bf842184a6"
+    "tag": "v1.1.5",
+    "sha": "fb42ae2e1f6d4853d0cb19fee1e56175dcb3b34c2114fd890d1e0439b3e615fd"
   },
   "tokens-erc20-erc721": {
     "image": "ghcr.io/hyperledger/firefly-tokens-erc20-erc721",
-    "tag": "v1.2.0",
-    "sha": "88fbaee7d7b24682bea8fe0c00d9baa50c9a3bcc86aaed828a1f5e8ac205985a"
+    "tag": "v1.1.4",
+    "sha": "6b2ce04bfa73c38639a2cdaeec9cb01564c839b4dee5b837d73dfbd56282e19a"
   },
   "signer": {
     "image": "ghcr.io/hyperledger/firefly-signer",
diff --git a/mocks/assetmocks/manager.go b/mocks/assetmocks/manager.go
index e6e6558f6..d1511398e 100644
--- a/mocks/assetmocks/manager.go
+++ b/mocks/assetmocks/manager.go
@@ -449,20 +449,6 @@ func (_m *Manager) PrepareOperation(ctx context.Context, op *core.Operation) (*c
 	return r0, r1
 }
 
-// ResolvePoolMethods provides a mock function with given fields: ctx, pool
-func (_m *Manager) ResolvePoolMethods(ctx context.Context, pool *core.TokenPool) error {
-	ret := _m.Called(ctx, pool)
-
-	var r0 error
-	if rf, ok := ret.Get(0).(func(context.Context, *core.TokenPool) error); ok {
-		r0 = rf(ctx, pool)
-	} else {
-		r0 = ret.Error(0)
-	}
-
-	return r0
-}
-
 // RunOperation provides a mock function with given fields: ctx, op
 func (_m *Manager) RunOperation(ctx context.Context, op *core.PreparedOperation) (fftypes.JSONObject, bool, error) {
 	ret := _m.Called(ctx, op)
diff --git a/mocks/contractmocks/manager.go b/mocks/contractmocks/manager.go
index 89be0cde6..1e86b25a4 100644
--- a/mocks/contractmocks/manager.go
+++ b/mocks/contractmocks/manager.go
@@ -382,52 +382,6 @@ func (_m *Manager) GetFFIByIDWithChildren(ctx context.Context, id *fftypes.UUID)
 	return r0, r1
 }
 
-// GetFFIEvents provides a mock function with given fields: ctx, id
-func (_m *Manager) GetFFIEvents(ctx context.Context, id *fftypes.UUID) ([]*fftypes.FFIEvent, error) {
-	ret := _m.Called(ctx, id)
-
-	var r0 []*fftypes.FFIEvent
-	if rf, ok := ret.Get(0).(func(context.Context, *fftypes.UUID) []*fftypes.FFIEvent); ok {
-		r0 = rf(ctx, id)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).([]*fftypes.FFIEvent)
-		}
-	}
-
-	var r1 error
-	if rf, ok := ret.Get(1).(func(context.Context, *fftypes.UUID) error); ok {
-		r1 = rf(ctx, id)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// GetFFIMethods provides a mock function with given fields: ctx, id
-func (_m *Manager) GetFFIMethods(ctx context.Context, id *fftypes.UUID) ([]*fftypes.FFIMethod, error) {
-	ret := _m.Called(ctx, id)
-
-	var r0 []*fftypes.FFIMethod
-	if rf, ok := ret.Get(0).(func(context.Context, *fftypes.UUID) []*fftypes.FFIMethod); ok {
-		r0 = rf(ctx, id)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).([]*fftypes.FFIMethod)
-		}
-	}
-
-	var r1 error
-	if rf, ok := ret.Get(1).(func(context.Context, *fftypes.UUID) error); ok {
-		r1 = rf(ctx, id)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
 // GetFFIWithChildren provides a mock function with given fields: ctx, name, version
 func (_m *Manager) GetFFIWithChildren(ctx context.Context, name string, version string) (*fftypes.FFI, error) {
 	ret := _m.Called(ctx, name, version)
@@ -594,20 +548,6 @@ func (_m *Manager) ResolveFFI(ctx context.Context, ffi *fftypes.FFI) error {
 	return r0
 }
 
-// ResolveFFIReference provides a mock function with given fields: ctx, ref
-func (_m *Manager) ResolveFFIReference(ctx context.Context, ref *fftypes.FFIReference) error {
-	ret := _m.Called(ctx, ref)
-
-	var r0 error
-	if rf, ok := ret.Get(0).(func(context.Context, *fftypes.FFIReference) error); ok {
-		r0 = rf(ctx, ref)
-	} else {
-		r0 = ret.Error(0)
-	}
-
-	return r0
-}
-
 // RunOperation provides a mock function with given fields: ctx, op
 func (_m *Manager) RunOperation(ctx context.Context, op *core.PreparedOperation) (fftypes.JSONObject, bool, error) {
 	ret := _m.Called(ctx, op)
diff --git a/mocks/tokenmocks/plugin.go b/mocks/tokenmocks/plugin.go
index 1c5a0721d..471e79842 100644
--- a/mocks/tokenmocks/plugin.go
+++ b/mocks/tokenmocks/plugin.go
@@ -9,8 +9,6 @@ import (
 
 	core "github.com/hyperledger/firefly/pkg/core"
 
-	fftypes "github.com/hyperledger/firefly-common/pkg/fftypes"
-
 	mock "github.com/stretchr/testify/mock"
 
 	tokens "github.com/hyperledger/firefly/pkg/tokens"
@@ -42,13 +40,13 @@ func (_m *Plugin) ActivateTokenPool(ctx context.Context, nsOpID string, pool *co
 	return r0, r1
 }
 
-// BurnTokens provides a mock function with given fields: ctx, nsOpID, poolLocator, burn, methods
-func (_m *Plugin) BurnTokens(ctx context.Context, nsOpID string, poolLocator string, burn *core.TokenTransfer, methods *fftypes.JSONAny) error {
-	ret := _m.Called(ctx, nsOpID, poolLocator, burn, methods)
+// BurnTokens provides a mock function with given fields: ctx, nsOpID, poolLocator, burn
+func (_m *Plugin) BurnTokens(ctx context.Context, nsOpID string, poolLocator string, burn *core.TokenTransfer) error {
+	ret := _m.Called(ctx, nsOpID, poolLocator, burn)
 
 	var r0 error
-	if rf, ok := ret.Get(0).(func(context.Context, string, string, *core.TokenTransfer, *fftypes.JSONAny) error); ok {
-		r0 = rf(ctx, nsOpID, poolLocator, burn, methods)
+	if rf, ok := ret.Get(0).(func(context.Context, string, string, *core.TokenTransfer) error); ok {
+		r0 = rf(ctx, nsOpID, poolLocator, burn)
 	} else {
 		r0 = ret.Error(0)
 	}
@@ -72,29 +70,6 @@ func (_m *Plugin) Capabilities() *tokens.Capabilities {
 	return r0
 }
 
-// CheckInterface provides a mock function with given fields: ctx, pool, methods
-func (_m *Plugin) CheckInterface(ctx context.Context, pool *core.TokenPool, methods []*fftypes.FFIMethod) (*fftypes.JSONAny, error) {
-	ret := _m.Called(ctx, pool, methods)
-
-	var r0 *fftypes.JSONAny
-	if rf, ok := ret.Get(0).(func(context.Context, *core.TokenPool, []*fftypes.FFIMethod) *fftypes.JSONAny); ok {
-		r0 = rf(ctx, pool, methods)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*fftypes.JSONAny)
-		}
-	}
-
-	var r1 error
-	if rf, ok := ret.Get(1).(func(context.Context, *core.TokenPool, []*fftypes.FFIMethod) error); ok {
-		r1 = rf(ctx, pool, methods)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
 // CreateTokenPool provides a mock function with given fields: ctx, nsOpID, pool
 func (_m *Plugin) CreateTokenPool(ctx context.Context, nsOpID string, pool *core.TokenPool) (bool, error) {
 	ret := _m.Called(ctx, nsOpID, pool)
@@ -135,13 +110,13 @@ func (_m *Plugin) InitConfig(_a0 config.KeySet) {
 	_m.Called(_a0)
 }
 
-// MintTokens provides a mock function with given fields: ctx, nsOpID, poolLocator, mint, methods
-func (_m *Plugin) MintTokens(ctx context.Context, nsOpID string, poolLocator string, mint *core.TokenTransfer, methods *fftypes.JSONAny) error {
-	ret := _m.Called(ctx, nsOpID, poolLocator, mint, methods)
+// MintTokens provides a mock function with given fields: ctx, nsOpID, poolLocator, mint
+func (_m *Plugin) MintTokens(ctx context.Context, nsOpID string, poolLocator string, mint *core.TokenTransfer) error {
+	ret := _m.Called(ctx, nsOpID, poolLocator, mint)
 
 	var r0 error
-	if rf, ok := ret.Get(0).(func(context.Context, string, string, *core.TokenTransfer, *fftypes.JSONAny) error); ok {
-		r0 = rf(ctx, nsOpID, poolLocator, mint, methods)
+	if rf, ok := ret.Get(0).(func(context.Context, string, string, *core.TokenTransfer) error); ok {
+		r0 = rf(ctx, nsOpID, poolLocator, mint)
 	} else {
 		r0 = ret.Error(0)
 	}
@@ -187,13 +162,13 @@ func (_m *Plugin) Start() error {
 	return r0
 }
 
-// TokensApproval provides a mock function with given fields: ctx, nsOpID, poolLocator, approval, methods
-func (_m *Plugin) TokensApproval(ctx context.Context, nsOpID string, poolLocator string, approval *core.TokenApproval, methods *fftypes.JSONAny) error {
-	ret := _m.Called(ctx, nsOpID, poolLocator, approval, methods)
+// TokensApproval provides a mock function with given fields: ctx, nsOpID, poolLocator, approval
+func (_m *Plugin) TokensApproval(ctx context.Context, nsOpID string, poolLocator string, approval *core.TokenApproval) error {
+	ret := _m.Called(ctx, nsOpID, poolLocator, approval)
 
 	var r0 error
-	if rf, ok := ret.Get(0).(func(context.Context, string, string, *core.TokenApproval, *fftypes.JSONAny) error); ok {
-		r0 = rf(ctx, nsOpID, poolLocator, approval, methods)
+	if rf, ok := ret.Get(0).(func(context.Context, string, string, *core.TokenApproval) error); ok {
+		r0 = rf(ctx, nsOpID, poolLocator, approval)
 	} else {
 		r0 = ret.Error(0)
 	}
@@ -201,13 +176,13 @@ func (_m *Plugin) TokensApproval(ctx context.Context, nsOpID string, poolLocator
 	return r0
 }
 
-// TransferTokens provides a mock function with given fields: ctx, nsOpID, poolLocator, transfer, methods
-func (_m *Plugin) TransferTokens(ctx context.Context, nsOpID string, poolLocator string, transfer *core.TokenTransfer, methods *fftypes.JSONAny) error {
-	ret := _m.Called(ctx, nsOpID, poolLocator, transfer, methods)
+// TransferTokens provides a mock function with given fields: ctx, nsOpID, poolLocator, transfer
+func (_m *Plugin) TransferTokens(ctx context.Context, nsOpID string, poolLocator string, transfer *core.TokenTransfer) error {
+	ret := _m.Called(ctx, nsOpID, poolLocator, transfer)
 
 	var r0 error
-	if rf, ok := ret.Get(0).(func(context.Context, string, string, *core.TokenTransfer, *fftypes.JSONAny) error); ok {
-		r0 = rf(ctx, nsOpID, poolLocator, transfer, methods)
+	if rf, ok := ret.Get(0).(func(context.Context, string, string, *core.TokenTransfer) error); ok {
+		r0 = rf(ctx, nsOpID, poolLocator, transfer)
 	} else {
 		r0 = ret.Error(0)
 	}
diff --git a/pkg/core/tokenpool.go b/pkg/core/tokenpool.go
index af91eddeb..69d31d681 100644
--- a/pkg/core/tokenpool.go
+++ b/pkg/core/tokenpool.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -39,38 +39,28 @@ var (
 	TokenPoolStateConfirmed = fftypes.FFEnumValue("tokenpoolstate", "confirmed")
 )
 
-type TokenInterfaceFormat = fftypes.FFEnum
-
-var (
-	TokenInterfaceFormatABI = fftypes.FFEnumValue("tokeninterfaceformat", "abi")
-	TokenInterfaceFormatFFI = fftypes.FFEnumValue("tokeninterfaceformat", "ffi")
-)
-
 type TokenPoolInput struct {
 	TokenPool
 	IdempotencyKey IdempotencyKey `ffstruct:"TokenPoolInput" json:"idempotencyKey,omitempty" ffexcludeoutput:"true"`
 }
 
 type TokenPool struct {
-	ID              *fftypes.UUID         `ffstruct:"TokenPool" json:"id,omitempty" ffexcludeinput:"true"`
-	Type            TokenType             `ffstruct:"TokenPool" json:"type" ffenum:"tokentype"`
-	Namespace       string                `ffstruct:"TokenPool" json:"namespace,omitempty" ffexcludeinput:"true"`
-	Name            string                `ffstruct:"TokenPool" json:"name,omitempty"`
-	Standard        string                `ffstruct:"TokenPool" json:"standard,omitempty" ffexcludeinput:"true"`
-	Locator         string                `ffstruct:"TokenPool" json:"locator,omitempty" ffexcludeinput:"true"`
-	Key             string                `ffstruct:"TokenPool" json:"key,omitempty"`
-	Symbol          string                `ffstruct:"TokenPool" json:"symbol,omitempty"`
-	Decimals        int                   `ffstruct:"TokenPool" json:"decimals,omitempty" ffexcludeinput:"true"`
-	Connector       string                `ffstruct:"TokenPool" json:"connector,omitempty"`
-	Message         *fftypes.UUID         `ffstruct:"TokenPool" json:"message,omitempty" ffexcludeinput:"true"`
-	State           TokenPoolState        `ffstruct:"TokenPool" json:"state,omitempty" ffenum:"tokenpoolstate" ffexcludeinput:"true"`
-	Created         *fftypes.FFTime       `ffstruct:"TokenPool" json:"created,omitempty" ffexcludeinput:"true"`
-	Config          fftypes.JSONObject    `ffstruct:"TokenPool" json:"config,omitempty" ffexcludeoutput:"true"` // for REST calls only (not stored)
-	Info            fftypes.JSONObject    `ffstruct:"TokenPool" json:"info,omitempty" ffexcludeinput:"true"`
-	TX              TransactionRef        `ffstruct:"TokenPool" json:"tx,omitempty" ffexcludeinput:"true"`
-	Interface       *fftypes.FFIReference `ffstruct:"TokenPool" json:"interface,omitempty"`
-	InterfaceFormat TokenInterfaceFormat  `ffstruct:"TokenPool" json:"interfaceFormat,omitempty" ffenum:"tokeninterfaceformat" ffexcludeinput:"true"`
-	Methods         *fftypes.JSONAny      `ffstruct:"TokenPool" json:"methods,omitempty" ffexcludeinput:"true"`
+	ID        *fftypes.UUID      `ffstruct:"TokenPool" json:"id,omitempty" ffexcludeinput:"true"`
+	Type      TokenType          `ffstruct:"TokenPool" json:"type" ffenum:"tokentype"`
+	Namespace string             `ffstruct:"TokenPool" json:"namespace,omitempty" ffexcludeinput:"true"`
+	Name      string             `ffstruct:"TokenPool" json:"name,omitempty"`
+	Standard  string             `ffstruct:"TokenPool" json:"standard,omitempty" ffexcludeinput:"true"`
+	Locator   string             `ffstruct:"TokenPool" json:"locator,omitempty" ffexcludeinput:"true"`
+	Key       string             `ffstruct:"TokenPool" json:"key,omitempty"`
+	Symbol    string             `ffstruct:"TokenPool" json:"symbol,omitempty"`
+	Decimals  int                `ffstruct:"TokenPool" json:"decimals,omitempty" ffexcludeinput:"true"`
+	Connector string             `ffstruct:"TokenPool" json:"connector,omitempty"`
+	Message   *fftypes.UUID      `ffstruct:"TokenPool" json:"message,omitempty" ffexcludeinput:"true"`
+	State     TokenPoolState     `ffstruct:"TokenPool" json:"state,omitempty" ffenum:"tokenpoolstate" ffexcludeinput:"true"`
+	Created   *fftypes.FFTime    `ffstruct:"TokenPool" json:"created,omitempty" ffexcludeinput:"true"`
+	Config    fftypes.JSONObject `ffstruct:"TokenPool" json:"config,omitempty" ffexcludeoutput:"true"` // for REST calls only (not stored)
+	Info      fftypes.JSONObject `ffstruct:"TokenPool" json:"info,omitempty" ffexcludeinput:"true"`
+	TX        TransactionRef     `ffstruct:"TokenPool" json:"tx,omitempty" ffexcludeinput:"true"`
 }
 
 type TokenPoolAnnouncement struct {
diff --git a/pkg/database/plugin.go b/pkg/database/plugin.go
index a24ca27b3..b0dd534b8 100644
--- a/pkg/database/plugin.go
+++ b/pkg/database/plugin.go
@@ -865,21 +865,19 @@ var BlobQueryFactory = &ffapi.QueryFields{
 
 // TokenPoolQueryFactory filter fields for token pools
 var TokenPoolQueryFactory = &ffapi.QueryFields{
-	"id":              &ffapi.UUIDField{},
-	"type":            &ffapi.StringField{},
-	"name":            &ffapi.StringField{},
-	"standard":        &ffapi.StringField{},
-	"locator":         &ffapi.StringField{},
-	"symbol":          &ffapi.StringField{},
-	"decimals":        &ffapi.Int64Field{},
-	"message":         &ffapi.UUIDField{},
-	"state":           &ffapi.StringField{},
-	"created":         &ffapi.TimeField{},
-	"connector":       &ffapi.StringField{},
-	"tx.type":         &ffapi.StringField{},
-	"tx.id":           &ffapi.UUIDField{},
-	"interface":       &ffapi.UUIDField{},
-	"interfaceformat": &ffapi.StringField{},
+	"id":        &ffapi.UUIDField{},
+	"type":      &ffapi.StringField{},
+	"name":      &ffapi.StringField{},
+	"standard":  &ffapi.StringField{},
+	"locator":   &ffapi.StringField{},
+	"symbol":    &ffapi.StringField{},
+	"decimals":  &ffapi.Int64Field{},
+	"message":   &ffapi.UUIDField{},
+	"state":     &ffapi.StringField{},
+	"created":   &ffapi.TimeField{},
+	"connector": &ffapi.StringField{},
+	"tx.type":   &ffapi.StringField{},
+	"tx.id":     &ffapi.UUIDField{},
 }
 
 // TokenBalanceQueryFactory filter fields for token balances
diff --git a/pkg/tokens/plugin.go b/pkg/tokens/plugin.go
index 941a56fcd..e5d7e9ae5 100644
--- a/pkg/tokens/plugin.go
+++ b/pkg/tokens/plugin.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -43,7 +43,7 @@ type Plugin interface {
 	// If namespace is set, plugin will attempt to deliver only events for that namespace
 	SetOperationHandler(namespace string, handler core.OperationCallbacks)
 
-	// Token interface must not deliver any events until start is called
+	// Blockchain interface must not deliver any events until start is called
 	Start() error
 
 	// Capabilities returns capabilities - not called until after Init
@@ -55,20 +55,17 @@ type Plugin interface {
 	// ActivateTokenPool activates a pool in order to begin receiving events
 	ActivateTokenPool(ctx context.Context, nsOpID string, pool *core.TokenPool) (complete bool, err error)
 
-	// CheckInterface checks which methods of a contract interface are supported by this connector
-	CheckInterface(ctx context.Context, pool *core.TokenPool, methods []*fftypes.FFIMethod) (*fftypes.JSONAny, error)
-
 	// MintTokens mints new tokens in a pool and adds them to the recipient's account
-	MintTokens(ctx context.Context, nsOpID string, poolLocator string, mint *core.TokenTransfer, methods *fftypes.JSONAny) error
+	MintTokens(ctx context.Context, nsOpID string, poolLocator string, mint *core.TokenTransfer) error
 
 	// BurnTokens burns tokens from an account
-	BurnTokens(ctx context.Context, nsOpID string, poolLocator string, burn *core.TokenTransfer, methods *fftypes.JSONAny) error
+	BurnTokens(ctx context.Context, nsOpID string, poolLocator string, burn *core.TokenTransfer) error
 
 	// TransferTokens transfers tokens within a pool from one account to another
-	TransferTokens(ctx context.Context, nsOpID string, poolLocator string, transfer *core.TokenTransfer, methods *fftypes.JSONAny) error
+	TransferTokens(ctx context.Context, nsOpID string, poolLocator string, transfer *core.TokenTransfer) error
 
 	// TokenApproval approves an operator to transfer tokens on the owner's behalf
-	TokensApproval(ctx context.Context, nsOpID string, poolLocator string, approval *core.TokenApproval, methods *fftypes.JSONAny) error
+	TokensApproval(ctx context.Context, nsOpID string, poolLocator string, approval *core.TokenApproval) error
 }
 
 // Callbacks is the interface provided to the tokens plugin, to allow it to pass events back to firefly.
@@ -115,10 +112,7 @@ type TokenPool struct {
 	// Standard is the well-defined token standard that this pool conforms to (optional)
 	Standard string
 
-	// InterfaceFormat is the interface encoding format understood by this connector (optional)
-	InterfaceFormat string
-
-	// Decimals is the number of decimal places that this token has (optional)
+	// Decimals is the number of decimal places that this token has
 	Decimals int
 
 	// Symbol is the short token symbol, if the connector uses one (optional)
@@ -131,14 +125,6 @@ type TokenPool struct {
 	Event *blockchain.Event
 }
 
-// TokenPoolMethods is a mapped set of interface methods to be used for various token operations
-type TokenPoolMethods struct {
-	Approval *fftypes.JSONAny `json:"approval"`
-	Burn     *fftypes.JSONAny `json:"burn"`
-	Mint     *fftypes.JSONAny `json:"mint"`
-	Transfer *fftypes.JSONAny `json:"transfer"`
-}
-
 type TokenTransfer struct {
 	// Although not every field will be filled in, embed core.TokenTransfer to avoid duplicating lots of fields
 	// Notable fields NOT expected to be populated by plugins: Namespace, LocalID, Pool


Test patch:
diff --git a/internal/assets/manager_test.go b/internal/assets/manager_test.go
index 19252e56f..36ffef150 100644
--- a/internal/assets/manager_test.go
+++ b/internal/assets/manager_test.go
@@ -6,7 +6,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//	http://www.apache.org/licenses/LICENSE-2.0
+//     http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
@@ -25,7 +25,6 @@ import (
 	"github.com/hyperledger/firefly/internal/txcommon"
 	"github.com/hyperledger/firefly/mocks/broadcastmocks"
 	"github.com/hyperledger/firefly/mocks/cachemocks"
-	"github.com/hyperledger/firefly/mocks/contractmocks"
 	"github.com/hyperledger/firefly/mocks/databasemocks"
 	"github.com/hyperledger/firefly/mocks/datamocks"
 	"github.com/hyperledger/firefly/mocks/identitymanagermocks"
@@ -64,14 +63,13 @@ func newTestAssetsCommon(t *testing.T, metrics bool) (*assetManager, func()) {
 	ctx := context.Background()
 	cmi.On("GetCache", mock.Anything).Return(cache.NewUmanagedCache(ctx, 100, 5*time.Minute), nil)
 	mom := &operationmocks.Manager{}
-	mcm := &contractmocks.Manager{}
 	txHelper, _ := txcommon.NewTransactionHelper(ctx, "ns1", mdi, mdm, cmi)
 	mm.On("IsMetricsEnabled").Return(metrics)
 	mm.On("TransferSubmitted", mock.Anything)
 	mom.On("RegisterHandler", mock.Anything, mock.Anything, mock.Anything)
 	mti.On("Name").Return("ut").Maybe()
 	ctx, cancel := context.WithCancel(ctx)
-	a, err := NewAssetManager(ctx, "ns1", "blockchain_plugin", mdi, map[string]tokens.Plugin{"magic-tokens": mti}, mim, msa, mbm, mpm, mm, mom, mcm, txHelper)
+	a, err := NewAssetManager(ctx, "ns1", "blockchain_plugin", mdi, map[string]tokens.Plugin{"magic-tokens": mti}, mim, msa, mbm, mpm, mm, mom, txHelper)
 	rag := mdi.On("RunAsGroup", mock.Anything, mock.Anything).Maybe()
 	rag.RunFn = func(a mock.Arguments) {
 		rag.ReturnArguments = mock.Arguments{a[1].(func(context.Context) error)(a[0].(context.Context))}
@@ -83,7 +81,7 @@ func newTestAssetsCommon(t *testing.T, metrics bool) (*assetManager, func()) {
 }
 
 func TestInitFail(t *testing.T) {
-	_, err := NewAssetManager(context.Background(), "", "", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
+	_, err := NewAssetManager(context.Background(), "", "", nil, nil, nil, nil, nil, nil, nil, nil, nil)
 	assert.Regexp(t, "FF10128", err)
 }
 
diff --git a/internal/assets/operations_test.go b/internal/assets/operations_test.go
index c9f89d4a2..2d132580d 100644
--- a/internal/assets/operations_test.go
+++ b/internal/assets/operations_test.go
@@ -6,7 +6,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//	http://www.apache.org/licenses/LICENSE-2.0
+//     http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
@@ -116,7 +116,7 @@ func TestPrepareAndRunTransfer(t *testing.T) {
 
 	mti := am.tokens["magic-tokens"].(*tokenmocks.Plugin)
 	mdi := am.database.(*databasemocks.Plugin)
-	mti.On("TransferTokens", context.Background(), "ns1:"+op.ID.String(), "F1", transfer, (*fftypes.JSONAny)(nil)).Return(nil)
+	mti.On("TransferTokens", context.Background(), "ns1:"+op.ID.String(), "F1", transfer).Return(nil)
 	mdi.On("GetTokenPoolByID", context.Background(), "ns1", pool.ID).Return(pool, nil)
 
 	po, err := am.PrepareOperation(context.Background(), op)
@@ -155,7 +155,7 @@ func TestPrepareAndRunApproval(t *testing.T) {
 
 	mti := am.tokens["magic-tokens"].(*tokenmocks.Plugin)
 	mdi := am.database.(*databasemocks.Plugin)
-	mti.On("TokensApproval", context.Background(), "ns1:"+op.ID.String(), "F1", approval, (*fftypes.JSONAny)(nil)).Return(nil)
+	mti.On("TokensApproval", context.Background(), "ns1:"+op.ID.String(), "F1", approval).Return(nil)
 	mdi.On("GetTokenPoolByID", context.Background(), "ns1", pool.ID).Return(pool, nil)
 
 	po, err := am.PrepareOperation(context.Background(), op)
@@ -471,35 +471,7 @@ func TestRunOperationTransferMint(t *testing.T) {
 	}
 
 	mti := am.tokens["magic-tokens"].(*tokenmocks.Plugin)
-	mti.On("MintTokens", context.Background(), "ns1:"+op.ID.String(), "F1", transfer, (*fftypes.JSONAny)(nil)).Return(nil)
-
-	_, complete, err := am.RunOperation(context.Background(), opTransfer(op, pool, transfer))
-
-	assert.False(t, complete)
-	assert.NoError(t, err)
-
-	mti.AssertExpectations(t)
-}
-
-func TestRunOperationTransferMintWithInterface(t *testing.T) {
-	am, cancel := newTestAssets(t)
-	defer cancel()
-
-	op := &core.Operation{
-		ID:        fftypes.NewUUID(),
-		Namespace: "ns1",
-	}
-	pool := &core.TokenPool{
-		Connector: "magic-tokens",
-		Locator:   "F1",
-		Methods:   fftypes.JSONAnyPtr(`{"mint": "test_interface"}`),
-	}
-	transfer := &core.TokenTransfer{
-		Type: core.TokenTransferTypeMint,
-	}
-
-	mti := am.tokens["magic-tokens"].(*tokenmocks.Plugin)
-	mti.On("MintTokens", context.Background(), "ns1:"+op.ID.String(), "F1", transfer, pool.Methods).Return(nil)
+	mti.On("MintTokens", context.Background(), "ns1:"+op.ID.String(), "F1", transfer).Return(nil)
 
 	_, complete, err := am.RunOperation(context.Background(), opTransfer(op, pool, transfer))
 
@@ -526,7 +498,7 @@ func TestRunOperationTransferBurn(t *testing.T) {
 	}
 
 	mti := am.tokens["magic-tokens"].(*tokenmocks.Plugin)
-	mti.On("BurnTokens", context.Background(), "ns1:"+op.ID.String(), "F1", transfer, (*fftypes.JSONAny)(nil)).Return(nil)
+	mti.On("BurnTokens", context.Background(), "ns1:"+op.ID.String(), "F1", transfer).Return(nil)
 
 	_, complete, err := am.RunOperation(context.Background(), opTransfer(op, pool, transfer))
 
@@ -553,7 +525,7 @@ func TestRunOperationTransfer(t *testing.T) {
 	}
 
 	mti := am.tokens["magic-tokens"].(*tokenmocks.Plugin)
-	mti.On("TransferTokens", context.Background(), "ns1:"+op.ID.String(), "F1", transfer, (*fftypes.JSONAny)(nil)).Return(nil)
+	mti.On("TransferTokens", context.Background(), "ns1:"+op.ID.String(), "F1", transfer).Return(nil)
 
 	_, complete, err := am.RunOperation(context.Background(), opTransfer(op, pool, transfer))
 
diff --git a/internal/assets/token_pool_test.go b/internal/assets/token_pool_test.go
index 7c2ace87e..18ff1c7a4 100644
--- a/internal/assets/token_pool_test.go
+++ b/internal/assets/token_pool_test.go
@@ -22,12 +22,10 @@ import (
 	"github.com/hyperledger/firefly-common/pkg/fftypes"
 	"github.com/hyperledger/firefly/internal/identity"
 	"github.com/hyperledger/firefly/internal/syncasync"
-	"github.com/hyperledger/firefly/mocks/contractmocks"
 	"github.com/hyperledger/firefly/mocks/databasemocks"
 	"github.com/hyperledger/firefly/mocks/identitymanagermocks"
 	"github.com/hyperledger/firefly/mocks/operationmocks"
 	"github.com/hyperledger/firefly/mocks/syncasyncmocks"
-	"github.com/hyperledger/firefly/mocks/tokenmocks"
 	"github.com/hyperledger/firefly/mocks/txcommonmocks"
 	"github.com/hyperledger/firefly/pkg/core"
 	"github.com/hyperledger/firefly/pkg/database"
@@ -316,33 +314,6 @@ func TestCreateTokenPoolOpInsertFail(t *testing.T) {
 	mom.AssertExpectations(t)
 }
 
-func TestCreateTokenPoolWithInterfaceFail(t *testing.T) {
-	am, cancel := newTestAssets(t)
-	defer cancel()
-
-	pool := &core.TokenPoolInput{
-		TokenPool: core.TokenPool{
-			Connector: "magic-tokens",
-			Name:      "testpool",
-			Interface: &fftypes.FFIReference{
-				ID: fftypes.NewUUID(),
-			},
-		},
-		IdempotencyKey: "idem1",
-	}
-
-	mdi := am.database.(*databasemocks.Plugin)
-	mcm := am.contracts.(*contractmocks.Manager)
-	mdi.On("GetTokenPool", context.Background(), "ns1", "testpool").Return(nil, nil)
-	mcm.On("ResolveFFIReference", context.Background(), pool.Interface).Return(fmt.Errorf("pop"))
-
-	_, err := am.CreateTokenPool(context.Background(), pool, false)
-	assert.EqualError(t, err, "pop")
-
-	mdi.AssertExpectations(t)
-	mcm.AssertExpectations(t)
-}
-
 func TestCreateTokenPoolSyncSuccess(t *testing.T) {
 	am, cancel := newTestAssets(t)
 	defer cancel()
@@ -754,30 +725,3 @@ func TestGetTokenPools(t *testing.T) {
 
 	mdi.AssertExpectations(t)
 }
-
-func TestResolvePoolMethods(t *testing.T) {
-	am, cancel := newTestAssets(t)
-	defer cancel()
-
-	pool := &core.TokenPool{
-		Connector: "magic-tokens",
-		Interface: &fftypes.FFIReference{
-			ID: fftypes.NewUUID(),
-		},
-	}
-	methods := []*fftypes.FFIMethod{{Name: "method1"}}
-	resolved := fftypes.JSONAnyPtr(`"resolved"`)
-
-	mcm := am.contracts.(*contractmocks.Manager)
-	mcm.On("GetFFIMethods", context.Background(), pool.Interface.ID).Return(methods, nil)
-
-	mti := am.tokens["magic-tokens"].(*tokenmocks.Plugin)
-	mti.On("CheckInterface", context.Background(), pool, methods).Return(resolved, nil)
-
-	err := am.ResolvePoolMethods(context.Background(), pool)
-	assert.NoError(t, err)
-	assert.Equal(t, resolved, pool.Methods)
-
-	mcm.AssertExpectations(t)
-	mti.AssertExpectations(t)
-}
diff --git a/internal/database/sqlcommon/tokenpool_sql_test.go b/internal/database/sqlcommon/tokenpool_sql_test.go
index 816b348f3..2b0813256 100644
--- a/internal/database/sqlcommon/tokenpool_sql_test.go
+++ b/internal/database/sqlcommon/tokenpool_sql_test.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -57,10 +57,6 @@ func TestTokenPoolE2EWithDB(t *testing.T) {
 		Info: fftypes.JSONObject{
 			"pool": "info",
 		},
-		Interface: &fftypes.FFIReference{
-			ID: fftypes.NewUUID(),
-		},
-		InterfaceFormat: "abi",
 	}
 
 	s.callbacks.On("UUIDCollectionNSEvent", database.CollectionTokenPools, core.ChangeEventTypeCreated, "ns1", poolID, mock.Anything).
diff --git a/internal/events/token_pool_created_test.go b/internal/events/token_pool_created_test.go
index 5723d60a2..45e3d74a0 100644
--- a/internal/events/token_pool_created_test.go
+++ b/internal/events/token_pool_created_test.go
@@ -370,57 +370,6 @@ func TestTokenPoolCreatedAnnounce(t *testing.T) {
 	mti.AssertExpectations(t)
 }
 
-func TestTokenPoolCreatedAnnounceBadInterface(t *testing.T) {
-	em := newTestEventManager(t)
-	defer em.cleanup(t)
-	mti := &tokenmocks.Plugin{}
-
-	poolID := fftypes.NewUUID()
-	txID := fftypes.NewUUID()
-	interfaceID := fftypes.NewUUID()
-	operations := []*core.Operation{
-		{
-			ID: fftypes.NewUUID(),
-			Input: fftypes.JSONObject{
-				"id":        poolID.String(),
-				"namespace": "ns1",
-				"name":      "my-pool",
-				"interface": fftypes.JSONObject{
-					"id": interfaceID.String(),
-				},
-			},
-		},
-	}
-	info := fftypes.JSONObject{"some": "info"}
-	pool := &tokens.TokenPool{
-		Type:        core.TokenTypeFungible,
-		PoolLocator: "123",
-		TX: core.TransactionRef{
-			ID:   txID,
-			Type: core.TransactionTypeTokenPool,
-		},
-		Connector: "erc1155",
-		Event: &blockchain.Event{
-			BlockchainTXID: "0xffffeeee",
-			ProtocolID:     "tx1",
-			Info:           info,
-		},
-		InterfaceFormat: "abi",
-	}
-
-	em.mdi.On("GetTokenPoolByLocator", em.ctx, "ns1", "erc1155", "123").Return(nil, nil).Times(2)
-	em.mdi.On("GetOperations", em.ctx, "ns1", mock.Anything).Return(nil, nil, fmt.Errorf("pop")).Once()
-	em.mdi.On("GetOperations", em.ctx, "ns1", mock.Anything).Return(operations, nil, nil).Once()
-	em.mam.On("ResolvePoolMethods", em.ctx, mock.MatchedBy(func(pool *core.TokenPool) bool {
-		return pool.Locator == "123" && pool.Name == "my-pool"
-	})).Return(fmt.Errorf("pop"))
-
-	err := em.TokenPoolCreated(mti, pool)
-	assert.EqualError(t, err, "pop")
-
-	mti.AssertExpectations(t)
-}
-
 func TestTokenPoolCreatedAnnounceBadOpInputID(t *testing.T) {
 	em := newTestEventManager(t)
 	defer em.cleanup(t)
diff --git a/internal/tokens/fftokens/fftokens_test.go b/internal/tokens/fftokens/fftokens_test.go
index 9736cfe55..be70801ed 100644
--- a/internal/tokens/fftokens/fftokens_test.go
+++ b/internal/tokens/fftokens/fftokens_test.go
@@ -572,65 +572,7 @@ func TestMintTokens(t *testing.T) {
 			return res, nil
 		})
 
-	err := h.MintTokens(context.Background(), nsOpID, "123", mint, nil)
-	assert.NoError(t, err)
-}
-
-func TestMintTokensWithInterface(t *testing.T) {
-	h, _, _, httpURL, done := newTestFFTokens(t)
-	defer done()
-
-	mint := &core.TokenTransfer{
-		LocalID: fftypes.NewUUID(),
-		To:      "user1",
-		Key:     "0x123",
-		Amount:  *fftypes.NewFFBigInt(10),
-		TX: core.TransactionRef{
-			ID:   fftypes.NewUUID(),
-			Type: core.TransactionTypeTokenTransfer,
-		},
-		URI: "FLAPFLIP",
-		Config: fftypes.JSONObject{
-			"foo": "bar",
-		},
-	}
-	methods := fftypes.JSONAnyPtr(`{"mint": "test_interface"}`)
-	opID := fftypes.NewUUID()
-	nsOpID := "ns1:" + opID.String()
-
-	httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/mint", httpURL),
-		func(req *http.Request) (*http.Response, error) {
-			body := make(fftypes.JSONObject)
-			err := json.NewDecoder(req.Body).Decode(&body)
-			assert.NoError(t, err)
-			assert.Equal(t, fftypes.JSONObject{
-				"poolLocator": "123",
-				"to":          "user1",
-				"amount":      "10",
-				"signer":      "0x123",
-				"config": map[string]interface{}{
-					"foo": "bar",
-				},
-				"requestId": "ns1:" + opID.String(),
-				"data": fftypes.JSONObject{
-					"tx":     mint.TX.ID.String(),
-					"txtype": core.TransactionTypeTokenTransfer.String(),
-				}.String(),
-				"uri":       "FLAPFLIP",
-				"interface": "test_interface",
-			}, body)
-
-			res := &http.Response{
-				Body: ioutil.NopCloser(bytes.NewReader([]byte(`{"id":"1"}`))),
-				Header: http.Header{
-					"Content-Type": []string{"application/json"},
-				},
-				StatusCode: 202,
-			}
-			return res, nil
-		})
-
-	err := h.MintTokens(context.Background(), nsOpID, "123", mint, methods)
+	err := h.MintTokens(context.Background(), nsOpID, "123", mint)
 	assert.NoError(t, err)
 }
 
@@ -684,7 +626,7 @@ func TestTokenApproval(t *testing.T) {
 			return res, nil
 		})
 
-	err := h.TokensApproval(context.Background(), nsOpID, "123", approval, nil)
+	err := h.TokensApproval(context.Background(), nsOpID, "123", approval)
 	assert.NoError(t, err)
 }
 
@@ -693,13 +635,12 @@ func TestTokenApprovalError(t *testing.T) {
 	defer done()
 
 	approval := &core.TokenApproval{}
-	methods := fftypes.JSONAnyPtr(`{}`)
 
 	httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/approval", httpURL),
 		httpmock.NewJsonResponderOrPanic(500, fftypes.JSONObject{}))
 
 	nsOpID := "ns1:" + fftypes.NewUUID().String()
-	err := h.TokensApproval(context.Background(), nsOpID, "F1", approval, methods)
+	err := h.TokensApproval(context.Background(), nsOpID, "F1", approval)
 	assert.Regexp(t, "FF10274", err)
 }
 
@@ -713,7 +654,7 @@ func TestMintTokensError(t *testing.T) {
 		httpmock.NewJsonResponderOrPanic(500, fftypes.JSONObject{}))
 
 	nsOpID := "ns1:" + fftypes.NewUUID().String()
-	err := h.MintTokens(context.Background(), nsOpID, "F1", mint, nil)
+	err := h.MintTokens(context.Background(), nsOpID, "F1", mint)
 	assert.Regexp(t, "FF10274", err)
 }
 
@@ -769,7 +710,7 @@ func TestBurnTokens(t *testing.T) {
 			return res, nil
 		})
 
-	err := h.BurnTokens(context.Background(), nsOpID, "123", burn, nil)
+	err := h.BurnTokens(context.Background(), nsOpID, "123", burn)
 	assert.NoError(t, err)
 }
 
@@ -778,13 +719,12 @@ func TestBurnTokensError(t *testing.T) {
 	defer done()
 
 	burn := &core.TokenTransfer{}
-	methods := fftypes.JSONAnyPtr(`{}`)
 
 	httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/burn", httpURL),
 		httpmock.NewJsonResponderOrPanic(500, fftypes.JSONObject{}))
 
 	nsOpID := "ns1:" + fftypes.NewUUID().String()
-	err := h.BurnTokens(context.Background(), nsOpID, "F1", burn, methods)
+	err := h.BurnTokens(context.Background(), nsOpID, "F1", burn)
 	assert.Regexp(t, "FF10274", err)
 }
 
@@ -842,7 +782,7 @@ func TestTransferTokens(t *testing.T) {
 			return res, nil
 		})
 
-	err := h.TransferTokens(context.Background(), nsOpID, "123", transfer, nil)
+	err := h.TransferTokens(context.Background(), nsOpID, "123", transfer)
 	assert.NoError(t, err)
 }
 
@@ -851,13 +791,12 @@ func TestTransferTokensError(t *testing.T) {
 	defer done()
 
 	transfer := &core.TokenTransfer{}
-	methods := fftypes.JSONAnyPtr(`{}`)
 
 	httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/transfer", httpURL),
 		httpmock.NewJsonResponderOrPanic(500, fftypes.JSONObject{}))
 
 	nsOpID := "ns1:" + fftypes.NewUUID().String()
-	err := h.TransferTokens(context.Background(), nsOpID, "F1", transfer, methods)
+	err := h.TransferTokens(context.Background(), nsOpID, "F1", transfer)
 	assert.Regexp(t, "FF10274", err)
 }
 
@@ -1452,179 +1391,3 @@ func TestCallbacksWrongNamespace(t *testing.T) {
 	h.callbacks.TokensTransferred(context.Background(), "ns1", nil)
 	h.callbacks.TokensApproved(context.Background(), "ns1", nil)
 }
-
-func TestCheckInterfaceBadFormat(t *testing.T) {
-	h, _, _, _, done := newTestFFTokens(t)
-	defer done()
-
-	pool := &core.TokenPool{
-		InterfaceFormat: "bad",
-	}
-
-	_, err := h.CheckInterface(context.Background(), pool, nil)
-	assert.Regexp(t, "FF10435.*bad", err)
-}
-
-func TestCheckInterfaceABI(t *testing.T) {
-	h, _, _, httpURL, done := newTestFFTokens(t)
-	defer done()
-
-	pool := &core.TokenPool{
-		InterfaceFormat: "abi",
-		Locator:         "N1",
-	}
-	methods := []*fftypes.FFIMethod{
-		{Name: "method1"},
-	}
-
-	httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/checkinterface", httpURL),
-		func(req *http.Request) (*http.Response, error) {
-			body := make(fftypes.JSONObject)
-			err := json.NewDecoder(req.Body).Decode(&body)
-			assert.NoError(t, err)
-			assert.Equal(t, fftypes.JSONObject{
-				"format":      "abi",
-				"poolLocator": "N1",
-				"methods": []interface{}{
-					map[string]interface{}{
-						"name":    "method1",
-						"type":    "function",
-						"inputs":  []interface{}{},
-						"outputs": []interface{}{},
-					},
-				},
-			}, body)
-
-			res := &http.Response{
-				Body: ioutil.NopCloser(bytes.NewReader([]byte(fftypes.JSONObject{
-					"approval": fftypes.JSONAny(`[]`),
-					"burn":     fftypes.JSONAny(`[]`),
-					"mint":     fftypes.JSONAny(`[]`),
-					"transfer": fftypes.JSONAny(`[]`),
-				}.String()))),
-				Header: http.Header{
-					"Content-Type": []string{"application/json"},
-				},
-				StatusCode: 200,
-			}
-			return res, nil
-		})
-
-	_, err := h.CheckInterface(context.Background(), pool, methods)
-	assert.NoError(t, err)
-}
-
-func TestCheckInterfaceABIBadInterface(t *testing.T) {
-	h, _, _, _, done := newTestFFTokens(t)
-	defer done()
-
-	pool := &core.TokenPool{
-		InterfaceFormat: "abi",
-		Locator:         "N1",
-	}
-	methods := []*fftypes.FFIMethod{
-		{Name: "method1", Params: fftypes.FFIParams{{Schema: fftypes.JSONAnyPtr("bad")}}},
-	}
-
-	_, err := h.CheckInterface(context.Background(), pool, methods)
-	assert.Regexp(t, "FF22052", err)
-}
-
-func TestCheckInterfaceFFI(t *testing.T) {
-	h, _, _, httpURL, done := newTestFFTokens(t)
-	defer done()
-
-	pool := &core.TokenPool{
-		InterfaceFormat: "ffi",
-		Locator:         "N1",
-	}
-	methods := []*fftypes.FFIMethod{
-		{Name: "method1"},
-	}
-
-	httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/checkinterface", httpURL),
-		func(req *http.Request) (*http.Response, error) {
-			body := make(fftypes.JSONObject)
-			err := json.NewDecoder(req.Body).Decode(&body)
-			assert.NoError(t, err)
-			assert.Equal(t, fftypes.JSONObject{
-				"format":      "ffi",
-				"poolLocator": "N1",
-				"methods": []interface{}{
-					map[string]interface{}{
-						"name":        "method1",
-						"description": "",
-						"pathname":    "",
-						"params":      nil,
-						"returns":     nil,
-					},
-				},
-			}, body)
-
-			res := &http.Response{
-				Body: ioutil.NopCloser(bytes.NewReader([]byte(fftypes.JSONObject{
-					"approval": fftypes.JSONAny(`[]`),
-					"burn":     fftypes.JSONAny(`[]`),
-					"mint":     fftypes.JSONAny(`[]`),
-					"transfer": fftypes.JSONAny(`[]`),
-				}.String()))),
-				Header: http.Header{
-					"Content-Type": []string{"application/json"},
-				},
-				StatusCode: 200,
-			}
-			return res, nil
-		})
-
-	_, err := h.CheckInterface(context.Background(), pool, methods)
-	assert.NoError(t, err)
-}
-
-func TestCheckInterfaceFFIFail(t *testing.T) {
-	h, _, _, httpURL, done := newTestFFTokens(t)
-	defer done()
-
-	pool := &core.TokenPool{
-		InterfaceFormat: "ffi",
-		Locator:         "N1",
-	}
-	methods := []*fftypes.FFIMethod{
-		{Name: "method1"},
-	}
-
-	httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/checkinterface", httpURL),
-		httpmock.NewJsonResponderOrPanic(500, fftypes.JSONObject{}))
-
-	_, err := h.CheckInterface(context.Background(), pool, methods)
-	assert.Regexp(t, "FF10274", err)
-}
-
-func TestCheckInterfaceFFIBadResponse(t *testing.T) {
-	h, _, _, httpURL, done := newTestFFTokens(t)
-	defer done()
-
-	pool := &core.TokenPool{
-		InterfaceFormat: "ffi",
-		Locator:         "N1",
-	}
-	methods := []*fftypes.FFIMethod{
-		{Name: "method1"},
-	}
-
-	httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/checkinterface", httpURL),
-		func(req *http.Request) (*http.Response, error) {
-			res := &http.Response{
-				Body: ioutil.NopCloser(bytes.NewReader([]byte(fftypes.JSONObject{
-					"approval": map[bool]bool{true: false},
-				}.String()))),
-				Header: http.Header{
-					"Content-Type": []string{"application/json"},
-				},
-				StatusCode: 200,
-			}
-			return res, nil
-		})
-
-	_, err := h.CheckInterface(context.Background(), pool, methods)
-	assert.Regexp(t, "FF00127", err)
-}
diff --git a/test/data/contracts/erc1155/ERC1155Sample.json b/test/data/contracts/erc1155/ERC1155Sample.json
deleted file mode 100644
index a51bbfc87..000000000
--- a/test/data/contracts/erc1155/ERC1155Sample.json
+++ /dev/null
@@ -1,563 +0,0 @@
-{
-  "_format": "hh-sol-artifact-1",
-  "contractName": "ERC1155MixedFungible",
-  "sourceName": "contracts/ERC1155MixedFungible.sol",
-  "abi": [
-    {
-      "inputs": [],
-      "stateMutability": "nonpayable",
-      "type": "constructor"
-    },
-    {
-      "anonymous": false,
-      "inputs": [
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "account",
-          "type": "address"
-        },
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "operator",
-          "type": "address"
-        },
-        {
-          "indexed": false,
-          "internalType": "bool",
-          "name": "approved",
-          "type": "bool"
-        }
-      ],
-      "name": "ApprovalForAll",
-      "type": "event"
-    },
-    {
-      "anonymous": false,
-      "inputs": [
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "operator",
-          "type": "address"
-        },
-        {
-          "indexed": true,
-          "internalType": "uint256",
-          "name": "type_id",
-          "type": "uint256"
-        },
-        {
-          "indexed": false,
-          "internalType": "bytes",
-          "name": "data",
-          "type": "bytes"
-        }
-      ],
-      "name": "TokenPoolCreation",
-      "type": "event"
-    },
-    {
-      "anonymous": false,
-      "inputs": [
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "operator",
-          "type": "address"
-        },
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "from",
-          "type": "address"
-        },
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "to",
-          "type": "address"
-        },
-        {
-          "indexed": false,
-          "internalType": "uint256[]",
-          "name": "ids",
-          "type": "uint256[]"
-        },
-        {
-          "indexed": false,
-          "internalType": "uint256[]",
-          "name": "values",
-          "type": "uint256[]"
-        }
-      ],
-      "name": "TransferBatch",
-      "type": "event"
-    },
-    {
-      "anonymous": false,
-      "inputs": [
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "operator",
-          "type": "address"
-        },
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "from",
-          "type": "address"
-        },
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "to",
-          "type": "address"
-        },
-        {
-          "indexed": false,
-          "internalType": "uint256",
-          "name": "id",
-          "type": "uint256"
-        },
-        {
-          "indexed": false,
-          "internalType": "uint256",
-          "name": "value",
-          "type": "uint256"
-        }
-      ],
-      "name": "TransferSingle",
-      "type": "event"
-    },
-    {
-      "anonymous": false,
-      "inputs": [
-        {
-          "indexed": false,
-          "internalType": "string",
-          "name": "value",
-          "type": "string"
-        },
-        {
-          "indexed": true,
-          "internalType": "uint256",
-          "name": "id",
-          "type": "uint256"
-        }
-      ],
-      "name": "URI",
-      "type": "event"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "account",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256",
-          "name": "id",
-          "type": "uint256"
-        }
-      ],
-      "name": "balanceOf",
-      "outputs": [
-        {
-          "internalType": "uint256",
-          "name": "",
-          "type": "uint256"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address[]",
-          "name": "accounts",
-          "type": "address[]"
-        },
-        {
-          "internalType": "uint256[]",
-          "name": "ids",
-          "type": "uint256[]"
-        }
-      ],
-      "name": "balanceOfBatch",
-      "outputs": [
-        {
-          "internalType": "uint256[]",
-          "name": "",
-          "type": "uint256[]"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "account",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256",
-          "name": "id",
-          "type": "uint256"
-        },
-        {
-          "internalType": "uint256",
-          "name": "value",
-          "type": "uint256"
-        }
-      ],
-      "name": "burn",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "account",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256[]",
-          "name": "ids",
-          "type": "uint256[]"
-        },
-        {
-          "internalType": "uint256[]",
-          "name": "values",
-          "type": "uint256[]"
-        }
-      ],
-      "name": "burnBatch",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "bool",
-          "name": "is_fungible",
-          "type": "bool"
-        },
-        {
-          "internalType": "bytes",
-          "name": "data",
-          "type": "bytes"
-        }
-      ],
-      "name": "create",
-      "outputs": [
-        {
-          "internalType": "uint256",
-          "name": "type_id",
-          "type": "uint256"
-        }
-      ],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "uint256",
-          "name": "",
-          "type": "uint256"
-        }
-      ],
-      "name": "creators",
-      "outputs": [
-        {
-          "internalType": "address",
-          "name": "",
-          "type": "address"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "account",
-          "type": "address"
-        },
-        {
-          "internalType": "address",
-          "name": "operator",
-          "type": "address"
-        }
-      ],
-      "name": "isApprovedForAll",
-      "outputs": [
-        {
-          "internalType": "bool",
-          "name": "",
-          "type": "bool"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "uint256",
-          "name": "",
-          "type": "uint256"
-        }
-      ],
-      "name": "maxIndex",
-      "outputs": [
-        {
-          "internalType": "uint256",
-          "name": "",
-          "type": "uint256"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "uint256",
-          "name": "type_id",
-          "type": "uint256"
-        },
-        {
-          "internalType": "address[]",
-          "name": "to",
-          "type": "address[]"
-        },
-        {
-          "internalType": "uint256[]",
-          "name": "amounts",
-          "type": "uint256[]"
-        },
-        {
-          "internalType": "bytes",
-          "name": "data",
-          "type": "bytes"
-        }
-      ],
-      "name": "mintFungible",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "uint256",
-          "name": "type_id",
-          "type": "uint256"
-        },
-        {
-          "internalType": "address[]",
-          "name": "to",
-          "type": "address[]"
-        },
-        {
-          "internalType": "bytes",
-          "name": "data",
-          "type": "bytes"
-        }
-      ],
-      "name": "mintNonFungible",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "uint256",
-          "name": "type_id",
-          "type": "uint256"
-        },
-        {
-          "internalType": "address[]",
-          "name": "to",
-          "type": "address[]"
-        },
-        {
-          "internalType": "bytes",
-          "name": "data",
-          "type": "bytes"
-        },
-        {
-          "internalType": "string",
-          "name": "_uri",
-          "type": "string"
-        }
-      ],
-      "name": "mintNonFungibleWithURI",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "from",
-          "type": "address"
-        },
-        {
-          "internalType": "address",
-          "name": "to",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256[]",
-          "name": "ids",
-          "type": "uint256[]"
-        },
-        {
-          "internalType": "uint256[]",
-          "name": "amounts",
-          "type": "uint256[]"
-        },
-        {
-          "internalType": "bytes",
-          "name": "data",
-          "type": "bytes"
-        }
-      ],
-      "name": "safeBatchTransferFrom",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "from",
-          "type": "address"
-        },
-        {
-          "internalType": "address",
-          "name": "to",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256",
-          "name": "id",
-          "type": "uint256"
-        },
-        {
-          "internalType": "uint256",
-          "name": "amount",
-          "type": "uint256"
-        },
-        {
-          "internalType": "bytes",
-          "name": "data",
-          "type": "bytes"
-        }
-      ],
-      "name": "safeTransferFrom",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "operator",
-          "type": "address"
-        },
-        {
-          "internalType": "bool",
-          "name": "approved",
-          "type": "bool"
-        }
-      ],
-      "name": "setApprovalForAll",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "operator",
-          "type": "address"
-        },
-        {
-          "internalType": "bool",
-          "name": "approved",
-          "type": "bool"
-        },
-        {
-          "internalType": "bytes",
-          "name": "data",
-          "type": "bytes"
-        }
-      ],
-      "name": "setApprovalForAllWithData",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "bytes4",
-          "name": "interfaceId",
-          "type": "bytes4"
-        }
-      ],
-      "name": "supportsInterface",
-      "outputs": [
-        {
-          "internalType": "bool",
-          "name": "",
-          "type": "bool"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "uint256",
-          "name": "id",
-          "type": "uint256"
-        }
-      ],
-      "name": "uri",
-      "outputs": [
-        {
-          "internalType": "string",
-          "name": "",
-          "type": "string"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    }
-  ],
-  "bytecode": "0x60806040523480156200001157600080fd5b506040518060200160405280600081525062000033816200003a60201b60201c565b506200016b565b80600290805190602001906200005292919062000056565b5050565b828054620000649062000106565b90600052602060002090601f016020900481019282620000885760008555620000d4565b82601f10620000a357805160ff1916838001178555620000d4565b82800160010185558215620000d4579182015b82811115620000d3578251825591602001919060010190620000b6565b5b509050620000e39190620000e7565b5090565b5b8082111562000102576000816000905550600101620000e8565b5090565b600060028204905060018216806200011f57607f821691505b602082108114156200013657620001356200013c565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b614312806200017b6000396000f3fe608060405234801561001057600080fd5b506004361061010a5760003560e01c806354dbdbf4116100a2578063a22cb46511610071578063a22cb465146102d7578063cd53d08e146102f3578063e985e9c514610323578063f242432a14610353578063f5298aca1461036f5761010a565b806354dbdbf4146102535780636b20c4541461026f57806371cc16561461028b5780637e53b65d146102bb5761010a565b8063183fb254116100de578063183fb254146101cf5780631cbf311d146101eb5780632eb2c2d6146102075780634e1273f4146102235761010a565b8062fdd58e1461010f57806301ffc9a71461013f57806308d7d4691461016f5780630e89341c1461019f575b600080fd5b61012960048036038101906101249190612e0a565b61038b565b60405161013691906138e1565b60405180910390f35b61015960048036038101906101549190612f59565b610454565b6040516101669190613680565b60405180910390f35b61018960048036038101906101849190612fab565b610536565b60405161019691906138e1565b60405180910390f35b6101b960048036038101906101b49190612fab565b61054e565b6040516101c691906136bf565b60405180910390f35b6101e960048036038101906101e49190612fd4565b610623565b005b61020560048036038101906102009190612d9e565b61082c565b005b610221600480360381019061021c9190612b95565b61083c565b005b61023d60048036038101906102389190612e95565b6108dd565b60405161024a9190613627565b60405180910390f35b61026d6004803603810190610268919061308d565b610a8e565b005b61028960048036038101906102849190612ce3565b610c78565b005b6102a560048036038101906102a09190612f01565b610d15565b6040516102b291906138e1565b60405180910390f35b6102d560048036038101906102d09190613116565b610e15565b005b6102f160048036038101906102ec9190612d62565b611011565b005b61030d60048036038101906103089190612fab565b611027565b60405161031a919061354a565b60405180910390f35b61033d60048036038101906103389190612b59565b61105a565b60405161034a9190613680565b60405180910390f35b61036d60048036038101906103689190612c54565b6110ee565b005b61038960048036038101906103849190612e46565b61118f565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156103fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f390613721565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061051f57507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061052f575061052e8261122c565b5b9050919050565b60056020528060005260406000206000915090505481565b6060600060066000848152602001908152602001600020805461057090613b81565b80601f016020809104026020016040519081016040528092919081815260200182805461059c90613b81565b80156105e95780601f106105be576101008083540402835291602001916105e9565b820191906000526020600020905b8154815290600101906020018083116105cc57829003601f168201915b50505050509050600081905060008151141561061857604051806020016040528060008152509250505061061e565b81925050505b919050565b8661062c611296565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461069657600080fd5b61069f8861129e565b6106de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106d5906137a1565b60405180910390fd5b848490508787905014610726576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161071d90613801565b60405180910390fd5b60005b8787905081101561082157610810888883818110610770577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906107859190612b30565b8a8888858181106107bf577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013587878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506112cc565b8061081a90613be4565b9050610729565b505050505050505050565b6108368484611011565b50505050565b610844611296565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061088a575061088985610884611296565b61105a565b5b6108c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c0906137e1565b60405180910390fd5b6108d6858585858561147d565b5050505050565b60608151835114610923576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091a90613881565b60405180910390fd5b6000835167ffffffffffffffff811115610966577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156109945781602001602082028036833780820191505090505b50905060005b8451811015610a8357610a2d8582815181106109df577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151858381518110610a20577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015161038b565b828281518110610a66577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080610a7c90613be4565b905061099a565b508091505092915050565b84610a97611296565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b0157600080fd5b610b0a866117eb565b610b49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4090613781565b60405180910390fd5b600060016005600089815260200190815260200160002054610b6b9190613a75565b9050610b8d86869050600560008a815260200190815260200160002054611819565b600560008981526020019081526020016000208190555060005b86869050811015610c6e57610c5d878783818110610bee577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610c039190612b30565b8284610c0f9190613a75565b8a17600188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506112cc565b80610c6790613be4565b9050610ba7565b5050505050505050565b610c80611296565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161480610cc65750610cc583610cc0611296565b61105a565b5b610d05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cfc90613761565b60405180910390fd5b610d1083838361182f565b505050565b60006080600360008154610d2890613be4565b919050819055901b905083610d5d577f8000000000000000000000000000000000000000000000000000000000000000811790505b610d65611296565b6004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080610dbf611296565b73ffffffffffffffffffffffffffffffffffffffff167f0d2ce24070e07853454690ae0a0416ddd4845188f8dbfe0ef3a761acb3d2e34e8585604051610e0692919061369b565b60405180910390a39392505050565b85610e1e611296565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e8857600080fd5b610e91876117eb565b610ed0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ec790613781565b60405180910390fd5b60006001600560008a815260200190815260200160002054610ef29190613a75565b9050610f1487879050600560008b815260200190815260200160002054611819565b600560008a81526020019081526020016000208190555060005b878790508110156110065760008183610f479190613a75565b8a179050610fe9898984818110610f87577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610f9c9190612b30565b8260018a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506112cc565b610ff48a8287611b4a565b5080610fff90613be4565b9050610f2e565b505050505050505050565b61102361101c611296565b8383611c33565b5050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6110f6611296565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061113c575061113b85611136611296565b61105a565b5b61117b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117290613761565b60405180910390fd5b6111888585858585611da0565b5050505050565b611197611296565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806111dd57506111dc836111d7611296565b61105a565b5b61121c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121390613761565b60405180910390fd5b61122783838361203c565b505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b6000807f80000000000000000000000000000000000000000000000000000000000000008316149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561133c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611333906138c1565b60405180910390fd5b6000611346611296565b9050600061135385612283565b9050600061136085612283565b905061137183600089858589612349565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113d09190613a75565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62898960405161144e9291906138fc565b60405180910390a461146583600089858589612351565b61147483600089898989612359565b50505050505050565b81518351146114c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b8906138a1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611531576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611528906137c1565b60405180910390fd5b600061153b611296565b905061154b818787878787612349565b60005b8451811015611748576000858281518110611592577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151905060008583815181106115d7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611678576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166f90613841565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172d9190613a75565b925050819055505050508061174190613be4565b905061154e565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516117bf929190613649565b60405180910390a46117d5818787878787612351565b6117e3818787878787612540565b505050505050565b60007f8000000000000000000000000000000000000000000000000000000000000000808316149050919050565b600081836118279190613a75565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561189f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189690613821565b60405180910390fd5b80518251146118e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118da906138a1565b60405180910390fd5b60006118ed611296565b905061190d81856000868660405180602001604052806000815250612349565b60005b8351811015611aa6576000848281518110611954577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015190506000848381518110611999577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600080600084815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611a3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3190613741565b60405180910390fd5b81810360008085815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050508080611a9e90613be4565b915050611910565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611b1e929190613649565b60405180910390a4611b4481856000868660405180602001604052806000815250612351565b50505050565b82611b53611296565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611bbd57600080fd5b611bc6846117eb565b611c05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bfc90613781565b60405180910390fd5b81600660008581526020019081526020016000209080519060200190611c2c92919061274a565b5050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9990613861565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611d939190613680565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e07906137c1565b60405180910390fd5b6000611e1a611296565b90506000611e2785612283565b90506000611e3485612283565b9050611e44838989858589612349565b600080600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015611edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ed290613841565b60405180910390fd5b85810360008089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508560008089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f909190613a75565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a60405161200d9291906138fc565b60405180910390a4612023848a8a86868a612351565b612031848a8a8a8a8a612359565b505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156120ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a390613821565b60405180910390fd5b60006120b6611296565b905060006120c384612283565b905060006120d084612283565b90506120f083876000858560405180602001604052806000815250612349565b600080600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015612187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217e90613741565b60405180910390fd5b84810360008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516122549291906138fc565b60405180910390a461227a84886000868660405180602001604052806000815250612351565b50505050505050565b60606000600167ffffffffffffffff8111156122c8577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156122f65781602001602082028036833780820191505090505b5090508281600081518110612334577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080915050919050565b505050505050565b505050505050565b6123788473ffffffffffffffffffffffffffffffffffffffff16612727565b15612538578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b81526004016123be9594939291906135cd565b602060405180830381600087803b1580156123d857600080fd5b505af192505050801561240957506040513d601f19601f820116820180604052508101906124069190612f82565b60015b6124af57612415613cba565b806308c379a01415612472575061242a6141ea565b806124355750612474565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246991906136bf565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124a6906136e1565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161252d90613701565b60405180910390fd5b505b505050505050565b61255f8473ffffffffffffffffffffffffffffffffffffffff16612727565b1561271f578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016125a5959493929190613565565b602060405180830381600087803b1580156125bf57600080fd5b505af19250505080156125f057506040513d601f19601f820116820180604052508101906125ed9190612f82565b60015b612696576125fc613cba565b806308c379a0141561265957506126116141ea565b8061261c575061265b565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265091906136bf565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161268d906136e1565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461271d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161271490613701565b60405180910390fd5b505b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b82805461275690613b81565b90600052602060002090601f01602090048101928261277857600085556127bf565b82601f1061279157805160ff19168380011785556127bf565b828001600101855582156127bf579182015b828111156127be5782518255916020019190600101906127a3565b5b5090506127cc91906127d0565b5090565b5b808211156127e95760008160009055506001016127d1565b5090565b60006128006127fb8461394a565b613925565b9050808382526020820190508285602086028201111561281f57600080fd5b60005b8581101561284f57816128358882612941565b845260208401935060208301925050600181019050612822565b5050509392505050565b600061286c61286784613976565b613925565b9050808382526020820190508285602086028201111561288b57600080fd5b60005b858110156128bb57816128a18882612b1b565b84526020840193506020830192505060018101905061288e565b5050509392505050565b60006128d86128d3846139a2565b613925565b9050828152602081018484840111156128f057600080fd5b6128fb848285613b3f565b509392505050565b6000612916612911846139d3565b613925565b90508281526020810184848401111561292e57600080fd5b612939848285613b3f565b509392505050565b60008135905061295081614280565b92915050565b60008083601f84011261296857600080fd5b8235905067ffffffffffffffff81111561298157600080fd5b60208301915083602082028301111561299957600080fd5b9250929050565b600082601f8301126129b157600080fd5b81356129c18482602086016127ed565b91505092915050565b60008083601f8401126129dc57600080fd5b8235905067ffffffffffffffff8111156129f557600080fd5b602083019150836020820283011115612a0d57600080fd5b9250929050565b600082601f830112612a2557600080fd5b8135612a35848260208601612859565b91505092915050565b600081359050612a4d81614297565b92915050565b600081359050612a62816142ae565b92915050565b600081519050612a77816142ae565b92915050565b60008083601f840112612a8f57600080fd5b8235905067ffffffffffffffff811115612aa857600080fd5b602083019150836001820283011115612ac057600080fd5b9250929050565b600082601f830112612ad857600080fd5b8135612ae88482602086016128c5565b91505092915050565b600082601f830112612b0257600080fd5b8135612b12848260208601612903565b91505092915050565b600081359050612b2a816142c5565b92915050565b600060208284031215612b4257600080fd5b6000612b5084828501612941565b91505092915050565b60008060408385031215612b6c57600080fd5b6000612b7a85828601612941565b9250506020612b8b85828601612941565b9150509250929050565b600080600080600060a08688031215612bad57600080fd5b6000612bbb88828901612941565b9550506020612bcc88828901612941565b945050604086013567ffffffffffffffff811115612be957600080fd5b612bf588828901612a14565b935050606086013567ffffffffffffffff811115612c1257600080fd5b612c1e88828901612a14565b925050608086013567ffffffffffffffff811115612c3b57600080fd5b612c4788828901612ac7565b9150509295509295909350565b600080600080600060a08688031215612c6c57600080fd5b6000612c7a88828901612941565b9550506020612c8b88828901612941565b9450506040612c9c88828901612b1b565b9350506060612cad88828901612b1b565b925050608086013567ffffffffffffffff811115612cca57600080fd5b612cd688828901612ac7565b9150509295509295909350565b600080600060608486031215612cf857600080fd5b6000612d0686828701612941565b935050602084013567ffffffffffffffff811115612d2357600080fd5b612d2f86828701612a14565b925050604084013567ffffffffffffffff811115612d4c57600080fd5b612d5886828701612a14565b9150509250925092565b60008060408385031215612d7557600080fd5b6000612d8385828601612941565b9250506020612d9485828601612a3e565b9150509250929050565b60008060008060608587031215612db457600080fd5b6000612dc287828801612941565b9450506020612dd387828801612a3e565b935050604085013567ffffffffffffffff811115612df057600080fd5b612dfc87828801612a7d565b925092505092959194509250565b60008060408385031215612e1d57600080fd5b6000612e2b85828601612941565b9250506020612e3c85828601612b1b565b9150509250929050565b600080600060608486031215612e5b57600080fd5b6000612e6986828701612941565b9350506020612e7a86828701612b1b565b9250506040612e8b86828701612b1b565b9150509250925092565b60008060408385031215612ea857600080fd5b600083013567ffffffffffffffff811115612ec257600080fd5b612ece858286016129a0565b925050602083013567ffffffffffffffff811115612eeb57600080fd5b612ef785828601612a14565b9150509250929050565b600080600060408486031215612f1657600080fd5b6000612f2486828701612a3e565b935050602084013567ffffffffffffffff811115612f4157600080fd5b612f4d86828701612a7d565b92509250509250925092565b600060208284031215612f6b57600080fd5b6000612f7984828501612a53565b91505092915050565b600060208284031215612f9457600080fd5b6000612fa284828501612a68565b91505092915050565b600060208284031215612fbd57600080fd5b6000612fcb84828501612b1b565b91505092915050565b60008060008060008060006080888a031215612fef57600080fd5b6000612ffd8a828b01612b1b565b975050602088013567ffffffffffffffff81111561301a57600080fd5b6130268a828b01612956565b9650965050604088013567ffffffffffffffff81111561304557600080fd5b6130518a828b016129ca565b9450945050606088013567ffffffffffffffff81111561307057600080fd5b61307c8a828b01612a7d565b925092505092959891949750929550565b6000806000806000606086880312156130a557600080fd5b60006130b388828901612b1b565b955050602086013567ffffffffffffffff8111156130d057600080fd5b6130dc88828901612956565b9450945050604086013567ffffffffffffffff8111156130fb57600080fd5b61310788828901612a7d565b92509250509295509295909350565b6000806000806000806080878903121561312f57600080fd5b600061313d89828a01612b1b565b965050602087013567ffffffffffffffff81111561315a57600080fd5b61316689828a01612956565b9550955050604087013567ffffffffffffffff81111561318557600080fd5b61319189828a01612a7d565b9350935050606087013567ffffffffffffffff8111156131b057600080fd5b6131bc89828a01612af1565b9150509295509295509295565b60006131d5838361352c565b60208301905092915050565b6131ea81613acb565b82525050565b60006131fb82613a14565b6132058185613a42565b935061321083613a04565b8060005b8381101561324157815161322888826131c9565b975061323383613a35565b925050600181019050613214565b5085935050505092915050565b61325781613add565b82525050565b60006132698385613a53565b9350613276838584613b3f565b61327f83613cdc565b840190509392505050565b600061329582613a1f565b61329f8185613a53565b93506132af818560208601613b4e565b6132b881613cdc565b840191505092915050565b60006132ce82613a2a565b6132d88185613a64565b93506132e8818560208601613b4e565b6132f181613cdc565b840191505092915050565b6000613309603483613a64565b915061331482613cfa565b604082019050919050565b600061332c602883613a64565b915061333782613d49565b604082019050919050565b600061334f602b83613a64565b915061335a82613d98565b604082019050919050565b6000613372602483613a64565b915061337d82613de7565b604082019050919050565b6000613395602983613a64565b91506133a082613e36565b604082019050919050565b60006133b8603f83613a64565b91506133c382613e85565b604082019050919050565b60006133db603b83613a64565b91506133e682613ed4565b604082019050919050565b60006133fe602583613a64565b915061340982613f23565b604082019050919050565b6000613421603283613a64565b915061342c82613f72565b604082019050919050565b6000613444603483613a64565b915061344f82613fc1565b604082019050919050565b6000613467602383613a64565b915061347282614010565b604082019050919050565b600061348a602a83613a64565b91506134958261405f565b604082019050919050565b60006134ad602983613a64565b91506134b8826140ae565b604082019050919050565b60006134d0602983613a64565b91506134db826140fd565b604082019050919050565b60006134f3602883613a64565b91506134fe8261414c565b604082019050919050565b6000613516602183613a64565b91506135218261419b565b604082019050919050565b61353581613b35565b82525050565b61354481613b35565b82525050565b600060208201905061355f60008301846131e1565b92915050565b600060a08201905061357a60008301886131e1565b61358760208301876131e1565b818103604083015261359981866131f0565b905081810360608301526135ad81856131f0565b905081810360808301526135c1818461328a565b90509695505050505050565b600060a0820190506135e260008301886131e1565b6135ef60208301876131e1565b6135fc604083018661353b565b613609606083018561353b565b818103608083015261361b818461328a565b90509695505050505050565b6000602082019050818103600083015261364181846131f0565b905092915050565b6000604082019050818103600083015261366381856131f0565b9050818103602083015261367781846131f0565b90509392505050565b6000602082019050613695600083018461324e565b92915050565b600060208201905081810360008301526136b681848661325d565b90509392505050565b600060208201905081810360008301526136d981846132c3565b905092915050565b600060208201905081810360008301526136fa816132fc565b9050919050565b6000602082019050818103600083015261371a8161331f565b9050919050565b6000602082019050818103600083015261373a81613342565b9050919050565b6000602082019050818103600083015261375a81613365565b9050919050565b6000602082019050818103600083015261377a81613388565b9050919050565b6000602082019050818103600083015261379a816133ab565b9050919050565b600060208201905081810360008301526137ba816133ce565b9050919050565b600060208201905081810360008301526137da816133f1565b9050919050565b600060208201905081810360008301526137fa81613414565b9050919050565b6000602082019050818103600083015261381a81613437565b9050919050565b6000602082019050818103600083015261383a8161345a565b9050919050565b6000602082019050818103600083015261385a8161347d565b9050919050565b6000602082019050818103600083015261387a816134a0565b9050919050565b6000602082019050818103600083015261389a816134c3565b9050919050565b600060208201905081810360008301526138ba816134e6565b9050919050565b600060208201905081810360008301526138da81613509565b9050919050565b60006020820190506138f6600083018461353b565b92915050565b6000604082019050613911600083018561353b565b61391e602083018461353b565b9392505050565b600061392f613940565b905061393b8282613bb3565b919050565b6000604051905090565b600067ffffffffffffffff82111561396557613964613c8b565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561399157613990613c8b565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156139bd576139bc613c8b565b5b6139c682613cdc565b9050602081019050919050565b600067ffffffffffffffff8211156139ee576139ed613c8b565b5b6139f782613cdc565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000613a8082613b35565b9150613a8b83613b35565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613ac057613abf613c2d565b5b828201905092915050565b6000613ad682613b15565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015613b6c578082015181840152602081019050613b51565b83811115613b7b576000848401525b50505050565b60006002820490506001821680613b9957607f821691505b60208210811415613bad57613bac613c5c565b5b50919050565b613bbc82613cdc565b810181811067ffffffffffffffff82111715613bdb57613bda613c8b565b5b80604052505050565b6000613bef82613b35565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613c2257613c21613c2d565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115613cd95760046000803e613cd6600051613ced565b90505b90565b6000601f19601f8301169050919050565b60008160e01c9050919050565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e742061206e6f6e2d66756e6769626c65207479706500602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e7420612066756e6769626c6520747970650000000000602082015250565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20746f20616e6420616d6f60008201527f756e7473206c656e677468206d69736d61746368000000000000000000000000602082015250565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600060443d10156141fa5761427d565b614202613940565b60043d036004823e80513d602482011167ffffffffffffffff8211171561422a57505061427d565b808201805167ffffffffffffffff811115614248575050505061427d565b80602083010160043d03850181111561426557505050505061427d565b61427482602001850186613bb3565b82955050505050505b90565b61428981613acb565b811461429457600080fd5b50565b6142a081613add565b81146142ab57600080fd5b50565b6142b781613ae9565b81146142c257600080fd5b50565b6142ce81613b35565b81146142d957600080fd5b5056fea2646970667358221220294807453883ec73af4b9e8ca1836696c00f88042e85782bf38ba686bd810b9364736f6c63430008040033",
-  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061010a5760003560e01c806354dbdbf4116100a2578063a22cb46511610071578063a22cb465146102d7578063cd53d08e146102f3578063e985e9c514610323578063f242432a14610353578063f5298aca1461036f5761010a565b806354dbdbf4146102535780636b20c4541461026f57806371cc16561461028b5780637e53b65d146102bb5761010a565b8063183fb254116100de578063183fb254146101cf5780631cbf311d146101eb5780632eb2c2d6146102075780634e1273f4146102235761010a565b8062fdd58e1461010f57806301ffc9a71461013f57806308d7d4691461016f5780630e89341c1461019f575b600080fd5b61012960048036038101906101249190612e0a565b61038b565b60405161013691906138e1565b60405180910390f35b61015960048036038101906101549190612f59565b610454565b6040516101669190613680565b60405180910390f35b61018960048036038101906101849190612fab565b610536565b60405161019691906138e1565b60405180910390f35b6101b960048036038101906101b49190612fab565b61054e565b6040516101c691906136bf565b60405180910390f35b6101e960048036038101906101e49190612fd4565b610623565b005b61020560048036038101906102009190612d9e565b61082c565b005b610221600480360381019061021c9190612b95565b61083c565b005b61023d60048036038101906102389190612e95565b6108dd565b60405161024a9190613627565b60405180910390f35b61026d6004803603810190610268919061308d565b610a8e565b005b61028960048036038101906102849190612ce3565b610c78565b005b6102a560048036038101906102a09190612f01565b610d15565b6040516102b291906138e1565b60405180910390f35b6102d560048036038101906102d09190613116565b610e15565b005b6102f160048036038101906102ec9190612d62565b611011565b005b61030d60048036038101906103089190612fab565b611027565b60405161031a919061354a565b60405180910390f35b61033d60048036038101906103389190612b59565b61105a565b60405161034a9190613680565b60405180910390f35b61036d60048036038101906103689190612c54565b6110ee565b005b61038960048036038101906103849190612e46565b61118f565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156103fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f390613721565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061051f57507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061052f575061052e8261122c565b5b9050919050565b60056020528060005260406000206000915090505481565b6060600060066000848152602001908152602001600020805461057090613b81565b80601f016020809104026020016040519081016040528092919081815260200182805461059c90613b81565b80156105e95780601f106105be576101008083540402835291602001916105e9565b820191906000526020600020905b8154815290600101906020018083116105cc57829003601f168201915b50505050509050600081905060008151141561061857604051806020016040528060008152509250505061061e565b81925050505b919050565b8661062c611296565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461069657600080fd5b61069f8861129e565b6106de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106d5906137a1565b60405180910390fd5b848490508787905014610726576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161071d90613801565b60405180910390fd5b60005b8787905081101561082157610810888883818110610770577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906107859190612b30565b8a8888858181106107bf577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013587878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506112cc565b8061081a90613be4565b9050610729565b505050505050505050565b6108368484611011565b50505050565b610844611296565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061088a575061088985610884611296565b61105a565b5b6108c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c0906137e1565b60405180910390fd5b6108d6858585858561147d565b5050505050565b60608151835114610923576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091a90613881565b60405180910390fd5b6000835167ffffffffffffffff811115610966577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156109945781602001602082028036833780820191505090505b50905060005b8451811015610a8357610a2d8582815181106109df577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151858381518110610a20577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015161038b565b828281518110610a66577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080610a7c90613be4565b905061099a565b508091505092915050565b84610a97611296565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b0157600080fd5b610b0a866117eb565b610b49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4090613781565b60405180910390fd5b600060016005600089815260200190815260200160002054610b6b9190613a75565b9050610b8d86869050600560008a815260200190815260200160002054611819565b600560008981526020019081526020016000208190555060005b86869050811015610c6e57610c5d878783818110610bee577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610c039190612b30565b8284610c0f9190613a75565b8a17600188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506112cc565b80610c6790613be4565b9050610ba7565b5050505050505050565b610c80611296565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161480610cc65750610cc583610cc0611296565b61105a565b5b610d05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cfc90613761565b60405180910390fd5b610d1083838361182f565b505050565b60006080600360008154610d2890613be4565b919050819055901b905083610d5d577f8000000000000000000000000000000000000000000000000000000000000000811790505b610d65611296565b6004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080610dbf611296565b73ffffffffffffffffffffffffffffffffffffffff167f0d2ce24070e07853454690ae0a0416ddd4845188f8dbfe0ef3a761acb3d2e34e8585604051610e0692919061369b565b60405180910390a39392505050565b85610e1e611296565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e8857600080fd5b610e91876117eb565b610ed0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ec790613781565b60405180910390fd5b60006001600560008a815260200190815260200160002054610ef29190613a75565b9050610f1487879050600560008b815260200190815260200160002054611819565b600560008a81526020019081526020016000208190555060005b878790508110156110065760008183610f479190613a75565b8a179050610fe9898984818110610f87577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610f9c9190612b30565b8260018a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506112cc565b610ff48a8287611b4a565b5080610fff90613be4565b9050610f2e565b505050505050505050565b61102361101c611296565b8383611c33565b5050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6110f6611296565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061113c575061113b85611136611296565b61105a565b5b61117b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117290613761565b60405180910390fd5b6111888585858585611da0565b5050505050565b611197611296565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806111dd57506111dc836111d7611296565b61105a565b5b61121c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121390613761565b60405180910390fd5b61122783838361203c565b505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b6000807f80000000000000000000000000000000000000000000000000000000000000008316149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561133c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611333906138c1565b60405180910390fd5b6000611346611296565b9050600061135385612283565b9050600061136085612283565b905061137183600089858589612349565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113d09190613a75565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62898960405161144e9291906138fc565b60405180910390a461146583600089858589612351565b61147483600089898989612359565b50505050505050565b81518351146114c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b8906138a1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611531576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611528906137c1565b60405180910390fd5b600061153b611296565b905061154b818787878787612349565b60005b8451811015611748576000858281518110611592577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151905060008583815181106115d7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611678576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166f90613841565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172d9190613a75565b925050819055505050508061174190613be4565b905061154e565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516117bf929190613649565b60405180910390a46117d5818787878787612351565b6117e3818787878787612540565b505050505050565b60007f8000000000000000000000000000000000000000000000000000000000000000808316149050919050565b600081836118279190613a75565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561189f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189690613821565b60405180910390fd5b80518251146118e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118da906138a1565b60405180910390fd5b60006118ed611296565b905061190d81856000868660405180602001604052806000815250612349565b60005b8351811015611aa6576000848281518110611954577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015190506000848381518110611999577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050600080600084815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611a3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3190613741565b60405180910390fd5b81810360008085815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050508080611a9e90613be4565b915050611910565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611b1e929190613649565b60405180910390a4611b4481856000868660405180602001604052806000815250612351565b50505050565b82611b53611296565b73ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611bbd57600080fd5b611bc6846117eb565b611c05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bfc90613781565b60405180910390fd5b81600660008581526020019081526020016000209080519060200190611c2c92919061274a565b5050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9990613861565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611d939190613680565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e07906137c1565b60405180910390fd5b6000611e1a611296565b90506000611e2785612283565b90506000611e3485612283565b9050611e44838989858589612349565b600080600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015611edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ed290613841565b60405180910390fd5b85810360008089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508560008089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f909190613a75565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a60405161200d9291906138fc565b60405180910390a4612023848a8a86868a612351565b612031848a8a8a8a8a612359565b505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156120ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a390613821565b60405180910390fd5b60006120b6611296565b905060006120c384612283565b905060006120d084612283565b90506120f083876000858560405180602001604052806000815250612349565b600080600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015612187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217e90613741565b60405180910390fd5b84810360008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516122549291906138fc565b60405180910390a461227a84886000868660405180602001604052806000815250612351565b50505050505050565b60606000600167ffffffffffffffff8111156122c8577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156122f65781602001602082028036833780820191505090505b5090508281600081518110612334577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080915050919050565b505050505050565b505050505050565b6123788473ffffffffffffffffffffffffffffffffffffffff16612727565b15612538578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b81526004016123be9594939291906135cd565b602060405180830381600087803b1580156123d857600080fd5b505af192505050801561240957506040513d601f19601f820116820180604052508101906124069190612f82565b60015b6124af57612415613cba565b806308c379a01415612472575061242a6141ea565b806124355750612474565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246991906136bf565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124a6906136e1565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161252d90613701565b60405180910390fd5b505b505050505050565b61255f8473ffffffffffffffffffffffffffffffffffffffff16612727565b1561271f578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016125a5959493929190613565565b602060405180830381600087803b1580156125bf57600080fd5b505af19250505080156125f057506040513d601f19601f820116820180604052508101906125ed9190612f82565b60015b612696576125fc613cba565b806308c379a0141561265957506126116141ea565b8061261c575061265b565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265091906136bf565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161268d906136e1565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461271d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161271490613701565b60405180910390fd5b505b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b82805461275690613b81565b90600052602060002090601f01602090048101928261277857600085556127bf565b82601f1061279157805160ff19168380011785556127bf565b828001600101855582156127bf579182015b828111156127be5782518255916020019190600101906127a3565b5b5090506127cc91906127d0565b5090565b5b808211156127e95760008160009055506001016127d1565b5090565b60006128006127fb8461394a565b613925565b9050808382526020820190508285602086028201111561281f57600080fd5b60005b8581101561284f57816128358882612941565b845260208401935060208301925050600181019050612822565b5050509392505050565b600061286c61286784613976565b613925565b9050808382526020820190508285602086028201111561288b57600080fd5b60005b858110156128bb57816128a18882612b1b565b84526020840193506020830192505060018101905061288e565b5050509392505050565b60006128d86128d3846139a2565b613925565b9050828152602081018484840111156128f057600080fd5b6128fb848285613b3f565b509392505050565b6000612916612911846139d3565b613925565b90508281526020810184848401111561292e57600080fd5b612939848285613b3f565b509392505050565b60008135905061295081614280565b92915050565b60008083601f84011261296857600080fd5b8235905067ffffffffffffffff81111561298157600080fd5b60208301915083602082028301111561299957600080fd5b9250929050565b600082601f8301126129b157600080fd5b81356129c18482602086016127ed565b91505092915050565b60008083601f8401126129dc57600080fd5b8235905067ffffffffffffffff8111156129f557600080fd5b602083019150836020820283011115612a0d57600080fd5b9250929050565b600082601f830112612a2557600080fd5b8135612a35848260208601612859565b91505092915050565b600081359050612a4d81614297565b92915050565b600081359050612a62816142ae565b92915050565b600081519050612a77816142ae565b92915050565b60008083601f840112612a8f57600080fd5b8235905067ffffffffffffffff811115612aa857600080fd5b602083019150836001820283011115612ac057600080fd5b9250929050565b600082601f830112612ad857600080fd5b8135612ae88482602086016128c5565b91505092915050565b600082601f830112612b0257600080fd5b8135612b12848260208601612903565b91505092915050565b600081359050612b2a816142c5565b92915050565b600060208284031215612b4257600080fd5b6000612b5084828501612941565b91505092915050565b60008060408385031215612b6c57600080fd5b6000612b7a85828601612941565b9250506020612b8b85828601612941565b9150509250929050565b600080600080600060a08688031215612bad57600080fd5b6000612bbb88828901612941565b9550506020612bcc88828901612941565b945050604086013567ffffffffffffffff811115612be957600080fd5b612bf588828901612a14565b935050606086013567ffffffffffffffff811115612c1257600080fd5b612c1e88828901612a14565b925050608086013567ffffffffffffffff811115612c3b57600080fd5b612c4788828901612ac7565b9150509295509295909350565b600080600080600060a08688031215612c6c57600080fd5b6000612c7a88828901612941565b9550506020612c8b88828901612941565b9450506040612c9c88828901612b1b565b9350506060612cad88828901612b1b565b925050608086013567ffffffffffffffff811115612cca57600080fd5b612cd688828901612ac7565b9150509295509295909350565b600080600060608486031215612cf857600080fd5b6000612d0686828701612941565b935050602084013567ffffffffffffffff811115612d2357600080fd5b612d2f86828701612a14565b925050604084013567ffffffffffffffff811115612d4c57600080fd5b612d5886828701612a14565b9150509250925092565b60008060408385031215612d7557600080fd5b6000612d8385828601612941565b9250506020612d9485828601612a3e565b9150509250929050565b60008060008060608587031215612db457600080fd5b6000612dc287828801612941565b9450506020612dd387828801612a3e565b935050604085013567ffffffffffffffff811115612df057600080fd5b612dfc87828801612a7d565b925092505092959194509250565b60008060408385031215612e1d57600080fd5b6000612e2b85828601612941565b9250506020612e3c85828601612b1b565b9150509250929050565b600080600060608486031215612e5b57600080fd5b6000612e6986828701612941565b9350506020612e7a86828701612b1b565b9250506040612e8b86828701612b1b565b9150509250925092565b60008060408385031215612ea857600080fd5b600083013567ffffffffffffffff811115612ec257600080fd5b612ece858286016129a0565b925050602083013567ffffffffffffffff811115612eeb57600080fd5b612ef785828601612a14565b9150509250929050565b600080600060408486031215612f1657600080fd5b6000612f2486828701612a3e565b935050602084013567ffffffffffffffff811115612f4157600080fd5b612f4d86828701612a7d565b92509250509250925092565b600060208284031215612f6b57600080fd5b6000612f7984828501612a53565b91505092915050565b600060208284031215612f9457600080fd5b6000612fa284828501612a68565b91505092915050565b600060208284031215612fbd57600080fd5b6000612fcb84828501612b1b565b91505092915050565b60008060008060008060006080888a031215612fef57600080fd5b6000612ffd8a828b01612b1b565b975050602088013567ffffffffffffffff81111561301a57600080fd5b6130268a828b01612956565b9650965050604088013567ffffffffffffffff81111561304557600080fd5b6130518a828b016129ca565b9450945050606088013567ffffffffffffffff81111561307057600080fd5b61307c8a828b01612a7d565b925092505092959891949750929550565b6000806000806000606086880312156130a557600080fd5b60006130b388828901612b1b565b955050602086013567ffffffffffffffff8111156130d057600080fd5b6130dc88828901612956565b9450945050604086013567ffffffffffffffff8111156130fb57600080fd5b61310788828901612a7d565b92509250509295509295909350565b6000806000806000806080878903121561312f57600080fd5b600061313d89828a01612b1b565b965050602087013567ffffffffffffffff81111561315a57600080fd5b61316689828a01612956565b9550955050604087013567ffffffffffffffff81111561318557600080fd5b61319189828a01612a7d565b9350935050606087013567ffffffffffffffff8111156131b057600080fd5b6131bc89828a01612af1565b9150509295509295509295565b60006131d5838361352c565b60208301905092915050565b6131ea81613acb565b82525050565b60006131fb82613a14565b6132058185613a42565b935061321083613a04565b8060005b8381101561324157815161322888826131c9565b975061323383613a35565b925050600181019050613214565b5085935050505092915050565b61325781613add565b82525050565b60006132698385613a53565b9350613276838584613b3f565b61327f83613cdc565b840190509392505050565b600061329582613a1f565b61329f8185613a53565b93506132af818560208601613b4e565b6132b881613cdc565b840191505092915050565b60006132ce82613a2a565b6132d88185613a64565b93506132e8818560208601613b4e565b6132f181613cdc565b840191505092915050565b6000613309603483613a64565b915061331482613cfa565b604082019050919050565b600061332c602883613a64565b915061333782613d49565b604082019050919050565b600061334f602b83613a64565b915061335a82613d98565b604082019050919050565b6000613372602483613a64565b915061337d82613de7565b604082019050919050565b6000613395602983613a64565b91506133a082613e36565b604082019050919050565b60006133b8603f83613a64565b91506133c382613e85565b604082019050919050565b60006133db603b83613a64565b91506133e682613ed4565b604082019050919050565b60006133fe602583613a64565b915061340982613f23565b604082019050919050565b6000613421603283613a64565b915061342c82613f72565b604082019050919050565b6000613444603483613a64565b915061344f82613fc1565b604082019050919050565b6000613467602383613a64565b915061347282614010565b604082019050919050565b600061348a602a83613a64565b91506134958261405f565b604082019050919050565b60006134ad602983613a64565b91506134b8826140ae565b604082019050919050565b60006134d0602983613a64565b91506134db826140fd565b604082019050919050565b60006134f3602883613a64565b91506134fe8261414c565b604082019050919050565b6000613516602183613a64565b91506135218261419b565b604082019050919050565b61353581613b35565b82525050565b61354481613b35565b82525050565b600060208201905061355f60008301846131e1565b92915050565b600060a08201905061357a60008301886131e1565b61358760208301876131e1565b818103604083015261359981866131f0565b905081810360608301526135ad81856131f0565b905081810360808301526135c1818461328a565b90509695505050505050565b600060a0820190506135e260008301886131e1565b6135ef60208301876131e1565b6135fc604083018661353b565b613609606083018561353b565b818103608083015261361b818461328a565b90509695505050505050565b6000602082019050818103600083015261364181846131f0565b905092915050565b6000604082019050818103600083015261366381856131f0565b9050818103602083015261367781846131f0565b90509392505050565b6000602082019050613695600083018461324e565b92915050565b600060208201905081810360008301526136b681848661325d565b90509392505050565b600060208201905081810360008301526136d981846132c3565b905092915050565b600060208201905081810360008301526136fa816132fc565b9050919050565b6000602082019050818103600083015261371a8161331f565b9050919050565b6000602082019050818103600083015261373a81613342565b9050919050565b6000602082019050818103600083015261375a81613365565b9050919050565b6000602082019050818103600083015261377a81613388565b9050919050565b6000602082019050818103600083015261379a816133ab565b9050919050565b600060208201905081810360008301526137ba816133ce565b9050919050565b600060208201905081810360008301526137da816133f1565b9050919050565b600060208201905081810360008301526137fa81613414565b9050919050565b6000602082019050818103600083015261381a81613437565b9050919050565b6000602082019050818103600083015261383a8161345a565b9050919050565b6000602082019050818103600083015261385a8161347d565b9050919050565b6000602082019050818103600083015261387a816134a0565b9050919050565b6000602082019050818103600083015261389a816134c3565b9050919050565b600060208201905081810360008301526138ba816134e6565b9050919050565b600060208201905081810360008301526138da81613509565b9050919050565b60006020820190506138f6600083018461353b565b92915050565b6000604082019050613911600083018561353b565b61391e602083018461353b565b9392505050565b600061392f613940565b905061393b8282613bb3565b919050565b6000604051905090565b600067ffffffffffffffff82111561396557613964613c8b565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561399157613990613c8b565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156139bd576139bc613c8b565b5b6139c682613cdc565b9050602081019050919050565b600067ffffffffffffffff8211156139ee576139ed613c8b565b5b6139f782613cdc565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000613a8082613b35565b9150613a8b83613b35565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613ac057613abf613c2d565b5b828201905092915050565b6000613ad682613b15565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015613b6c578082015181840152602081019050613b51565b83811115613b7b576000848401525b50505050565b60006002820490506001821680613b9957607f821691505b60208210811415613bad57613bac613c5c565b5b50919050565b613bbc82613cdc565b810181811067ffffffffffffffff82111715613bdb57613bda613c8b565b5b80604052505050565b6000613bef82613b35565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613c2257613c21613c2d565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115613cd95760046000803e613cd6600051613ced565b90505b90565b6000601f19601f8301169050919050565b60008160e01c9050919050565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e742061206e6f6e2d66756e6769626c65207479706500602082015250565b7f455243313135354d6978656446756e6769626c653a20696420646f6573206e6f60008201527f7420726570726573656e7420612066756e6769626c6520747970650000000000602082015250565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b7f455243313135354d6978656446756e6769626c653a20746f20616e6420616d6f60008201527f756e7473206c656e677468206d69736d61746368000000000000000000000000602082015250565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600060443d10156141fa5761427d565b614202613940565b60043d036004823e80513d602482011167ffffffffffffffff8211171561422a57505061427d565b808201805167ffffffffffffffff811115614248575050505061427d565b80602083010160043d03850181111561426557505050505061427d565b61427482602001850186613bb3565b82955050505050505b90565b61428981613acb565b811461429457600080fd5b50565b6142a081613add565b81146142ab57600080fd5b50565b6142b781613ae9565b81146142c257600080fd5b50565b6142ce81613b35565b81146142d957600080fd5b5056fea2646970667358221220294807453883ec73af4b9e8ca1836696c00f88042e85782bf38ba686bd810b9364736f6c63430008040033",
-  "linkReferences": {},
-  "deployedLinkReferences": {}
-}
diff --git a/test/data/contracts/erc20/ERC20OpenZeppelin.json b/test/data/contracts/erc20/ERC20OpenZeppelin.json
deleted file mode 100644
index 7e3cef66c..000000000
--- a/test/data/contracts/erc20/ERC20OpenZeppelin.json
+++ /dev/null
@@ -1,387 +0,0 @@
-{
-  "_format": "hh-sol-artifact-1",
-  "contractName": "MyToken",
-  "sourceName": "contracts/MyToken.sol",
-  "abi": [
-    {
-      "inputs": [],
-      "stateMutability": "nonpayable",
-      "type": "constructor"
-    },
-    {
-      "anonymous": false,
-      "inputs": [
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "owner",
-          "type": "address"
-        },
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "spender",
-          "type": "address"
-        },
-        {
-          "indexed": false,
-          "internalType": "uint256",
-          "name": "value",
-          "type": "uint256"
-        }
-      ],
-      "name": "Approval",
-      "type": "event"
-    },
-    {
-      "anonymous": false,
-      "inputs": [
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "previousOwner",
-          "type": "address"
-        },
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "newOwner",
-          "type": "address"
-        }
-      ],
-      "name": "OwnershipTransferred",
-      "type": "event"
-    },
-    {
-      "anonymous": false,
-      "inputs": [
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "from",
-          "type": "address"
-        },
-        {
-          "indexed": true,
-          "internalType": "address",
-          "name": "to",
-          "type": "address"
-        },
-        {
-          "indexed": false,
-          "internalType": "uint256",
-          "name": "value",
-          "type": "uint256"
-        }
-      ],
-      "name": "Transfer",
-      "type": "event"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "owner",
-          "type": "address"
-        },
-        {
-          "internalType": "address",
-          "name": "spender",
-          "type": "address"
-        }
-      ],
-      "name": "allowance",
-      "outputs": [
-        {
-          "internalType": "uint256",
-          "name": "",
-          "type": "uint256"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "spender",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256",
-          "name": "amount",
-          "type": "uint256"
-        }
-      ],
-      "name": "approve",
-      "outputs": [
-        {
-          "internalType": "bool",
-          "name": "",
-          "type": "bool"
-        }
-      ],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "account",
-          "type": "address"
-        }
-      ],
-      "name": "balanceOf",
-      "outputs": [
-        {
-          "internalType": "uint256",
-          "name": "",
-          "type": "uint256"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "uint256",
-          "name": "amount",
-          "type": "uint256"
-        }
-      ],
-      "name": "burn",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "account",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256",
-          "name": "amount",
-          "type": "uint256"
-        }
-      ],
-      "name": "burnFrom",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [],
-      "name": "decimals",
-      "outputs": [
-        {
-          "internalType": "uint8",
-          "name": "",
-          "type": "uint8"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "spender",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256",
-          "name": "subtractedValue",
-          "type": "uint256"
-        }
-      ],
-      "name": "decreaseAllowance",
-      "outputs": [
-        {
-          "internalType": "bool",
-          "name": "",
-          "type": "bool"
-        }
-      ],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "spender",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256",
-          "name": "addedValue",
-          "type": "uint256"
-        }
-      ],
-      "name": "increaseAllowance",
-      "outputs": [
-        {
-          "internalType": "bool",
-          "name": "",
-          "type": "bool"
-        }
-      ],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "to",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256",
-          "name": "amount",
-          "type": "uint256"
-        }
-      ],
-      "name": "mint",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [],
-      "name": "name",
-      "outputs": [
-        {
-          "internalType": "string",
-          "name": "",
-          "type": "string"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [],
-      "name": "owner",
-      "outputs": [
-        {
-          "internalType": "address",
-          "name": "",
-          "type": "address"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [],
-      "name": "renounceOwnership",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [],
-      "name": "symbol",
-      "outputs": [
-        {
-          "internalType": "string",
-          "name": "",
-          "type": "string"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [],
-      "name": "totalSupply",
-      "outputs": [
-        {
-          "internalType": "uint256",
-          "name": "",
-          "type": "uint256"
-        }
-      ],
-      "stateMutability": "view",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "to",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256",
-          "name": "amount",
-          "type": "uint256"
-        }
-      ],
-      "name": "transfer",
-      "outputs": [
-        {
-          "internalType": "bool",
-          "name": "",
-          "type": "bool"
-        }
-      ],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "from",
-          "type": "address"
-        },
-        {
-          "internalType": "address",
-          "name": "to",
-          "type": "address"
-        },
-        {
-          "internalType": "uint256",
-          "name": "amount",
-          "type": "uint256"
-        }
-      ],
-      "name": "transferFrom",
-      "outputs": [
-        {
-          "internalType": "bool",
-          "name": "",
-          "type": "bool"
-        }
-      ],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    },
-    {
-      "inputs": [
-        {
-          "internalType": "address",
-          "name": "newOwner",
-          "type": "address"
-        }
-      ],
-      "name": "transferOwnership",
-      "outputs": [],
-      "stateMutability": "nonpayable",
-      "type": "function"
-    }
-  ],
-  "bytecode": "0x60806040523480156200001157600080fd5b506040518060400160405280600781526020016626bcaa37b5b2b760c91b815250604051806040016040528060038152602001624d544b60e81b815250816003908051906020019062000066929190620000f5565b5080516200007c906004906020840190620000f5565b50505062000099620000936200009f60201b60201c565b620000a3565b620001d8565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805462000103906200019b565b90600052602060002090601f01602090048101928262000127576000855562000172565b82601f106200014257805160ff191683800117855562000172565b8280016001018555821562000172579182015b828111156200017257825182559160200191906001019062000155565b506200018092915062000184565b5090565b5b8082111562000180576000815560010162000185565b600181811c90821680620001b057607f821691505b60208210811415620001d257634e487b7160e01b600052602260045260246000fd5b50919050565b610ca180620001e86000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a257806395d89b411161007157806395d89b411461021f578063a457c2d714610227578063a9059cbb1461023a578063dd62ed3e1461024d578063f2fde38b1461026057600080fd5b806370a08231146101c0578063715018a6146101e957806379cc6790146101f15780638da5cb5b1461020457600080fd5b8063313ce567116100de578063313ce56714610176578063395093511461018557806340c10f191461019857806342966c68146101ad57600080fd5b806306fdde0314610110578063095ea7b31461012e57806318160ddd1461015157806323b872dd14610163575b600080fd5b610118610273565b6040516101259190610ac5565b60405180910390f35b61014161013c366004610b36565b610305565b6040519015158152602001610125565b6002545b604051908152602001610125565b610141610171366004610b60565b61031d565b60405160128152602001610125565b610141610193366004610b36565b610341565b6101ab6101a6366004610b36565b610363565b005b6101ab6101bb366004610b9c565b610379565b6101556101ce366004610bb5565b6001600160a01b031660009081526020819052604090205490565b6101ab610386565b6101ab6101ff366004610b36565b61039a565b6005546040516001600160a01b039091168152602001610125565b6101186103af565b610141610235366004610b36565b6103be565b610141610248366004610b36565b61043e565b61015561025b366004610bd7565b61044c565b6101ab61026e366004610bb5565b610477565b60606003805461028290610c0a565b80601f01602080910402602001604051908101604052809291908181526020018280546102ae90610c0a565b80156102fb5780601f106102d0576101008083540402835291602001916102fb565b820191906000526020600020905b8154815290600101906020018083116102de57829003601f168201915b5050505050905090565b6000336103138185856104ed565b5060019392505050565b60003361032b858285610612565b61033685858561068c565b506001949350505050565b600033610313818585610354838361044c565b61035e9190610c45565b6104ed565b61036b610830565b610375828261088a565b5050565b6103833382610949565b50565b61038e610830565b6103986000610a73565b565b6103a5823383610612565b6103758282610949565b60606004805461028290610c0a565b600033816103cc828661044c565b9050838110156104315760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b61033682868684036104ed565b60003361031381858561068c565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61047f610830565b6001600160a01b0381166104e45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610428565b61038381610a73565b6001600160a01b03831661054f5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610428565b6001600160a01b0382166105b05760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610428565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b600061061e848461044c565b9050600019811461068657818110156106795760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610428565b61068684848484036104ed565b50505050565b6001600160a01b0383166106f05760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610428565b6001600160a01b0382166107525760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610428565b6001600160a01b038316600090815260208190526040902054818110156107ca5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610428565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610686565b6005546001600160a01b031633146103985760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610428565b6001600160a01b0382166108e05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610428565b80600260008282546108f29190610c45565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0382166109a95760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610428565b6001600160a01b03821660009081526020819052604090205481811015610a1d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610428565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610605565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208083528351808285015260005b81811015610af257858101830151858201604001528201610ad6565b81811115610b04576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114610b3157600080fd5b919050565b60008060408385031215610b4957600080fd5b610b5283610b1a565b946020939093013593505050565b600080600060608486031215610b7557600080fd5b610b7e84610b1a565b9250610b8c60208501610b1a565b9150604084013590509250925092565b600060208284031215610bae57600080fd5b5035919050565b600060208284031215610bc757600080fd5b610bd082610b1a565b9392505050565b60008060408385031215610bea57600080fd5b610bf383610b1a565b9150610c0160208401610b1a565b90509250929050565b600181811c90821680610c1e57607f821691505b60208210811415610c3f57634e487b7160e01b600052602260045260246000fd5b50919050565b60008219821115610c6657634e487b7160e01b600052601160045260246000fd5b50019056fea2646970667358221220e098e84337ed515fa28fa493e8123cac9696f689e1707acbf904514a57749b2f64736f6c63430008090033",
-  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a257806395d89b411161007157806395d89b411461021f578063a457c2d714610227578063a9059cbb1461023a578063dd62ed3e1461024d578063f2fde38b1461026057600080fd5b806370a08231146101c0578063715018a6146101e957806379cc6790146101f15780638da5cb5b1461020457600080fd5b8063313ce567116100de578063313ce56714610176578063395093511461018557806340c10f191461019857806342966c68146101ad57600080fd5b806306fdde0314610110578063095ea7b31461012e57806318160ddd1461015157806323b872dd14610163575b600080fd5b610118610273565b6040516101259190610ac5565b60405180910390f35b61014161013c366004610b36565b610305565b6040519015158152602001610125565b6002545b604051908152602001610125565b610141610171366004610b60565b61031d565b60405160128152602001610125565b610141610193366004610b36565b610341565b6101ab6101a6366004610b36565b610363565b005b6101ab6101bb366004610b9c565b610379565b6101556101ce366004610bb5565b6001600160a01b031660009081526020819052604090205490565b6101ab610386565b6101ab6101ff366004610b36565b61039a565b6005546040516001600160a01b039091168152602001610125565b6101186103af565b610141610235366004610b36565b6103be565b610141610248366004610b36565b61043e565b61015561025b366004610bd7565b61044c565b6101ab61026e366004610bb5565b610477565b60606003805461028290610c0a565b80601f01602080910402602001604051908101604052809291908181526020018280546102ae90610c0a565b80156102fb5780601f106102d0576101008083540402835291602001916102fb565b820191906000526020600020905b8154815290600101906020018083116102de57829003601f168201915b5050505050905090565b6000336103138185856104ed565b5060019392505050565b60003361032b858285610612565b61033685858561068c565b506001949350505050565b600033610313818585610354838361044c565b61035e9190610c45565b6104ed565b61036b610830565b610375828261088a565b5050565b6103833382610949565b50565b61038e610830565b6103986000610a73565b565b6103a5823383610612565b6103758282610949565b60606004805461028290610c0a565b600033816103cc828661044c565b9050838110156104315760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b61033682868684036104ed565b60003361031381858561068c565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61047f610830565b6001600160a01b0381166104e45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610428565b61038381610a73565b6001600160a01b03831661054f5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610428565b6001600160a01b0382166105b05760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610428565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b600061061e848461044c565b9050600019811461068657818110156106795760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610428565b61068684848484036104ed565b50505050565b6001600160a01b0383166106f05760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610428565b6001600160a01b0382166107525760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610428565b6001600160a01b038316600090815260208190526040902054818110156107ca5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610428565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610686565b6005546001600160a01b031633146103985760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610428565b6001600160a01b0382166108e05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610428565b80600260008282546108f29190610c45565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0382166109a95760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610428565b6001600160a01b03821660009081526020819052604090205481811015610a1d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610428565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610605565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208083528351808285015260005b81811015610af257858101830151858201604001528201610ad6565b81811115610b04576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114610b3157600080fd5b919050565b60008060408385031215610b4957600080fd5b610b5283610b1a565b946020939093013593505050565b600080600060608486031215610b7557600080fd5b610b7e84610b1a565b9250610b8c60208501610b1a565b9150604084013590509250925092565b600060208284031215610bae57600080fd5b5035919050565b600060208284031215610bc757600080fd5b610bd082610b1a565b9392505050565b60008060408385031215610bea57600080fd5b610bf383610b1a565b9150610c0160208401610b1a565b90509250929050565b600181811c90821680610c1e57607f821691505b60208210811415610c3f57634e487b7160e01b600052602260045260246000fd5b50919050565b60008219821115610c6657634e487b7160e01b600052601160045260246000fd5b50019056fea2646970667358221220e098e84337ed515fa28fa493e8123cac9696f689e1707acbf904514a57749b2f64736f6c63430008090033",
-  "linkReferences": {},
-  "deployedLinkReferences": {}
-}
diff --git a/test/e2e/client/restclient.go b/test/e2e/client/restclient.go
index fc9eed507..35231b573 100644
--- a/test/e2e/client/restclient.go
+++ b/test/e2e/client/restclient.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -64,7 +64,6 @@ var (
 	urlContractInvoke    = "/contracts/invoke"
 	urlContractQuery     = "/contracts/query"
 	urlContractInterface = "/contracts/interfaces"
-	urlContractGenerate  = "/contracts/interfaces/generate"
 	urlContractListeners = "/contracts/listeners"
 	urlContractAPI       = "/apis"
 	urlBlockchainEvents  = "/blockchainevents"
@@ -577,16 +576,6 @@ func (client *FireFlyClient) GetTokenPools(t *testing.T, startTime time.Time) (p
 	return pools
 }
 
-func (client *FireFlyClient) GetTokenPool(t *testing.T, poolID *fftypes.UUID) (pool *core.TokenPool) {
-	path := client.namespaced(urlTokenPools + "/" + poolID.String())
-	resp, err := client.Client.R().
-		SetResult(&pool).
-		Get(path)
-	require.NoError(t, err)
-	require.Equal(t, 200, resp.StatusCode(), "GET %s [%d]: %s", path, resp.StatusCode(), resp.String())
-	return pool
-}
-
 func (client *FireFlyClient) MintTokens(t *testing.T, mint *core.TokenTransferInput, confirm bool, expectedStatus ...int) *core.TokenTransfer {
 	var transferOut core.TokenTransfer
 	path := client.namespaced(urlTokenMint)
@@ -722,7 +711,7 @@ func (client *FireFlyClient) GetTokenBalance(t *testing.T, poolID *fftypes.UUID,
 		Get(path)
 	require.NoError(t, err)
 	require.Equal(t, 200, resp.StatusCode(), "GET %s [%d]: %s", path, resp.StatusCode(), resp.String())
-	require.Equal(t, 1, len(accounts))
+	require.Equal(t, len(accounts), 1)
 	return accounts[0]
 }
 
@@ -824,18 +813,6 @@ func (client *FireFlyClient) QueryContractMethod(t *testing.T, req *core.Contrac
 	return res, err
 }
 
-func (client *FireFlyClient) GenerateFFIFromABI(t *testing.T, req *fftypes.FFIGenerationRequest) *fftypes.FFI {
-	var res fftypes.FFI
-	path := client.namespaced(urlContractGenerate)
-	resp, err := client.Client.R().
-		SetBody(req).
-		SetResult(&res).
-		Post(path)
-	require.NoError(t, err)
-	require.Equal(t, 200, resp.StatusCode(), "POST %s [%d]: %s", path, resp.StatusCode(), resp.String())
-	return &res
-}
-
 func (client *FireFlyClient) CreateFFI(t *testing.T, ffi *fftypes.FFI) (interface{}, error) {
 	var res interface{}
 	path := client.namespaced(urlContractInterface)
diff --git a/test/e2e/multiparty/contract_migration.go b/test/e2e/multiparty/contract_migration.go
index f3db4c8c4..63e8cc16c 100644
--- a/test/e2e/multiparty/contract_migration.go
+++ b/test/e2e/multiparty/contract_migration.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -34,13 +34,16 @@ type ContractMigrationTestSuite struct {
 	testState *testState
 }
 
+func (suite *ContractMigrationTestSuite) SetupSuite() {
+	suite.testState = beforeE2ETest(suite.T())
+}
+
 func (suite *ContractMigrationTestSuite) BeforeTest(suiteName, testName string) {
 	suite.testState = beforeE2ETest(suite.T())
 }
 
 func (suite *ContractMigrationTestSuite) AfterTest(suiteName, testName string) {
 	e2e.VerifyAllOperationsSucceeded(suite.T(), []*client.FireFlyClient{suite.testState.client1, suite.testState.client2}, suite.testState.startTime)
-	suite.testState.done()
 }
 
 func (suite *ContractMigrationTestSuite) TestContractMigration() {
diff --git a/test/e2e/multiparty/contract_migration_v1.go b/test/e2e/multiparty/contract_migration_v1.go
index 007f6f202..d93c308ae 100644
--- a/test/e2e/multiparty/contract_migration_v1.go
+++ b/test/e2e/multiparty/contract_migration_v1.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -25,13 +25,16 @@ type ContractMigrationV1TestSuite struct {
 	ContractMigrationTestSuite
 }
 
+func (suite *ContractMigrationV1TestSuite) SetupSuite() {
+	suite.testState = beforeE2ETest(suite.T())
+}
+
 func (suite *ContractMigrationV1TestSuite) BeforeTest(suiteName, testName string) {
 	suite.testState = beforeE2ETest(suite.T())
 }
 
 func (suite *ContractMigrationV1TestSuite) AfterTest(suiteName, testName string) {
 	e2e.VerifyAllOperationsSucceeded(suite.T(), []*client.FireFlyClient{suite.testState.client1, suite.testState.client2}, suite.testState.startTime)
-	suite.testState.done()
 }
 
 func (suite *ContractMigrationV1TestSuite) TestContractMigration() {
diff --git a/test/e2e/multiparty/ethereum_contracts.go b/test/e2e/multiparty/ethereum_contracts.go
index 967d65918..329b125c5 100644
--- a/test/e2e/multiparty/ethereum_contracts.go
+++ b/test/e2e/multiparty/ethereum_contracts.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -19,8 +19,6 @@ package multiparty
 import (
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
-	"os"
 	"os/exec"
 	"testing"
 
@@ -136,7 +134,6 @@ func (suite *EthereumContractTestSuite) BeforeTest(suiteName, testName string) {
 
 func (suite *EthereumContractTestSuite) AfterTest(suiteName, testName string) {
 	e2e.VerifyAllOperationsSucceeded(suite.T(), []*client.FireFlyClient{suite.testState.client1, suite.testState.client2}, suite.testState.startTime)
-	suite.testState.done()
 }
 
 func (suite *EthereumContractTestSuite) TestDirectInvokeMethod() {
@@ -310,16 +307,3 @@ func (suite *EthereumContractTestSuite) TestContractAPIMethod() {
 
 	suite.testState.client1.DeleteContractListener(suite.T(), listener.ID)
 }
-
-func readContractJSON(t *testing.T, contract string) fftypes.JSONObject {
-	path := "../../data/contracts/" + contract
-	jsonFile, err := os.Open(path)
-	assert.NoError(t, err)
-	defer jsonFile.Close()
-	byteValue, err := ioutil.ReadAll(jsonFile)
-	assert.NoError(t, err)
-	var jsonValue fftypes.JSONObject
-	err = json.Unmarshal(byteValue, &jsonValue)
-	assert.NoError(t, err)
-	return jsonValue
-}
diff --git a/test/e2e/multiparty/ethereum_token_contract.go b/test/e2e/multiparty/ethereum_token_contract.go
deleted file mode 100644
index 14eaa525e..000000000
--- a/test/e2e/multiparty/ethereum_token_contract.go
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright © 2023 Kaleido, Inc.
-//
-// SPDX-License-Identifier: Apache-2.0
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package multiparty
-
-import (
-	"fmt"
-	"strings"
-
-	"github.com/hyperledger/firefly-common/pkg/fftypes"
-	"github.com/hyperledger/firefly/pkg/core"
-	"github.com/hyperledger/firefly/test/e2e"
-	"github.com/hyperledger/firefly/test/e2e/client"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/suite"
-)
-
-var expectedERC20Methods = fftypes.JSONAnyPtr(`{
-	"approval": {
-		"format": "abi",
-		"methods": [
-		{
-			"type": "function",
-			"name": "approve",
-			"stateMutability": "nonpayable",
-			"inputs": [
-			{
-				"name": "spender",
-				"type": "address",
-				"internalType": "address"
-			},
-			{
-				"name": "amount",
-				"type": "uint256",
-				"internalType": "uint256"
-			}
-			],
-			"outputs": [
-			{
-				"name": "",
-				"type": "bool",
-				"internalType": "bool"
-			}
-			]
-		}
-		]
-	},
-	"burn": {
-		"format": "abi",
-		"methods": [
-		{
-			"type": "function",
-			"name": "burn",
-			"stateMutability": "nonpayable",
-			"inputs": [
-			{
-				"name": "amount",
-				"type": "uint256",
-				"internalType": "uint256"
-			}
-			],
-			"outputs": []
-		},
-		{
-			"type": "function",
-			"name": "burnFrom",
-			"stateMutability": "nonpayable",
-			"inputs": [
-			{
-				"name": "account",
-				"type": "address",
-				"internalType": "address"
-			},
-			{
-				"name": "amount",
-				"type": "uint256",
-				"internalType": "uint256"
-			}
-			],
-			"outputs": []
-		}
-		]
-	},
-	"mint": {
-		"format": "abi",
-		"methods": [
-		{
-			"type": "function",
-			"name": "mint",
-			"stateMutability": "nonpayable",
-			"inputs": [
-			{
-				"name": "to",
-				"type": "address",
-				"internalType": "address"
-			},
-			{
-				"name": "amount",
-				"type": "uint256",
-				"internalType": "uint256"
-			}
-			],
-			"outputs": []
-		}
-		]
-	},
-	"transfer": {
-		"format": "abi",
-		"methods": [
-		{
-			"type": "function",
-			"name": "transfer",
-			"stateMutability": "nonpayable",
-			"inputs": [
-			{
-				"name": "to",
-				"type": "address",
-				"internalType": "address"
-			},
-			{
-				"name": "amount",
-				"type": "uint256",
-				"internalType": "uint256"
-			}
-			],
-			"outputs": [
-			{
-				"name": "",
-				"type": "bool",
-				"internalType": "bool"
-			}
-			]
-		},
-		{
-			"type": "function",
-			"name": "transferFrom",
-			"stateMutability": "nonpayable",
-			"inputs": [
-			{
-				"name": "from",
-				"type": "address",
-				"internalType": "address"
-			},
-			{
-				"name": "to",
-				"type": "address",
-				"internalType": "address"
-			},
-			{
-				"name": "amount",
-				"type": "uint256",
-				"internalType": "uint256"
-			}
-			],
-			"outputs": [
-			{
-				"name": "",
-				"type": "bool",
-				"internalType": "bool"
-			}
-			]
-		}
-		]
-	}
-}`)
-
-var expectedERC1155Methods = fftypes.JSONAnyPtr(`{
-	"approval": {
-	  "format": "abi",
-	  "methods": [
-		{
-		  "type": "function",
-		  "name": "setApprovalForAllWithData",
-		  "stateMutability": "nonpayable",
-		  "inputs": [
-			{
-			  "name": "operator",
-			  "type": "address",
-			  "internalType": "address"
-			},
-			{
-			  "name": "approved",
-			  "type": "bool",
-			  "internalType": "bool"
-			},
-			{
-			  "name": "data",
-			  "type": "bytes",
-			  "internalType": "bytes"
-			}
-		  ],
-		  "outputs": []
-		},
-		{
-		  "type": "function",
-		  "name": "setApprovalForAll",
-		  "stateMutability": "nonpayable",
-		  "inputs": [
-			{
-			  "name": "operator",
-			  "type": "address",
-			  "internalType": "address"
-			},
-			{
-			  "name": "approved",
-			  "type": "bool",
-			  "internalType": "bool"
-			}
-		  ],
-		  "outputs": []
-		}
-	  ]
-	},
-	"burn": {
-	  "format": "abi",
-	  "methods": [
-		{
-		  "type": "function",
-		  "name": "burn",
-		  "stateMutability": "nonpayable",
-		  "inputs": [
-			{
-			  "name": "account",
-			  "type": "address",
-			  "internalType": "address"
-			},
-			{
-			  "name": "id",
-			  "type": "uint256",
-			  "internalType": "uint256"
-			},
-			{
-			  "name": "value",
-			  "type": "uint256",
-			  "internalType": "uint256"
-			}
-		  ],
-		  "outputs": []
-		}
-	  ]
-	},
-	"mint": {
-	  "format": "abi",
-	  "methods": [
-		{
-		  "type": "function",
-		  "name": "mintFungible",
-		  "stateMutability": "nonpayable",
-		  "inputs": [
-			{
-			  "name": "type_id",
-			  "type": "uint256",
-			  "internalType": "uint256"
-			},
-			{
-			  "name": "to",
-			  "type": "address[]",
-			  "internalType": "address[]"
-			},
-			{
-			  "name": "amounts",
-			  "type": "uint256[]",
-			  "internalType": "uint256[]"
-			},
-			{
-			  "name": "data",
-			  "type": "bytes",
-			  "internalType": "bytes"
-			}
-		  ],
-		  "outputs": []
-		},
-		{
-		  "type": "function",
-		  "name": "mintNonFungibleWithURI",
-		  "stateMutability": "nonpayable",
-		  "inputs": [
-			{
-			  "name": "type_id",
-			  "type": "uint256",
-			  "internalType": "uint256"
-			},
-			{
-			  "name": "to",
-			  "type": "address[]",
-			  "internalType": "address[]"
-			},
-			{
-			  "name": "data",
-			  "type": "bytes",
-			  "internalType": "bytes"
-			},
-			{
-			  "name": "_uri",
-			  "type": "string",
-			  "internalType": "string"
-			}
-		  ],
-		  "outputs": []
-		},
-		{
-		  "type": "function",
-		  "name": "mintNonFungible",
-		  "stateMutability": "nonpayable",
-		  "inputs": [
-			{
-			  "name": "type_id",
-			  "type": "uint256",
-			  "internalType": "uint256"
-			},
-			{
-			  "name": "to",
-			  "type": "address[]",
-			  "internalType": "address[]"
-			},
-			{
-			  "name": "data",
-			  "type": "bytes",
-			  "internalType": "bytes"
-			}
-		  ],
-		  "outputs": []
-		}
-	  ]
-	},
-	"transfer": {
-	  "format": "abi",
-	  "methods": [
-		{
-		  "type": "function",
-		  "name": "safeTransferFrom",
-		  "stateMutability": "nonpayable",
-		  "inputs": [
-			{
-			  "name": "from",
-			  "type": "address",
-			  "internalType": "address"
-			},
-			{
-			  "name": "to",
-			  "type": "address",
-			  "internalType": "address"
-			},
-			{
-			  "name": "id",
-			  "type": "uint256",
-			  "internalType": "uint256"
-			},
-			{
-			  "name": "amount",
-			  "type": "uint256",
-			  "internalType": "uint256"
-			},
-			{
-			  "name": "data",
-			  "type": "bytes",
-			  "internalType": "bytes"
-			}
-		  ],
-		  "outputs": []
-		}
-	  ]
-	}
-  }`)
-
-type EthereumTokenContractTestSuite struct {
-	suite.Suite
-	testState       *testState
-	contract        string
-	expectedMethods *fftypes.JSONAny
-}
-
-func (suite *EthereumTokenContractTestSuite) SetupSuite() {
-	stack := e2e.ReadStack(suite.T())
-	suite.contract = "erc20/ERC20OpenZeppelin.json"
-	suite.expectedMethods = expectedERC20Methods
-	if stack.TokenProviders[0] == "erc1155" {
-		suite.contract = "erc1155/ERC1155Sample.json"
-		suite.expectedMethods = expectedERC1155Methods
-	}
-}
-
-func (suite *EthereumTokenContractTestSuite) BeforeTest(suiteName, testName string) {
-	suite.testState = beforeE2ETest(suite.T())
-}
-
-func (suite *EthereumTokenContractTestSuite) AfterTest(suiteName, testName string) {
-	e2e.VerifyAllOperationsSucceeded(suite.T(), []*client.FireFlyClient{suite.testState.client1, suite.testState.client2}, suite.testState.startTime)
-	suite.testState.done()
-}
-
-func (suite *EthereumTokenContractTestSuite) TestTokensWithInterface() {
-	defer suite.testState.Done()
-
-	received1 := e2e.WsReader(suite.testState.ws1)
-
-	suite.T().Logf("contract: %s", suite.contract)
-	contractAddress := deployContract(suite.T(), suite.testState.stackName, suite.contract)
-	contractJSON := readContractJSON(suite.T(), suite.contract)
-
-	ffi := suite.testState.client1.GenerateFFIFromABI(suite.T(), &fftypes.FFIGenerationRequest{
-		Name:    "ERC20",
-		Version: contractVersion,
-		Input:   fftypes.JSONAnyPtr(`{"abi":` + contractJSON.GetObjectArray("abi").String() + `}`),
-	})
-	_, err := suite.testState.client1.CreateFFI(suite.T(), ffi)
-	assert.NoError(suite.T(), err)
-
-	poolName := fmt.Sprintf("pool_%s", e2e.RandomName(suite.T()))
-	pool := &core.TokenPool{
-		Name: poolName,
-		Type: core.TokenTypeFungible,
-		Config: fftypes.JSONObject{
-			"address": contractAddress,
-		},
-		Interface: &fftypes.FFIReference{
-			Name:    "ERC20",
-			Version: contractVersion,
-		},
-	}
-	poolResp := suite.testState.client1.CreateTokenPool(suite.T(), pool, false)
-	e2e.WaitForEvent(suite.T(), received1, core.EventTypePoolConfirmed, poolResp.ID)
-
-	poolResp = suite.testState.client1.GetTokenPool(suite.T(), poolResp.ID)
-	assert.Equal(suite.T(), core.TokenInterfaceFormatABI, poolResp.InterfaceFormat)
-	assert.Equal(suite.T(), suite.expectedMethods.JSONObject(), poolResp.Methods.JSONObject())
-
-	transfer := &core.TokenTransferInput{
-		TokenTransfer: core.TokenTransfer{Amount: *fftypes.NewFFBigInt(1)},
-		Pool:          poolName,
-	}
-	suite.testState.client1.MintTokens(suite.T(), transfer, false)
-	e2e.WaitForEvent(suite.T(), received1, core.EventTypeTransferConfirmed, nil)
-
-	transfers := suite.testState.client1.GetTokenTransfers(suite.T(), poolResp.ID)
-	assert.Len(suite.T(), transfers, 1)
-	blockchainEvent := suite.testState.client1.GetBlockchainEvent(suite.T(), transfers[0].BlockchainEvent.String())
-	assert.Equal(suite.T(), strings.ToLower(contractAddress), strings.ToLower(blockchainEvent.Info["address"].(string)))
-
-	e2e.ValidateAccountBalances(suite.T(), suite.testState.client1, poolResp.ID, "", map[string]int64{
-		suite.testState.org1key.Value: 1,
-	})
-
-	transfer = &core.TokenTransferInput{
-		TokenTransfer: core.TokenTransfer{Amount: *fftypes.NewFFBigInt(1)},
-		Pool:          poolName,
-	}
-	suite.testState.client1.BurnTokens(suite.T(), transfer, false)
-	e2e.WaitForEvent(suite.T(), received1, core.EventTypeTransferConfirmed, nil)
-
-	transfers = suite.testState.client1.GetTokenTransfers(suite.T(), poolResp.ID)
-	assert.Len(suite.T(), transfers, 2)
-
-	e2e.ValidateAccountBalances(suite.T(), suite.testState.client1, poolResp.ID, "", map[string]int64{
-		suite.testState.org1key.Value: 0,
-	})
-}
diff --git a/test/e2e/multiparty/ethereum_v1_migration.go b/test/e2e/multiparty/ethereum_v1_migration.go
new file mode 100644
index 000000000..2e628e763
--- /dev/null
+++ b/test/e2e/multiparty/ethereum_v1_migration.go
@@ -0,0 +1,27 @@
+// Copyright © 2022 Kaleido, Inc.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package multiparty
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/suite"
+)
+
+func TestEthereumMultipartyV1MigrationE2ESuite(t *testing.T) {
+	suite.Run(t, new(ContractMigrationV1TestSuite))
+}
diff --git a/test/e2e/multiparty/fabric_contracts.go b/test/e2e/multiparty/fabric_contracts.go
index 451d3714d..5677877c3 100644
--- a/test/e2e/multiparty/fabric_contracts.go
+++ b/test/e2e/multiparty/fabric_contracts.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -109,10 +109,11 @@ func (suite *FabricContractTestSuite) BeforeTest(suiteName, testName string) {
 
 func (suite *FabricContractTestSuite) AfterTest(suiteName, testName string) {
 	e2e.VerifyAllOperationsSucceeded(suite.T(), []*client.FireFlyClient{suite.testState.client1, suite.testState.client2}, suite.testState.startTime)
-	suite.testState.done()
 }
 
 func (suite *FabricContractTestSuite) TestE2EContractEvents() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 
 	sub := suite.testState.client1.CreateContractListener(suite.T(), assetCreatedEvent, &fftypes.JSONObject{
diff --git a/test/e2e/multiparty/identity.go b/test/e2e/multiparty/identity.go
index 89c804bc7..9fa573e81 100644
--- a/test/e2e/multiparty/identity.go
+++ b/test/e2e/multiparty/identity.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -42,10 +42,11 @@ func (suite *IdentityTestSuite) BeforeTest(suiteName, testName string) {
 
 func (suite *IdentityTestSuite) AfterTest(suiteName, testName string) {
 	e2e.VerifyAllOperationsSucceeded(suite.T(), []*client.FireFlyClient{suite.testState.client1, suite.testState.client2}, suite.testState.startTime)
-	suite.testState.done()
 }
 
 func (suite *IdentityTestSuite) TestCustomChildIdentityBroadcasts() {
+	defer suite.testState.done()
+
 	ctx := context.Background()
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
@@ -98,6 +99,8 @@ func (suite *IdentityTestSuite) TestCustomChildIdentityBroadcasts() {
 }
 
 func (suite *IdentityTestSuite) TestCustomChildIdentityPrivate() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
 
@@ -140,6 +143,8 @@ func (suite *IdentityTestSuite) TestCustomChildIdentityPrivate() {
 }
 
 func (suite *IdentityTestSuite) TestInvalidIdentityAlreadyRegistered() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 
 	key := getUnregisteredAccount(suite, suite.testState.org1.Name)
diff --git a/test/e2e/multiparty/multi_tenancy.go b/test/e2e/multiparty/multi_tenancy.go
index 36317e7a3..86722699c 100644
--- a/test/e2e/multiparty/multi_tenancy.go
+++ b/test/e2e/multiparty/multi_tenancy.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -33,13 +33,16 @@ type NamespaceAliasSuite struct {
 	testState *testState
 }
 
+func (suite *NamespaceAliasSuite) SetupSuite() {
+	suite.testState = beforeE2ETest(suite.T())
+}
+
 func (suite *NamespaceAliasSuite) BeforeTest(suiteName, testName string) {
 	suite.testState = beforeE2ETest(suite.T())
 }
 
 func (suite *NamespaceAliasSuite) AfterTest(suiteName, testName string) {
 	e2e.VerifyAllOperationsSucceeded(suite.T(), []*client.FireFlyClient{suite.testState.client1, suite.testState.client2}, suite.testState.startTime)
-	suite.testState.done()
 }
 
 func newNamespace(networkNamespace, contractAddress string) (ns, org, node map[string]interface{}) {
diff --git a/test/e2e/multiparty/onchain_offchain.go b/test/e2e/multiparty/onchain_offchain.go
index afc9f6a57..165f7efb1 100644
--- a/test/e2e/multiparty/onchain_offchain.go
+++ b/test/e2e/multiparty/onchain_offchain.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -48,10 +48,11 @@ func (suite *OnChainOffChainTestSuite) BeforeTest(suiteName, testName string) {
 
 func (suite *OnChainOffChainTestSuite) AfterTest(suiteName, testName string) {
 	e2e.VerifyAllOperationsSucceeded(suite.T(), []*client.FireFlyClient{suite.testState.client1, suite.testState.client2}, suite.testState.startTime)
-	suite.testState.done()
 }
 
 func (suite *OnChainOffChainTestSuite) TestE2EBroadcast() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
 
@@ -99,6 +100,8 @@ func (suite *OnChainOffChainTestSuite) TestE2EBroadcast() {
 }
 
 func (suite *OnChainOffChainTestSuite) TestStrongDatatypesBroadcast() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
 
@@ -146,6 +149,8 @@ func (suite *OnChainOffChainTestSuite) TestStrongDatatypesBroadcast() {
 }
 
 func (suite *OnChainOffChainTestSuite) TestStrongDatatypesPrivate() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
 
@@ -198,6 +203,9 @@ func (suite *OnChainOffChainTestSuite) TestStrongDatatypesPrivate() {
 }
 
 func (suite *OnChainOffChainTestSuite) TestE2EPrivate() {
+
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
 
@@ -251,6 +259,8 @@ func (suite *OnChainOffChainTestSuite) TestE2EPrivate() {
 }
 
 func (suite *OnChainOffChainTestSuite) TestE2EBroadcastBlob() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
 
@@ -275,6 +285,8 @@ func (suite *OnChainOffChainTestSuite) TestE2EBroadcastBlob() {
 }
 
 func (suite *OnChainOffChainTestSuite) TestE2EPrivateBlobDatatypeTagged() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
 
@@ -305,6 +317,8 @@ func (suite *OnChainOffChainTestSuite) TestE2EPrivateBlobDatatypeTagged() {
 }
 
 func (suite *OnChainOffChainTestSuite) TestE2EWebhookExchange() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
 
@@ -363,6 +377,8 @@ func (suite *OnChainOffChainTestSuite) TestE2EWebhookExchange() {
 }
 
 func (suite *OnChainOffChainTestSuite) TestE2EWebhookRequestReplyNoTx() {
+	defer suite.testState.done()
+
 	subJSON := fmt.Sprintf(`{
 		"transport": "webhooks",
 		"namespace": "%s",
diff --git a/test/e2e/multiparty/tokens.go b/test/e2e/multiparty/tokens.go
index e16d330a8..1ba4dcc86 100644
--- a/test/e2e/multiparty/tokens.go
+++ b/test/e2e/multiparty/tokens.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -45,10 +45,11 @@ func (suite *TokensTestSuite) BeforeTest(suiteName, testName string) {
 
 func (suite *TokensTestSuite) AfterTest(suiteName, testName string) {
 	e2e.VerifyAllOperationsSucceeded(suite.T(), []*client.FireFlyClient{suite.testState.client1, suite.testState.client2}, suite.testState.startTime)
-	suite.testState.done()
 }
 
 func (suite *TokensTestSuite) TestE2EFungibleTokensAsync() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
 
@@ -219,6 +220,8 @@ func (suite *TokensTestSuite) TestE2EFungibleTokensAsync() {
 }
 
 func (suite *TokensTestSuite) TestE2ENonFungibleTokensSync() {
+	defer suite.testState.done()
+
 	received1 := e2e.WsReader(suite.testState.ws1)
 	received2 := e2e.WsReader(suite.testState.ws2)
 
diff --git a/test/e2e/multiparty/tokens_remote_name.go b/test/e2e/multiparty/tokens_remote_name.go
index c6ece024e..d1a735c99 100644
--- a/test/e2e/multiparty/tokens_remote_name.go
+++ b/test/e2e/multiparty/tokens_remote_name.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -45,10 +45,11 @@ func (suite *TokensRemoteNameTestSuite) BeforeTest(suiteName, testName string) {
 
 func (suite *TokensRemoteNameTestSuite) AfterTest(suiteName, testName string) {
 	e2e.VerifyAllOperationsSucceeded(suite.T(), []*client.FireFlyClient{suite.testState.client1, suite.testState.client2}, suite.testState.startTime)
-	suite.testState.done()
 }
 
 func (suite *TokensRemoteNameTestSuite) TestE2EFungibleTokensWithRemoteNameAsync() {
+	defer suite.testState.done()
+
 	newLocalName := "tokens1"
 
 	config1 := e2e.ReadConfig(suite.T(), suite.testState.configFile1)
diff --git a/test/e2e/runners/ethereum_multiparty_test.go b/test/e2e/runners/ethereum_multiparty_test.go
index 4f8ef2809..25b297cfa 100644
--- a/test/e2e/runners/ethereum_multiparty_test.go
+++ b/test/e2e/runners/ethereum_multiparty_test.go
@@ -28,7 +28,6 @@ func TestEthereumMultipartyE2ESuite(t *testing.T) {
 	suite.Run(t, new(multiparty.IdentityTestSuite))
 	suite.Run(t, new(multiparty.TokensTestSuite))
 	suite.Run(t, new(multiparty.EthereumContractTestSuite))
-	suite.Run(t, new(multiparty.EthereumTokenContractTestSuite))
 	suite.Run(t, new(multiparty.ContractMigrationTestSuite))
 	suite.Run(t, new(multiparty.NamespaceAliasSuite))
 }
diff --git a/test/e2e/runners/ethereum_namespace.go b/test/e2e/runners/ethereum_namespace.go
index 2476ad9ba..0faa2d7b5 100644
--- a/test/e2e/runners/ethereum_namespace.go
+++ b/test/e2e/runners/ethereum_namespace.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -27,5 +27,4 @@ func TestEthereumNamespaceE2ESuite(t *testing.T) {
 	suite.Run(t, new(multiparty.OnChainOffChainTestSuite))
 	suite.Run(t, new(multiparty.TokensTestSuite))
 	suite.Run(t, new(multiparty.EthereumContractTestSuite))
-	suite.Run(t, new(multiparty.EthereumTokenContractTestSuite))
 }