Repository: hyperledger/firefly
Pull request #1129 (2023-01-05 21:36:40)

Add docs on fftokens
<img width="1234" alt="fftokens_-_Hyperledger_FireFly_Docs" src="https://user-images.githubusercontent.com/1993829/210884637-4b4a3027-4e8c-4e6c-a5b4-ecc2e5d4f288.png">


codecov-commenter: # [Codecov](https://codecov.io/gh/hyperledger/firefly/pull/1129?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=hyperledger) Report
> Merging [#1129](https://codecov.io/gh/hyperledger/firefly/pull/1129?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=hyperledger) (3404dab) into [main](https://codecov.io/gh/hyperledger/firefly/commit/f1b10e9c5cab7abe59a7e5db13e7344e650707f9?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=hyperledger) (f1b10e9) will **decrease** coverage by `0.03%`.
> The diff coverage is `n/a`.

```diff
@@            Coverage Diff             @@
##             main    #1129      +/-   ##
==========================================
- Coverage   99.34%   99.31%   -0.04%     
==========================================
  Files         303      303              
  Lines       19695    19695              
==========================================
- Hits        19566    19560       -6     
- Misses        120      124       +4     
- Partials        9       11       +2     
```


| [Impacted Files](https://codecov.io/gh/hyperledger/firefly/pull/1129?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=hyperledger) | Coverage Δ | |
|---|---|---|
| [internal/events/webhooks/webhooks.go](https://codecov.io/gh/hyperledger/firefly/pull/1129?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=hyperledger#diff-aW50ZXJuYWwvZXZlbnRzL3dlYmhvb2tzL3dlYmhvb2tzLmdv) | `97.23% <0.00%> (-2.77%)` | :arrow_down: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=hyperledger). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=hyperledger)


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/microservices/fftokens.md b/docs/reference/microservices/fftokens.md
new file mode 100644
index 000000000..8191ee83a
--- /dev/null
+++ b/docs/reference/microservices/fftokens.md
@@ -0,0 +1,456 @@
+---
+layout: default
+title: fftokens
+parent: Microservices
+grand_parent: pages.reference
+nav_order: 1
+---
+
+# fftokens
+{: .no_toc }
+
+## Table of contents
+{: .no_toc .text-delta }
+
+1. TOC
+{:toc}
+
+---
+
+## Overview
+
+fftokens is a protocol that can be implemented by token connector runtimes in order to be usable by the [fftokens](https://github.com/hyperledger/firefly/blob/main/internal/tokens/fftokens/fftokens.go) plugin in FireFly.
+
+The connector runtime must expose an **HTTP and websocket server**, along with a minimum set of HTTP APIs and websocket events. Each connector will be strongly coupled to a specific ledger technology and token standard(s), but **no assumptions are made** in the fftokens spec about what these technologies must be, as long as they can satisfy the basic requirements laid out here.
+
+Note that this is an _internal_ protocol in the FireFly ecosystem - application developers working against FireFly should never need to care about or directly
+interact with a token connector runtime. The audience for this document is only developers interested in creating new token connectors (or editing/forking
+existing ones).
+
+Two implementations of this specification have been created to date (both based on common Ethereum token standards) - [firefly-tokens-erc1155](https://github.com/hyperledger/firefly-tokens-erc1155) and [firefly-tokens-erc20-erc721](https://github.com/hyperledger/firefly-tokens-erc20-erc721).
+
+## HTTP APIs
+
+This is the minimum set of APIs that must be implemented by a conforming token connector. A connector may choose to expose other APIs for its own purposes. All requests and responses to the APIs below are encoded as JSON. The APIs are currently understood to live under a `/api/v1` prefix.
+
+### `POST /createpool`
+
+Create a new token pool. The exact meaning of this is flexible - it may mean invoking a contract or contract factory to actually define a new set of tokens via a blockchain transaction, or it may mean indexing a set of tokens that already exists (depending on the options a connector accepts in `config`).
+
+In a multiparty network, this operation will only be performed by one of the parties, and FireFly will broadcast the result to the others.
+
+FireFly will store a "pending" token pool after a successful creation, but will replace it with a "confirmed" token pool after a successful activation (see below).
+
+**Request**
+```
+{
+  "type": "fungible",
+  "signer": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "name": "FFCoin",
+  "symbol": "FFC",
+  "data": "pool-metadata",
+  "requestId": "1",
+  "config": {}
+}
+```
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| type | string enum | The type of pool to create. Currently supported types are "fungible" and "nonfungible". It is recommended (but not required) that token connectors support both. Unrecognized/unsupported types should be rejected with HTTP 400. |
+| signer | string | The signing identity to be used for the blockchain transaction, in a format understood by this connector. |
+| name | string | (OPTIONAL) If supported by this token contract, this is a requested name for the token pool. May be ignored at the connector's discretion. |
+| symbol | string | (OPTIONAL) If supported by this token contract, this is a requested symbol for the token pool. May be ignored at the connector's discretion. |
+| requestId | string | (OPTIONAL) A unique identifier for this request. Will be included in the "receipt" websocket event to match receipts to requests. |
+| data | string | (OPTIONAL) A data string that should be returned in the connector's response to this creation request. |
+| config | object | (OPTIONAL) An arbitrary JSON object where the connector may accept additional parameters if desired. Each connector may define its own valid options to influence how the token pool is created. |
+
+**Response**
+
+HTTP 200: pool creation was successful, and the pool details are returned in the response.
+
+_See [Response Types: Token Pool](#token-pool-1)_
+
+HTTP 202: request was accepted, but pool will be created asynchronously, with "receipt" and "token-pool" events sent later on the websocket.
+
+_See [Response Types: Async Request](#async-request)_
+
+### `POST /activatepool`
+
+Activate a token pool to begin receiving events. Generally this means the connector will create blockchain event subscriptions to transfer and approval events related to the set of tokens encompassed by this token pool.
+
+In a multiparty network, this step will be performed by every member after a successful token pool broadcast. It therefore also serves the purpose of validating the broadcast info - if the connector does not find a valid pool given the `poolLocator` and `config` information passed in to this call, the pool should not get confirmed.
+
+**Request**
+```
+{
+  "poolLocator": "id=F1",
+  "poolData": "extra-pool-info",
+  "requestId": "1",
+  "config": {}
+}
+```
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| poolLocator | string | The locator of the pool, as supplied by the output of the pool creation. |
+| poolData | string | (OPTIONAL) A data string that should be permanently attached to this pool and returned in all events. |
+| requestId | string | (OPTIONAL) A unique identifier for this request. Will be included in the "receipt" websocket event to match receipts to requests. |
+| config | object | (OPTIONAL) An arbitrary JSON object where the connector may accept additional parameters if desired. This should be the same `config` object that was passed when the pool was created. |
+
+**Response**
+
+HTTP 200: pool activation was successful, and the pool details are returned in the response.
+
+_See [Response Types: Token Pool](#token-pool-1)_
+
+HTTP 202: request was accepted, but pool will be activated asynchronously, with "receipt" and "token-pool" events sent later on the websocket.
+
+_See [Response Types: Async Request](#async-request)_
+
+HTTP 204: activation was successful - no separate receipt will be delivered, but "token-pool" event will be sent later on the websocket.
+
+_No body_
+
+### `POST /mint`
+
+Mint new tokens.
+
+**Request**
+
+```
+{
+  "poolLocator": "id=F1",
+  "signer": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "to": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "amount": "10",
+  "tokenIndex": "1",
+  "uri": "ipfs://000000",
+  "requestId": "1",
+  "data": "transfer-metadata",
+  "config": {}
+}
+```
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| poolLocator | string | The locator of the pool, as supplied by the output of the pool creation. |
+| signer | string | The signing identity to be used for the blockchain transaction, in a format understood by this connector. |
+| to | string | The identity to receive the minted tokens, in a format understood by this connector. |
+| amount | number string | The amount of tokens to mint. |
+| tokenIndex | string | (OPTIONAL) For non-fungible tokens that require choosing an index at mint time, the index of the specific token to mint. |
+| uri | string | (OPTIONAL) For non-fungible tokens that support choosing a URI at mint time, the URI to be attached to the token. |
+| requestId | string | (OPTIONAL) A unique identifier for this request. Will be included in the "receipt" websocket event to match receipts to requests. |
+| config | object | (OPTIONAL) An arbitrary JSON object where the connector may accept additional parameters if desired. Each connector may define its own valid options to influence how the mint is carried out. |
+
+**Response**
+
+HTTP 202: request was accepted, but mint will occur asynchronously, with "receipt" and "token-mint" events sent later on the websocket.
+
+_See [Response Types: Async Request](#async-request)_
+
+### `POST /burn`
+
+Burn tokens.
+
+**Request**
+
+```
+{
+  "poolLocator": "id=F1",
+  "signer": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "from": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "amount": "10",
+  "tokenIndex": "1",
+  "requestId": "1",
+  "data": "transfer-metadata",
+  "config": {}
+}
+```
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| poolLocator | string | The locator of the pool, as supplied by the output of the pool creation. |
+| signer | string | The signing identity to be used for the blockchain transaction, in a format understood by this connector. |
+| from | string | The identity that currently owns the tokens to be burned, in a format understood by this connector. |
+| amount | number string | The amount of tokens to burn. |
+| tokenIndex | string | (OPTIONAL) For non-fungible tokens, the index of the specific token to burn. |
+| requestId | string | (OPTIONAL) A unique identifier for this request. Will be included in the "receipt" websocket event to match receipts to requests. |
+| config | object | (OPTIONAL) An arbitrary JSON object where the connector may accept additional parameters if desired. Each connector may define its own valid options to influence how the burn is carried out. |
+
+**Response**
+
+HTTP 202: request was accepted, but burn will occur asynchronously, with "receipt" and "token-burn" events sent later on the websocket.
+
+_See [Response Types: Async Request](#async-request)_
+
+### `POST /transfer`
+
+Transfer tokens from one address to another.
+
+**Request**
+
+```
+{
+  "poolLocator": "id=F1",
+  "signer": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "from": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "to": "0xb107ed9caa1323b7bc36e81995a4658ec2251951",
+  "amount": "1",
+  "tokenIndex": "1",
+  "requestId": "1",
+  "data": "transfer-metadata",
+  "config": {}
+}
+```
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| poolLocator | string | The locator of the pool, as supplied by the output of the pool creation. |
+| signer | string | The signing identity to be used for the blockchain transaction, in a format understood by this connector. |
+| from | string | The identity to be used for the source of the transfer, in a format understood by this connector. |
+| to | string | The identity to be used for the destination of the transfer, in a format understood by this connector. |
+| amount | number string | The amount of tokens to transfer. |
+| tokenIndex | string | (OPTIONAL) For non-fungible tokens, the index of the specific token to transfer. |
+| requestId | string | (OPTIONAL) A unique identifier for this request. Will be included in the "receipt" websocket event to match receipts to requests. |
+| config | object | (OPTIONAL) An arbitrary JSON object where the connector may accept additional parameters if desired. Each connector may define its own valid options to influence how the transfer is carried out. |
+
+**Response**
+
+HTTP 202: request was accepted, but transfer will occur asynchronously, with "receipt" and "token-transfer" events sent later on the websocket.
+
+_See [Response Types: Async Request](#async-request)_
+
+### `POST /approval`
+
+Approve another identity to manage tokens.
+
+**Request**
+
+```
+{
+  "poolLocator": "id=F1",
+  "signer": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "operator": "0xb107ed9caa1323b7bc36e81995a4658ec2251951",
+  "approved": true,
+  "requestId": "1",
+  "data": "approval-metadata",
+  "config": {}
+}
+```
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| poolLocator | string | The locator of the pool, as supplied by the output of the pool creation. |
+| signer | string | The signing identity to be used for the blockchain transaction, in a format understood by this connector. |
+| operator | string | The identity to be approved (or unapproved) for managing the signer's tokens. |
+| approved | boolean | Whether to approve (the default) or unapprove. |
+| requestId | string | (OPTIONAL) A unique identifier for this request. Will be included in the "receipt" websocket event to match receipts to requests. |
+| config | object | (OPTIONAL) An arbitrary JSON object where the connector may accept additional parameters if desired. Each connector may define its own valid options to influence how the approval is carried out. |
+
+**Response**
+
+HTTP 202: request was accepted, but approval will occur asynchronously, with "receipt" and "token-approval" events sent later on the websocket.
+
+_See [Response Types: Async Request](#async-request)_
+
+## Websocket Events
+
+A connector should expose a websocket at `/api/ws`. All emitted websocket events are a JSON string of the form:
+```
+{
+  "id": "event-id",
+  "event": "event-name",
+  "data": {}
+}
+```
+
+The `event` name will match one of the names listed below, and the `data` payload will correspond to the linked response object.
+
+All events _except the receipt event_ must be acknowledged by sending an ack of the form:
+```
+{
+  "event": "ack",
+  "data": {
+    "id": "event-id"
+  }
+}
+```
+
+Many messages may also be batched into a single websocket event of the form:
+```
+{
+  "id": "event-id",
+  "event": "batch",
+  "data": {
+    "events": [
+      {
+        "event": "event-name",
+        "data": {}
+      },
+      ...
+    ]
+  }
+}
+```
+
+Batched messages must be acked all at once using the ID of the batch.
+
+### `receipt`
+
+An asynchronous operation has completed.
+
+_See [Response Types: Receipt](#receipt-1)_
+
+### `token-pool`
+
+A new token pool has been created or activated.
+
+_See [Response Types: Token Pool](#token-pool-1)_
+
+### `token-mint`
+
+Tokens have been minted.
+
+_See [Response Types: Token Transfer](#token-transfer-1)_
+
+### `token-burn`
+
+Tokens have been burned.
+
+_See [Response Types: Token Transfer](#token-transfer-1)_
+
+### `token-transfer`
+
+Tokens have been transferred.
+
+_See [Response Types: Token Transfer](#token-transfer-1)_
+
+### `token-approval`
+
+Token approvals have changed.
+
+_See [Response Types: Token Approval](#token-approval-1)_
+
+## Response Types
+
+### Async Request
+
+Many operations may happen asynchronously in the background, and will return only a request ID. This may be a request ID that was passed in, or if none was passed, will be randomly assigned. This ID can be used to correlate with a receipt event later received on the websocket.
+
+```
+{
+  "id": "b84ab27d-0d50-42a6-9c26-2fda5eb901ba"
+}
+```
+
+### Receipt
+
+```
+  "headers": {
+    "type": "",
+    "requestId": ""
+  }
+  "transactionHash": "",
+  "errorMessage": ""
+}
+```
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| headers.type | string enum | The type of this response. Should be "TransactionSuccess", "TransactionUpdate", or "TransactionFailed". |
+| headers.requestId | string | The ID of the request to which this receipt should correlate. |
+| transactionHash | string | The unique identifier for the blockchain transaction which generated this receipt. |
+| errorMessage| string | (OPTIONAL) If this is a failure, contains details on the reason for the failure. |
+
+### Token Pool
+
+```
+{
+  "type": "fungible",
+  "data": "pool-metadata",
+  "poolLocator": "id=F1",
+  "standard": "ERC20",
+  "symbol": "FFC",
+  "decimals": 18,
+  "info": {},
+  "signer": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "blockchain": {}
+}
+```
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| type | string enum | The type of pool that was created. |
+| data | string | A copy of the data that was passed in on the creation request. |
+| poolLocator | string | A string to identify this pool, generated by the connector. Must be unique for each pool created by this connector. Will be passed back on all operations within this pool, and may be packed with relevant data about the pool for later usage (such as the address and type of the pool). |
+| standard | string | (OPTIONAL) The name of a well-defined token standard to which this pool conforms. |
+| symbol | string | (OPTIONAL) The symbol for this token pool, if applicable. |
+| decimals | number | (OPTIONAL) The number of decimals used for balances in this token pool, if applicable. |
+| info | object | (OPTIONAL) Additional information about the pool. Each connector may define the format for this object. |
+| signer | string | (OPTIONAL) If this operation triggered a blockchain transaction, the signing identity used for the transaction. |
+| blockchain | object | (OPTIONAL) If this operation triggered a blockchain transaction, contains details on the blockchain event in FireFly's standard blockchain event format. |
+
+### Token Transfer
+
+Note that mint and burn operations are just specialized versions of transfer. A mint will omit the "from" field,
+while a burn will omit the "to" field.
+
+```
+{
+  "id": "1",
+  "data": "transfer-metadata",
+  "poolLocator": "id=F1",
+  "poolData": "extra-pool-info",
+  "from": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "to": "0xb107ed9caa1323b7bc36e81995a4658ec2251951",
+  "amount": "1",
+  "tokenIndex": "1",
+  "uri": "ipfs://000000",
+  "signer": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "blockchain": {}
+}
+```
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| id | string | An identifier for this transfer. Must be unique for every transfer within this pool. |
+| data | string | A copy of the data that was passed in on the mint/burn/transfer request. May be omitted if the token contract does not support a method of attaching extra data (will result in reduced ability for FireFly to correlate the inputs and outputs of the transaction). |
+| poolLocator | string | The locator of the pool, as supplied by the output of the pool creation. |
+| poolData | string | The extra data associated with the pool at pool activation. |
+| from | string | The identity used for the source of the transfer. |
+| to | string | The identity used for the destination of the transfer. |
+| amount | number string | The amount of tokens transferred. |
+| tokenIndex | string | (OPTIONAL) For non-fungible tokens, the index of the specific token transferred. |
+| uri | string | (OPTIONAL) For non-fungible tokens, the URI attached to the token. |
+| signer | string | (OPTIONAL) If this operation triggered a blockchain transaction, the signing identity used for the transaction. |
+| blockchain | object | (OPTIONAL) If this operation triggered a blockchain transaction, contains details on the blockchain event in FireFly's standard blockchain event format. |
+
+### Token Approval
+
+```
+{
+  "id": "1",
+  "data": "transfer-metadata",
+  "poolLocator": "id=F1",
+  "poolData": "extra-pool-info",
+  "operator": "0xb107ed9caa1323b7bc36e81995a4658ec2251951",
+  "approved": true,
+  "subject": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A:0xb107ed9caa1323b7bc36e81995a4658ec2251951",
+  "info": {},
+  "signer": "0x0Ef1D0Dd56a8FB1226C0EaC374000B81D6c8304A",
+  "blockchain": {}
+}
+```
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| id | string | An identifier for this approval. Must be unique for every approval within this pool. |
+| data | string | A copy of the data that was passed in on the approval request. May be omitted if the token contract does not support a method of attaching extra data (will result in reduced ability for FireFly to correlate the inputs and outputs of the transaction). |
+| poolLocator | string | The locator of the pool, as supplied by the output of the pool creation. |
+| poolData | string | The extra data associated with the pool at pool activation. |
+| operator | string | The identity that was approved (or unapproved) for managing tokens. |
+| approved | boolean | Whether this was an approval or unapproval. |
+| subject | string | A string identifying the scope of the approval, generated by the connector. Approvals with the same subject are understood replace one another, so that a previously-recorded approval becomes inactive. This string may be a combination of the identities involved, the token index, etc. |
+| info | object | (OPTIONAL) Additional information about the approval. Each connector may define the format for this object. |
+| signer | string | (OPTIONAL) If this operation triggered a blockchain transaction, the signing identity used for the transaction. |
+| blockchain | object | (OPTIONAL) If this operation triggered a blockchain transaction, contains details on the blockchain event in FireFly's standard blockchain event format. |
diff --git a/docs/reference/microservices/index.md b/docs/reference/microservices/index.md
new file mode 100644
index 000000000..0ffb7cdbe
--- /dev/null
+++ b/docs/reference/microservices/index.md
@@ -0,0 +1,7 @@
+---
+layout: default
+title: Microservices
+parent: pages.reference
+nav_order: 9
+has_children: true
+---
diff --git a/docs/reference/namespaces.md b/docs/reference/namespaces.md
index 77de67946..c149e2b33 100644
--- a/docs/reference/namespaces.md
+++ b/docs/reference/namespaces.md
@@ -2,7 +2,7 @@
 layout: default
 title: Namespaces
 parent: pages.reference
-nav_order:  7
+nav_order: 8
 ---
 
 # Namespaces
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/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))
 }