Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve docs #9

Merged
merged 3 commits into from
May 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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')