Skip to content

Commit

Permalink
Improve docs (#9)
Browse files Browse the repository at this point in the history
* improve haddock documentation

* add tutorial for specialized forwarder and fix typo

* link to specializd readme
  • Loading branch information
michaeljklein authored May 28, 2020
1 parent d585f94 commit e248f0f
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 2 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# prototype-forwarder-contract

For the specialized forwarder contract, see [here](README_SPECIALIZED.md)

## Building

```bash
Expand Down
238 changes: 238 additions & 0 deletions README_SPECIALIZED.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@

# Building

To build, run:

```bash
stack build
```

# Origination

The CLI tool's `print-specialized-fa12` command can be used to print the contract:

```bash
❯❯❯ stack exec -- prototype-forwarder-contract print-specialized-fa12 --help
Usage: prototype-forwarder-contract print-specialized-fa12 --central-wallet ADDRESS
--fa12-address ADDRESS
[-o|--output FILEPATH]
[--oneline]
Dump FA1.2 Token Forwarder contract, specialized to paricular addresses, in
the form of Michelson code

Available options:
-h,--help Show this help text
--central-wallet ADDRESS Address of central wallet
--fa12-address ADDRESS Address of FA1.2 Token contract
-o,--output FILEPATH Output file
--oneline Force single line output
```


# Usage

## Overview

The forwarder contract's only entrypoint allows any user to trigger a "flush" of
a given `nat`ural number of tokens from the forwarder to a "central wallet":

```
+-------------+
| |
| Any user |
| |
+--+----------+
|
|
| Call with: 42
|
|
+--v----------+ +-------+
| | Transfer 42 tokens | |
| Forwarder +--------------------------->+ FA1.2 |
| | From: Forwarder | |
+-------------+ To: Central Wallet +-------+
```

The central wallet is fixed upon origination.


## Setup

Originate a dummy FA1.2 that has the appropriate `transfer`
entrypoint and fails on all inputs:

```bash
❯❯❯ tezos-client --wait none originate contract DummyManagedLedger \
transferring 0 from $BOB_ADDRESS running \
"$(cat dummy_fa12.tz | tr -d '\n')" \
--burn-cap 0.378

Waiting for the node to be bootstrapped before injection...
Current head: BLYqnrwfpmKF (timestamp: 2020-05-28T18:51:47-00:00, validation: 2020-05-28T18:52:08-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 12214 units (will add 100 for safety)
Estimated storage: 378 bytes added (will add 20 for safety)
Operation successfully injected in the node.
Operation hash is 'ong5uJLknnycztcM2VTZ8faeAGPJEhaAQbNo7fiLQKPGyAJ8qYZ'
NOT waiting for the operation to be included.
Use command
tezos-client wait for ong5uJLknnycztcM2VTZ8faeAGPJEhaAQbNo7fiLQKPGyAJ8qYZ to be included --confirmations 30 --branch BLYqnrwfpmKFscvGCqhC5SkZKbdLvNhpQ9MTVPat5q4UrP6Jp41
and/or an external block explorer to make sure that it has been included.
This sequence of operations was run:
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0.001582
Expected counter: 623977
Gas limit: 12314
Storage limit: 398 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001582
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,216) ... +ꜩ0.001582
Origination:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Credit: ꜩ0
Script:
{ parameter
(or (pair %transfer (address :from) (pair (address :to) (nat :value)))
(pair %approve (address :spender) (nat :value))) ;
storage unit ;
code { FAILWITH } }
Initial storage: Unit
No delegate for this contract
This origination was successfully applied
Originated contracts:
KT1B73ePQbxBHFxKgKjHE46Y6WnabnNu5i7f
Storage size: 121 bytes
Paid storage size diff: 121 bytes
Consumed gas: 12214
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.121
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257

New contract KT1B73ePQbxBHFxKgKjHE46Y6WnabnNu5i7f originated.
Contract memorized as DummyManagedLedger.
```
Originate a copy of the specialized forwarder that points to the dummy FA1.2
and uses Alice's address as the central wallet:
```bash
❯❯❯ tezos-client --wait none originate contract FA12Forwarder \
transferring 0 from $BOB_ADDRESS running \
"$(stack exec -- prototype-forwarder-contract print-specialized-fa12 \
--central-wallet $ALICE_ADDRESS \
--fa12-address KT1B73ePQbxBHFxKgKjHE46Y6WnabnNu5i7f)" \
--burn-cap 0.493
Waiting for the node to be bootstrapped before injection...
Current head: BL8qgEypo1DM (timestamp: 2020-05-28T19:04:27-00:00, validation: 2020-05-28T19:04:29-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 15042 units (will add 100 for safety)
Estimated storage: 493 bytes added (will add 20 for safety)
Operation successfully injected in the node.
Operation hash is 'ooJYSs4R8dQkuf4mXumExcB57r4ZG6g5HWnHaveSqshJischitT'
NOT waiting for the operation to be included.
Use command
tezos-client wait for ooJYSs4R8dQkuf4mXumExcB57r4ZG6g5HWnHaveSqshJischitT to be included --confirmations 30 --branch BL8qgEypo1DMw7ngmXSVhsjkaamb4Yb4oQ34H7EJ5NLpeMqMvDc
and/or an external block explorer to make sure that it has been included.
This sequence of operations was run:
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0.00198
Expected counter: 623978
Gas limit: 15142
Storage limit: 513 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.00198
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,216) ... +ꜩ0.00198
Origination:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Credit: ꜩ0
Script:
{ parameter nat ;
storage unit ;
code { CAR ;
PUSH address "tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr" ;
PAIR ;
SELF ;
ADDRESS ;
PAIR ;
DIP { PUSH address "KT1B73ePQbxBHFxKgKjHE46Y6WnabnNu5i7f" ;
CONTRACT %transfer (pair address (pair address nat)) ;
IF_NONE { PUSH string "Internal: not FA1.2" ; FAILWITH } { PUSH mutez 0 } } ;
TRANSFER_TOKENS ;
DIP { NIL operation } ;
CONS ;
DIP { UNIT } ;
PAIR } }
Initial storage: Unit
No delegate for this contract
This origination was successfully applied
Originated contracts:
KT1FgsP8zrKgG9pNW6vwK98dUB7BvjkQmqeD
Storage size: 236 bytes
Paid storage size diff: 236 bytes
Consumed gas: 15042
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.236
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257
New contract KT1FgsP8zrKgG9pNW6vwK98dUB7BvjkQmqeD originated.
Contract memorized as FA12Forwarder.
```
Call the forwarder with the parameter `42`:
```bash
❯❯❯ tezos-client --wait none transfer 0 from $BOB_ADDRESS to KT1FgsP8zrKgG9pNW6vwK98dUB7BvjkQmqeD --arg 42
Waiting for the node to be bootstrapped before injection...
Current head: BLKvZAnwhm9d (timestamp: 2020-05-28T19:05:27-00:00, validation: 2020-05-28T19:05:54-00:00)
Node is bootstrapped, ready for injecting operations.
This simulation failed:
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0
Expected counter: 623979
Gas limit: 1040000
Storage limit: 60000 bytes
Transaction:
Amount: ꜩ0
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
To: KT1FgsP8zrKgG9pNW6vwK98dUB7BvjkQmqeD
Parameter: 42
This transaction was BACKTRACKED, its expected effects (as follow) were NOT applied.
Updated storage: Unit
Storage size: 236 bytes
Consumed gas: 26359
Internal operations:
Transaction:
Amount: ꜩ0
From: KT1FgsP8zrKgG9pNW6vwK98dUB7BvjkQmqeD
To: KT1B73ePQbxBHFxKgKjHE46Y6WnabnNu5i7f
Entrypoint: transfer
Parameter: (Pair 0x014df03b5b4530dd0ac5ca1b2f4754ba4bd8e97b2100
(Pair 0x00003b5d4596c032347b72fb51f688c45200d0cb50db 42))
This operation FAILED.
Runtime error in contract KT1B73ePQbxBHFxKgKjHE46Y6WnabnNu5i7f:
1: { parameter
2: (or (pair %transfer (address :from) (pair (address :to) (nat :value)))
3: (pair %approve (address :spender) (nat :value))) ;
4: storage unit ;
5: code { FAILWITH } }
At line 5 characters 9 to 17,
script reached FAILWITH instruction
with
(Pair (Left (Pair 0x014df03b5b4530dd0ac5ca1b2f4754ba4bd8e97b2100
(Pair 0x00003b5d4596c032347b72fb51f688c45200d0cb50db 42)))
Unit)
Fatal error:
transfer simulation failed
```
As expected, the dummy FA1.2 fails with a transfer of `42` tokens from the
forwarder contract to `$ALICE_ADDRESS`.
2 changes: 1 addition & 1 deletion app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ argParser = Opt.subparser $ mconcat
parseAddress "tokens-contract" "Address of FA1.2 token contract" <*>
outputOption
)
"Parameter to flush spzialized any-token forwarder"
"Parameter to flush specialized any-token forwarder"

outputOption = Opt.optional $ Opt.strOption $ mconcat
[ Opt.short 'o'
Expand Down
5 changes: 5 additions & 0 deletions src/Lorentz/Contracts/Forwarder/Specialized.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type Parameter = Natural
-- - The central wallet to transfer sub-tokens to
type Storage = ()

-- | Wrap a @to@ `Address` and number of tokens to transfer
-- in `TransferParams`, sending from `self`
toTransferParameter :: forall s. Address & Natural & s :-> TransferParams & s
toTransferParameter = do
pair
Expand All @@ -53,6 +55,8 @@ toTransferParameter = do
pair
forcedCoerce_ @(Address, (Address, Natural)) @TransferParams

-- | Run a transfer to the given central wallet `Address`, given the token
-- contract `Address` and the number of tokens to transfer
runSpecializedTransfer :: Address -> Address -> (Natural & s) :-> (Operation & s)
runSpecializedTransfer centralWalletAddr' contractAddr' = do
push centralWalletAddr'
Expand All @@ -76,6 +80,7 @@ specializedForwarderContract centralWalletAddr' contractAddr' = do
dip unit
pair

-- | `analyzeLorentz` specialized to the `specializedForwarderContract`
analyzeSpecializedForwarder :: Address -> Address -> AnalyzerRes
analyzeSpecializedForwarder centralWalletAddr' contractAddr' =
analyzeLorentz $ specializedForwarderContract centralWalletAddr' contractAddr'
Expand Down
9 changes: 8 additions & 1 deletion src/Lorentz/Contracts/Forwarder/Specialized/FlushAny.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ import Prelude (Show(..), Enum(..), Eq(..), ($), String, show)
import Michelson.Typed.Value.Orphans ()


-- | The number of sub-tokens to forward and which token to forward it on
-- | The number of sub-tokens to forward and the typed contract address of the
-- token to forward it on
data Parameter = Parameter
{ amountToFlush :: !Natural
, tokenContract :: !(ContractRef TransferParams)
Expand All @@ -54,6 +55,7 @@ instance HasTypeAnn Parameter
instance ParameterHasEntryPoints Parameter where
type ParameterEntryPointsDerivation Parameter = EpdNone

-- | Unwrap a `Parameter`
unParameter :: Parameter & s :-> (Natural, ContractRef TransferParams) & s
unParameter = forcedCoerce_

Expand Down Expand Up @@ -92,6 +94,8 @@ mkParameter amountToFlush' tokenContract' =
-- - The central wallet to transfer sub-tokens to
type Storage = ()

-- | Wrap a @to@ `Address` and number of tokens to transfer
-- in `TransferParams`, sending from `self`
toTransferParameter :: forall s. Address & Natural & s :-> TransferParams & s
toTransferParameter = do
pair
Expand All @@ -100,6 +104,8 @@ toTransferParameter = do
pair
forcedCoerce_ @(Address, (Address, Natural)) @TransferParams

-- | Run a transfer to the given central wallet `Address`, given the token
-- contract `Address` and the number of tokens to transfer
runSpecializedAnyTransfer :: Address -> (Natural & ContractRef TransferParams & s) :-> (Operation & s)
runSpecializedAnyTransfer centralWalletAddr' = do
push centralWalletAddr'
Expand All @@ -120,6 +126,7 @@ specializedAnyForwarderContract centralWalletAddr' = do
dip unit
pair

-- | `analyzeLorentz` specialized to the `specializedAnyForwarderContract`
analyzeSpecializedAnyForwarder :: Address -> AnalyzerRes
analyzeSpecializedAnyForwarder centralWalletAddr' =
analyzeLorentz $ specializedAnyForwarderContract centralWalletAddr'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ instance ParameterHasEntryPoints Parameter where
instance (SingI t) => ParameterHasEntryPoints (Value t) where
type ParameterEntryPointsDerivation (Value t) = EpdNone

-- | Run a transfer to the given central wallet `Address`, given `FlushAny.Parameter`.
-- If no `FlushAny.Parameter` is provided, skip forwarding contract tokens.
--
-- Always attempt to forward any Tez in `balance`.
runSpecializedAnyTezTransfer :: Address -> (Maybe FlushAny.Parameter & s) :-> ([Operation] & s)
runSpecializedAnyTezTransfer centralWalletAddr' = do
dip $ push centralWalletAddr'
Expand Down Expand Up @@ -95,6 +99,7 @@ specializedAnyFA12ForwarderContract centralWalletAddr' = do
dip unit
pair

-- | `analyzeLorentz` specialized to the `specializedAnyFA12ForwarderContract`
analyzeSpecializedAnyTezForwarder :: Address -> AnalyzerRes
analyzeSpecializedAnyTezForwarder centralWalletAddr' =
analyzeLorentz $ specializedAnyFA12ForwarderContract centralWalletAddr'
Expand Down Expand Up @@ -123,3 +128,4 @@ verifyForwarderContract centralWalletAddr' (SomeContract (contract' :: ContractC
forceOneline
(specializedAnyFA12ForwarderContract
centralWalletAddr')

6 changes: 6 additions & 0 deletions src/Lorentz/Contracts/Forwarder/Specialized/FlushAny/Tez.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ import Michelson.Typed.Value.Orphans ()
-- - The central wallet to transfer sub-tokens to
type Storage = ()

-- | Run a transfer to the given central wallet `Address`, given the number of
-- tokens to forward and the token contract reference.
--
-- Always attempt to forward any Tez in `balance`.
runSpecializedAnyTezTransfer :: Address -> (Natural & ContractRef TransferParams & s) :-> ([Operation] & s)
runSpecializedAnyTezTransfer centralWalletAddr' = do
push centralWalletAddr'
Expand Down Expand Up @@ -82,6 +86,7 @@ specializedAnyTezForwarderContract centralWalletAddr' = do
dip unit
pair

-- | `analyzeLorentz` specialized to the `specializedAnyTezForwarderContract`
analyzeSpecializedAnyTezForwarder :: Address -> AnalyzerRes
analyzeSpecializedAnyTezForwarder centralWalletAddr' =
analyzeLorentz $ specializedAnyTezForwarderContract centralWalletAddr'
Expand Down Expand Up @@ -110,3 +115,4 @@ verifyForwarderContract centralWalletAddr' (SomeContract (contract' :: ContractC
forceOneline
(specializedAnyTezForwarderContract
centralWalletAddr')

0 comments on commit e248f0f

Please sign in to comment.