Commit 4454ce4c authored by Eugene Mishura's avatar Eugene Mishura

refined custom policy behavior and extension

parent a14d7019
Pipeline #115688750 passed with stage
in 2 minutes and 35 seconds
......@@ -43,7 +43,7 @@ type view_allowance_param = {
type entry_points =
| Change_allowance of change_allowance_param
| View_allowance of view_allowance_param
| On_transfer_hook of hook_param
| Tokens_transferred_hook of hook_param
| Register_with_fa2 of fa2_entry_points contract
(**
......@@ -114,10 +114,10 @@ let main (param, s : entry_points * allowances) : (operation list) * allowances
let op = Operation.transaction resp 0mutez p.view in
[op], s
| On_transfer_hook p ->
| Tokens_transferred_hook p ->
let new_s = List.fold (track_allowances p.operator) p.batch s in
([] : operation list), new_s
| Register_with_fa2 fa2 ->
let op = create_register_hook_op fa2 (Allowance_config Current.self_address) in
let op = create_register_hook_op fa2 (Some (Allowance_config Current.self_address)) in
[op], s
......@@ -9,12 +9,12 @@ Any address can be a recipient of the token transfer
#include "hook_lib.mligo"
type entry_points =
| On_transfer_hook of hook_param
| Tokens_transferred_hook of hook_param
| Register_with_fa2 of fa2_entry_points contract
let main (param, s : entry_points * unit) : (operation list) * unit =
match param with
| On_transfer_hook p ->
| Tokens_transferred_hook p ->
let u = List.iter ( fun (tx : hook_transfer) ->
match tx.from_ with
| None -> unit
......@@ -26,5 +26,5 @@ type entry_points =
([] : operation list), unit
| Register_with_fa2 fa2 ->
let op = create_register_hook_op fa2 (No_config Current.self_address) in
let op = create_register_hook_op fa2 (None : permission_policy_config option) in
[op], s
\ No newline at end of file
......@@ -15,7 +15,7 @@
type entry_points =
| Add_operator of address
| Remove_operator of address
| On_transfer_hook of hook_param
| Tokens_transferred_hook of hook_param
| Register_with_fa2 of fa2_entry_points contract
......@@ -57,7 +57,7 @@ let main (param, s : entry_points * operators) : (operation list) * operators =
let new_s = Big_map.update owner (Some new_ops) s in
([] : operation list), new_s
| On_transfer_hook p ->
| Tokens_transferred_hook p ->
let u = List.iter (fun (tx : hook_transfer) ->
let allowed = match tx.from_ with
| None -> true
......@@ -70,5 +70,5 @@ let main (param, s : entry_points * operators) : (operation list) * operators =
([] : operation list), s
| Register_with_fa2 fa2 ->
let op = create_register_hook_op fa2 (Operator_config Current.self_address) in
let op = create_register_hook_op fa2 (Some (Operator_config Current.self_address)) in
[op], s
......@@ -14,7 +14,7 @@ MUST fail.
type entry_points =
| Add_receiver of address
| Remove_receiver of address
| On_admin_hook of hook_param
| Tokens_transferred_hook of hook_param
| Register_with_fa2 of fa2_entry_points contract
......@@ -30,7 +30,7 @@ let main (param, s : entry_points * whitelist) : (operation list) * whitelist =
let new_s = Set.remove op s in
([] : operation list), new_s
| On_admin_hook p ->
| Tokens_transferred_hook p ->
let u = List.iter (fun (tx : hook_transfer) ->
let allowed = match tx.to_ with
| None -> true
......@@ -43,5 +43,5 @@ let main (param, s : entry_points * whitelist) : (operation list) * whitelist =
([] : operation list), s
| Register_with_fa2 fa2 ->
let op = create_register_hook_op fa2 (Whitelist_config Current.self_address) in
let op = create_register_hook_op fa2 (Some (Whitelist_config Current.self_address)) in
[op], s
......@@ -2,15 +2,18 @@
let get_hook (hook_contract : address) : address =
let hook_entry : hook_param contract =
Operation.get_entrypoint "%on_transfer_hook" hook_contract in
Operation.get_entrypoint "%tokens_transferred_hook" hook_contract in
Current.address hook_entry
let create_register_hook_op
(fa2 : fa2_entry_points contract) (config : permission_policy_config) : operation =
(fa2 : fa2_entry_points contract) (config : permission_policy_config option) : operation =
let hook : address = get_hook Current.self_address in
let cfg = match config with
| None -> ([] : permission_policy_config list)
| Some c -> [c] in
let pp : set_hook_param = {
hook = hook;
config = [config];
config = cfg;
} in
Operation.transaction (Set_transfer_hook pp) 0mutez fa2
......@@ -11,11 +11,16 @@ type transfer = {
type transfer_param = transfer list
type custom_config_param = {
entrypoint : address;
tag : string;
}
type permission_policy_config =
| No_config of address
| Allowance_config of address
| Operator_config of address
| Whitelist_config of address
| Custom_config of custom_config_param
type balance_request = {
owner : address;
......@@ -82,6 +87,7 @@ type fa2_entry_points =
| Total_supply of total_supply_param
| Token_descriptor of token_descriptor_param
| Get_permissions_policy of permission_policy_config
(* Recommended design pattern. Not part of FA2 standard. *)
| Set_transfer_hook of set_hook_param
......
......@@ -62,11 +62,16 @@ type transfer = {
type transfer_param = transfer list
type custom_config_param = {
entrypoint : address;
tag : string;
}
type permission_policy_config =
| No_config of address
| Allowance_config of address
| Operator_config of address
| Whitelist_config of address
| Custom_config of custom_config_param
type balance_request = {
owner : address;
......@@ -133,7 +138,6 @@ type fa2_entry_points =
| Total_supply of total_supply_param
| Token_descriptor of token_descriptor_param
| Get_permissions_policy of permission_policy_config
| Set_transfer_hook of set_hook_param
```
### FA2 Permission Policies and Configuration
......@@ -158,15 +162,6 @@ implementation of FA2 token contract MAY extend one of the standard configuratio
APIs with additional custom entry points. Definition and interaction with such
custom config entry points is out of scope of this standard.
#### `no_config`
Represent non-configurable FA2 implementation with the following default behavior
which represents minimal permission policy.
1. Only token owner can initiate a transfer of tokens from their accounts
( `from_` MUST be equal to `SENDER`)
2. Any address can be a recipient of the token transfer
#### `allowance_config`
Spender is a Tezos address which initiates token transfer operation.
......@@ -255,6 +250,13 @@ type fa2_whitelist_config_entry_points =
| Remove_from_white_list of address list
```
#### `custom_config`
Custom config API is an extension point to support custom permission policy behavior
and its possible configuration. This standard does not specify exact types for
custom config entry points. FA2 token contract clients which support custom config
entry points must know their types a priori and/or use `tag` hint.
### Entry Point Semantics
#### `transfer`
......@@ -301,10 +303,10 @@ permission configuration contract.
| `permission_policy_config` option | config entry points type |
| :------------------------- | :----------------------- |
| `No_config` | `unit` (there are no config entry points for this option) |
| `Allowance_config` | `fa2_allowance_config_entry_points` |
| `Operator_config` | `fa2_operator_config_entry_points` |
| `Whitelist_config` | `fa2_whitelist_config_entry_points` |
| `Custom_config` | Not specified |
Config entry points may be implemented either by FA2 token contract (then the
returned address will be `SELF`), or by a separate contract (see recommended
......@@ -429,18 +431,18 @@ This behavior specifies of the token owner can transfer its own tokens.
| Possible value | Required config API | Comment |
| --------------- | -------------------- | ------- |
| `Self(true)` | No (`No_config`) | Token owner can transfer own tokens|
| `Self(false)` | No (`No_config`) | Token owner cannot transfer own |
| `Self(true)` | None | Token owner can transfer own tokens|
| `Self(false)` | None | Token owner cannot transfer own |
#### `Operator` Permissioning Behavior
This behavior specifies if a tokens transfer can be initiated by someone other than
token owner (operator).
| Possible value | Required config API | Comment |
| --------------- | -------------------- | ------- |
| Operator(None) | No (`No_config`) | Nobody can transfer on behalf of the token owner |
| Operator(Op) | `Operator_config` | Each token owner has a list of operators who can transfer on behalf of the token owner. Operator can transfer any tokens and any amount on behalf of the owner |
| Possible value | Required config API | Comment |
| --------------- | ---------------------- | ------- |
| Operator(None) | None | Nobody can transfer on behalf of the token owner |
| Operator(Op) | `Operator_config` | Each token owner has a list of operators who can transfer on behalf of the token owner. Operator can transfer any tokens and any amount on behalf of the owner |
| Operator(Allowance) | `Allowance_config` | Each token owner has a list of operators who can transfer on behalf of the token owner. Each operator has allowance for each token type and amount, it can transfer. |
#### `Whitelist` Permissioning Behavior
......@@ -448,10 +450,10 @@ token owner (operator).
This behavior specifies if token transfer should be permitted by whitelisting token
owner addresses.
| Possible value | Required config API | Comment |
| --------------- | -------------------- | ------- |
| `Whitelist(false)` | No (`No_config`) | No whitelisting. Owner's address is not checked against white list |
| `Whilelist(true)` | `Whitelist_config` | If owner's address is not present in the white list, the transfer MUST fail. |
| Possible value | Required config API | Comment |
| --------------- | --------------------- | ------- |
| `Whitelist(false)` | None | No whitelisting. Owner's address is not checked against white list |
| `Whilelist(true)` | `Whitelist_config` | If owner's address is not present in the white list, the transfer MUST fail. |
It is possible to have white lists for both token sender and token receiver addresses.
But for practical reasons this specification limits whitelisting behavior to the
......@@ -465,15 +467,21 @@ failed, the whole transfer operation MUST fail.
| Possible value | Required config API | Comment |
| --------------- | -------------------- | ------- |
| `Owner_hook(None)` | No (`No_config`) | Permission policy does not invoke owner's hooks and does not check if token owner address implements owner hook API |
| `Owner_hook(Optional)` | No (`No_config`) | Owner hook is optional. If owner address implenents owner hook API, owner hook MUST be invoked. If owner hook fails, whole transfer operation MUST fail. If owner address does not implements owner hook API, transfer operation MUST continue. |
| `Owner_hook(Required)` | No (`No_config`) | Owner hook is required. If owner address implenents owner hook API, owner hook MUST be invoked. If owner hook fails, whole transfer operation MUST fail. If owner address does not implements owner hook API, transfer operation MUST fail. |
| `Owner_hook(None)` | None | Permission policy does not invoke owner's hooks and does not check if token owner address implements owner hook API |
| `Owner_hook(Optional)` | None | Owner hook is optional. If owner address implenents owner hook API, owner hook MUST be invoked. If owner hook fails, whole transfer operation MUST fail. If owner address does not implements owner hook API, transfer operation MUST continue. |
| `Owner_hook(Required)` | None | Owner hook is required. If owner address implenents owner hook API, owner hook MUST be invoked. If owner hook fails, whole transfer operation MUST fail. If owner address does not implements owner hook API, transfer operation MUST fail. |
There are two kinds of the owner hook. Sender hook (`Sender_Owner_Hook`) is invoked
when tokens are transferred **from** the owners account. Receiver hook
when tokens are transferred **from** the owners account. Receiver hook
(`Receiver_Owner_Hook`) is invoked when tokens are transferred **to** the owners
account.
### Extending Behavior Patterns
It is possible to extend permission policy with custom behavior patterns. If such
new behavior patters require configuration API, `Custom_config` options of
`permission_policy_config` can be used to expose then to FA2 contract clients.
### Permission Policy Formulae
Each concrete implementation of the permission policy can be described by a formulate
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment